728x90

- SPRING 3.9.7 ver 조건의 ajax 처리 예시가 적어서 찾는데 고생을 하였으나 

사용해본 결과 , 대강의 문법은 SPRING 4이상 ver과 비슷하다.

 

하단의 샘플이미지처럼,  비동기 통신이 성공 하였을때 , 크롬 f12 에서  Request Headers , Resonpse headers 로 타입을 확인 할 수

있다.

 

-front part-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function ajaxTest2(){
            var formarian = {
                    name"jamong",
                    age: 100
            }
            $.ajax({
                url: "stringify",
                type: "POST",
                data: JSON.stringify(formarian),
                contentType: "application/json",
                dataType: "json",
                success: function(data){
                    var txt = data.name + data.age;
                    $('#ajaxText').val(txt);
                },
                error: function(){
                    alert("stringify err");
                }
            });
}     
cs

9 :  서버로 data 에 지정된 값을 전달

     +)request 안에 포함된 json 형태의 데이터를 서버가 받았을 때, 이것을 보통 VO(혹은 DTO)에 다시 담아 사용하는데  .ajax는 데이터를 문자열화 해주지 않기 때문에 보낼 데이터를 JSON.stringify()로 감싸주어야 합니다.

참고 : https://thiago6.tistory.com/11

 

10 : contentType: "application/json" 은 , client-> server 로의 데이터 전달을 json으로 지정하는 것이다.

11 : dataType:'json' 은   server->client 로의 데이터 반환 타입을 json으로 지정하는 것이다.

 

-SPRING MVC controller-

1
2
3
4
5
6
@RequestMapping(value = "/stringify"
        produces = { MediaType.APPLICATION_JSON_VALUE} , method=RequestMethod.POST)     
    public @ResponseBody Map<String,Object> getTodayChart(@RequestBody Map<String,Object> map) {         
        System.out.println(map);
        return map;
    }
cs

2:  produces 에서 JSON객체를 반환하겠다고 지정.

 

    @RequestMapping에는 요청과 응답에 관련한 프로퍼티를 설정할 수 있습니다. produces와 consumes 이 있다.

    produces는 어떠한 데이터 형식으로 응답할 것인가를 결정하는 부분입니다.

    consumes는 어떠한 요청에 대해서 처리할 것인가를 결정하는 부분입니다.

produces를 설정하지 않는다면 , HTTP 요청의 Accept 로 HTTP Message Convertor가 자동으로 컨버터 시켜준다.

 

 

3 : @RequestBody를 Map 앞에 추가해 주어야 한다.

그래야 넘어온 json 값들이 map변수에 key, value값들이 잘 매핑이 된다.

 

 

@RequestBody - JSON형태로 받게해주는 Annotation이며 ,  JSON 데이터를 원하는 타입으로 바인딩 처리

 

@ResponseBody - 일반적인 JSP와 같은 뷰로 전달되는 게 아니라 데이터 자체를 전달하기 위한 용도

메소드의 return형 앞에 @ResponseBody를 붙여서 사용하도록 한다.

 

 

-pom.xml-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!--  Jackson librarys -->
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
        
        <!-- Jackson 2.0 -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.12.3</version>
        </dependency>
        
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.3</version>
        </dependency>
        
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.12.3</version>
        </dependency>    
cs

Spring 3.1.1 인 경우 정상적으로 json 을 출력한다. 다만 버전을 3.2.x 로 업데이트한 경우 문제가 발생한다.
Spring 3.2.x 인 경우 Jackson2 가 필수 사항이기 때문이다.
출처: https://syaku.tistory.com/290 

해당 글을 보고 , Spring 3.9.7에서도 비슷한 이슈거리라고 생각하였다. 이에따라 pom.xml의 jackson-mapper-asl 을 제외한 모든 jackson 버전을 2.대로 맞추어 주었다.

 

https://mvnrepository.com/

윗 공식 mvn-repository에서 dependency등록이 가능한 버전들을 검색할 수 있다.

 

 

 

참고 : jackson라이브러리 , @RequestMapping의 produces,consume  참고 https://github.com/kdevkr/spring-demo-ajax

참고 :  $.ajax head 용어참고  https://thiago6.tistory.com/7?category=827229 

 

728x90

자주사용되는 데이터 전달객체들은 하단의 주소에 자세히 설명되어있다.

참고주소: https://codevang.tistory.com/247

 

-StereoType-

https://incheol-jung.gitbook.io/docs/q-and-a/spring/stereo-type 

해당주소에 스테레오타입의 정의에 대해서 자세히 설명되어있다.

 

-어노테이션-

-@Repository ,@Service-

위 두 어노테이션에 대해서는 

https://m.blog.naver.com/PostView.naver?blogId=kbh3983&logNo=220908370180& 

해당 주소에서 자세히 설명해주고 있다.

 

-@Autowired, @Inject-

위 두 어노테이션에 대해서는

https://velog.io/@sungmo738/Resource-Autowired-Inject-%EC%B0%A8%EC%9D%B4 

https://codevang.tistory.com/256

해당 두 주소가 자세히 설명해주고 있다..

 

-@RequestParam-

client -> server 로 단일 데이터를 옮기는데 사용되고, 메소드의 파라미터로 쓰인다.

 

@RequestParam 문법 :

@RequestParam(value="checkbox",required=false,defaultValue="0") 자료형타입 변수명

value(필수) : client에서 전달해준 key값

required(필수x) : true로 지정할시 넘어오는 key값이 없다면 에러발생, false로 지정할시

                      넘어오는 키값이 없더라도 정상작동됨(대신 null이 변수에 들어감)

defaultValue(필수x) : "required=false" 일 경우에, 변수에 설정해준 defaultValue값을 넣어줌.

자료형타입 변수명(필수) : value="checkbox"에 매칭되는 값이 대입된다.

 

본인은 단일 checkbox 체크유무를 위하여 사용하였다.

하단의 샘플은 @RequestParam을 사용한 예시중 어노테이션 부분위주로만 뽑았다.

1
2
3
4
5
6
7
8
9
@RequestMapping(value="/Login",method = RequestMethod.POST)
public String postLogin(@RequestParam(value="checkbox",required=falseString checked,~) {
    ~~
    if(checked!=null
        session.setMaxInactiveInterval(-1); //web.xml
    else 
        session.setMaxInactiveInterval(60*30);
    ~~    
}
cs

 

checkbox에서는 name="checkbox"로 설정되어있으며 , checkbox는 form 태그내부에 존재한다.

2 : checked 에 value="checkbox" 와 매칭되는 값이 들어온다.

defaultValue를 지정해주지 않았으므로 , 들어오는 값이 없다면 기본적으로 null이 checked에 들어간다. 

4~7 : checked가 null인가 아닌가로 구분하여 셋팅해주었다.

참고로, checkbox가 선택됬다면 값은 기본적으로 "on"이 들어오게 될것임.

 

-@RequestMapping-

client->server로 오는 url을 mapping 시켜준다. or redirect,forward로 server->server 오는 url을 매핑시켜준다.

문법:

@RequestMapping(value= {"/","/main"},method = RequestMethod.GET)

value(필수) : 매핑될 url , 다수url 매핑을 원할시 위와 같이 작성해줌.

method(필수x) : method를 작성해주지 않을시 post, get 방식모두 허용해줌

참고로,,, Spring 4.3부턴

HTTP 메소드들로 restful하게

@PostMapping,@GetMapping,@PutMapping,@DeleteMapping,@PatchMapping  

해당 5가지가 더 지원된다고 한다..

 

하단의 샘플은 웹의 루트인 url : / 와 url :/main 을 같이 묶어 주었다. 

1
2
3
4
@RequestMapping(value= {"/","/main"},method = RequestMethod.GET)
    public String main() {
        return "main";
}
cs

 

------------------------------------------------Lombok-------------------------------------------

@Getter, @Setter, @ToString, @EqualsAndHashCode , @RequiredArgsConstructor, @NoArgsConstructor , @AllArgsConstructor , @Data 

 

@Getter : Getter 메소드가 자동으로 생성

 

@Setter : Setter 메소드가 자동으로 생성

 

@ToString : toString 메소드를 자동으로 생성

 

@EqualsAndHashCode : Equals 와 HashCode 메소드를 자동으로 생성

 

@RequiredArgsConstructor : final이나 @NonNull로 지정된 필드 값만 파라미터로 받는 생성자를 만들어줍니다.

 

@NoArgsConstructor : 파라미터가 없는 기본 생성자를 생성해줌

 

@AllArgsConstructor : 모든 필드 값을 파라미터로 받는 생성자를 만들어줌

 

@Data : 클래스레밸에서 해당 Annotation 이용시 , Lombok에서 지원하는 윗 어노테이션기능들을 모두 수행해준다. (@RequiredArgsConstructor 가 선택됨 )

 

-참고주소

https://stackoverflow.com/questions/37359851/how-to-receive-html-check-box-value-in-spring-mvc-controller

https://www.daleseo.com/lombok-popular-annotations/ (Lombok)

728x90

-개발환경-

IDE : Eclipse 2018-12 (4.10.0)
Spring Tool Suite : 3.9.7.RELEASE
WAS : Pivotal tc Server Developer Edition v4.0 (피보탈 톰캣 서버)
DB : Oracle 11g

-설정-

-STS 브라우저 테스트환경 설정해주기-

WINDOW => Web Browser => Chrome 선택해서 테스트 환경을 크롬으로 잡아주기

-한글깨짐방`지 태그 추가해주기-
web.xml 파일에서 아래 태그들 추가.

 

web.xml

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>
        org.springframework.web.filter.CharacterEncodingFilter     
    </filter-class>
    <init-param>
        <param-name>encoding</param-name>   
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>  
        <param-value>true</param-value>
    </init-param>
</filter>    
 
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>                 
</filter-mapping>
cs

 

Mybatis 구성을 위해 pom.xml 에서 다음을 설정해준다.

 

pom.xml

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!-- 오라클 드라이버 외부 저장소 설정 -->
<repositories>
    <repository>
        <id>oracle</id>
        <name>ORACLE JDBC Repository</name>
        <url>http://maven.jahia.org/maven2</url>
    </repository>
</repositories>
 
<!-- oracle -->
<dependency>
    <groupId>com.oracle</groupId>
    <artifactId>ojdbc6</artifactId>
    <version>12.1.0.1</version>
</dependency>
<!-- spring jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.1.4.RELEASE</version>
</dependency>
<!-- mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.2.8</version>
</dependency>
 
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.2.2</version>
</dependency>
cs

 

 

Mybatis 구성을 위해 servlet-context.xml 에서 다음을 설정해준다.

 

servlet-context.xml

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<beans:bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
    <beans:property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
    <beans:property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
    <beans:property name="username" value="Shin"/>
    <beans:property name="password" value="0000"/>
</beans:bean>
    
<beans:bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <beans:property name="dataSource" ref="dataSource"></beans:property>
    <beans:property name="mapperLocations" value="classpath:com/koreait/dao/*.xml"></beans:property>
    <beans:property name="configLocation" value="classpath:mybatis-config.xml"></beans:property>
</beans:bean>
    
<beans:bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
    <beans:constructor-arg index="0" ref="sqlSessionFactory"></beans:constructor-arg>
</beans:bean>
cs

 

1~6 : 데이터 베이스 연결 정보를 설정하는 DriverManagerDataSource 클래스의 bean을 설정한다.

8~12 : db 연결 정보와 실행할 sql 명령이 저장된 xml 파일의 경로를 기억하는 bean을 설정한다.
          mapper 설정 정보를 기억하는 bean.

10 : 실행할 sql 명령이 저장된 xml파일의 경로

11 :  typeAliases 설정 정보가 저장된 xml 파일의 경로를 설정한다. (의무 x ) (요약어설정)

14~16 : 윗 정보들을 종합한 템플릿 bean.

 

 

 

typeAliases(요약어) 설정을 위해서  resources 폴더에 적당한 (mybatis-config.xml)파일을 생성후 다음을 추가한다.

 

mybatis-config.xml 

 

1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <typeAlias alias="vo" type="com.koreait.vo.MvcboardVO"/>
    </typeAliases>
</configuration>
cs

 

mvcboard.xml 

 

1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.koreait.dao.MybatisDAO">
    <insert id="insert" parameterType="vo">
        ~sql 명렁~
    </insert>
</mapper>
cs

 

해당 파일은 , 실행할 sql 명령이 저장된 xml파일이다.

 

3 : namespace에는 반드시 mapper 역할을 하는 인터페이스의 이름을 풀 패키지 이름으로 적어야 한다.

 

mapper 역할을 하는 MybatisDAO.java

 

1
2
3
public interface MybatisDAO {
    void insert(MvcboardVO mvcboardVO);
}
cs

 

mapper로 사용되는 interface의 추상 메소드 형식은 resultType id(parameterType)와 같은 형식으로 만들어 사용한다.

추상 메소드 이름이 XML 파일의 sql명령을 식별하는 id로 사용되고,
추상 메소드의 인수로 지정된 데이터가 xml 파일의 sql 명령으로 전달된다.
xml 파일의 parameterType 속성에는 1개의 자료형만 쓸 수 있는데 ,
여러개의 데이터를 넘겨야 할 경우
인수로 넘어가는 데이터를 모두 멤버 변수로 가지고 있는 클래스를 사용하면된다.  2번째 줄처럼.

 

mvcboard.xml 

 

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.koreait.dao.MybatisDAO">
    <insert id="insert" parameterType="vo">
        insert into mvcboard (idx,name,subject,content,ref,lev,seq) values 
        (mvcboard_idx_seq.nextval,#{name},#{subject},#{content},mvcboard_idx_seq.currval,0,0)
    </insert>
</mapper>
cs

 

4 : mapper역할을 하는 인터페이스에서  추상메소드이름이   이곳 id 속성값이다.

    parameterType 속성값은 mybatis-config.xml 에서 설정한 요약어이다.

 

HomeController.java

 

1
2
3
4
@Controller
public class HomeController {
    @Autowired
    public SqlSession sqlSession;
cs

4 : servlet-context.xml 파일에서 생성한 mybatis bean을 사용하기 위해
    sqlSession 인터페이스 타입의 변수를 선언한다.
    JDBC Template과 다르게 Setter가 필요없다. 자동으로 넣어준다.

 

 

HomeController.java

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RequestMapping("/insertOK")
     public String insertOK(HttpServletRequest request, Model model) {
        MybatisDAO mapper = sqlSession.getMapper(MybatisDAO.class);
        
        AbstractApplicationContext ctx = new GenericXmlApplicationContext("classpath:applicationCTX.xml");
        MvcboardVO mvcboardVO = ctx.getBean("mvcboardVO", MvcboardVO.class);
        
        mvcboardVO.setName(request.getParameter("name"));
        mvcboardVO.setSubject(request.getParameter("subject"));
        mvcboardVO.setContent(request.getParameter("content"));
        
        mapper.insert(mvcboardVO);
        
        return "redirect:list";
    }
cs

 

3 : mapper로 사용할 interface 변수에 mybatis mapper를 얻어온다.

8~10 : MvcboardVO클래스의 bean에 insert.jsp(view) 에서 request 객체로 넘어온 데이터를 저장한다.

12 : sql 명령을 실행하는 메소드를 호출한다.

728x90

-개발환경-

IDE : Eclipse 2018-12 (4.10.0)
Spring Tool Suite : 3.9.7.RELEASE
WAS : Pivotal tc Server Developer Edition v4.0 (피보탈 톰캣 서버)
DB : Oracle 11g

-설정-

-STS 브라우저 테스트환경 설정해주기-

WINDOW => Web Browser => Chrome 선택해서 테스트 환경을 크롬으로 잡아주기

-한글깨짐방지 태그 추가해주기-
web.xml 파일에서 아래 태그들 추가.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>
        org.springframework.web.filter.CharacterEncodingFilter     
    </filter-class>
    <init-param>
        <param-name>encoding</param-name>   
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>  
        <param-value>true</param-value>
    </init-param>
</filter>    
 
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>                 
</filter-mapping>
cs

 

DBCP Template을 위해 pom.xml 에서 다음을 설정해준다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- 오라클 드라이버 외부 저장소 설정 -->
<repositories>
    <repository>
        <id>oracle</id>
        <name>ORACLE JDBC Repository</name>
        <url>http://maven.jahia.org/maven2</url>
    </repository>
</repositories>
<!-- oracle -->
<dependency>
    <groupId>com.oracle</groupId>
    <artifactId>ojdbc6</artifactId>
    <version>12.1.0.1</version>
</dependency>
<!-- spring dbcp -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.1.4.RELEASE</version>
</dependency>
cs

 

DBCP Template을 위해 servlet-context.xml 에서 다음을 설정해준다.

1
2
3
4
5
6
7
8
9
10
11
<!--servlet-context.xml에 dbcp template을 사용하기 위한 bean을 추가한다.-->
<beans:bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <beans:property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
    <beans:property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
    <beans:property name="username" value="koreait"/>
    <beans:property name="password" value="0000"/>
</beans:bean>
    
<beans:bean name="template" class="org.springframework.jdbc.core.JdbcTemplate">
    <beans:property name="dataSource" ref="dataSource"/>
</beans:bean>
cs

 

-HomeController.java-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Controller
public class HomeController {
    
    private JdbcTemplate template;
 
    public JdbcTemplate getTemplate() {
        return template;
    }
    @Autowired
    public void setTemplate(JdbcTemplate template) {
        this.template = template;
        Constant.template = template;
    }
 
    ~~~
cs

 

사전에 , servlet-context.xml 파일에서 JdbcTemplate 타입의 bean을 생성한다.
 프로젝트가 시작될 때  JdbcTemplate 클래스의 bean을  JdbcTemplate 타입 변수에 넣어주도록 만든다.

9 :  JdbcTemplate 클래스 객체의 setter 메소드가 프로젝트가 시작될때 자동으로 실행되게 하기 위해서 @Autowired 어노테이션을 붙여준다.
@Autowired 어노테이션이 붙어있는 메소드의 인수로 스프링이 servlet-context.xml 파일에서 생성한 JdbcTemplate 클래스의 bean을 자동으로 넣어준다.

12 :  컨트롤러 이외의 클래스에서 JdbcTemplate을 사용할수 있게 하기 위해서
       적당한 이름의 패키지에 적당한 이름으로 클래스를 만들고 선언한 정적 변수에 servlet-context.xml 파일에서 생성된 JdbcTemplate 클래스의 bean을 넣어준다.   

 

-Constant.java-

1
2
3
4
5
public class Constant {
    //다른 클래스에서 접근해서 사용해야 하기때문에 ,public static 으로 선언
    public static JdbcTemplate template;
}
 
cs

 

-MvcboardDAO.java-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class MvcboardDAO {
 
    private JdbcTemplate template;
 
    public MvcboardDAO() {
        template = Constant.template;
    }
 
    public void insert(final MvcboardVO mvcboardVO) {
        String sql = "insert into mvcboard (idx,name,subject,content, ref , lev , seq) "
                + "values (mvcboard_idx_seq.nextval,?,?,?,mvcboard_idx_seq.currval,0,0)";
 
        template.update(sql,new PreparedStatementSetter() { 
            @Override
            public void setValues(PreparedStatement ps) throws SQLException {
                ps.setString(1, mvcboardVO.getName());
                ps.setString(2, mvcboardVO.getSubject());
                ps.setString(3, mvcboardVO.getContent());
            }
        });
    }
 
cs

 

3 : DAO 클래스에서 jdbc template 을 사용하기 위해서 JdbcTemplate 클래스 타입의 객체변수를 생성한다.

5~7 : 생성자에서 template을 초기화한다.

9 : 테이블내용이 변경되는 SQL 명령을 수행하려할때, 
메소드의 인수로 넘어오는 데이터는 중간에 값이 변경되면 안되기 때문에 fianl로 지정하도록 되어있다.

13 : 메소드의 인자로 ? 를 채울 익명객체가 들어간다.

15 :  오버라이드된 setValues메소드 에서 ? 를 채운다.

template.update(sql); => executeUpdate(sql)와 같은기능 
template.query(~);//테이블의 내용이 갱신되지 않는 sql 명령을 실행한다. => 실행결과가 여러건 일 경우 사용한다.
template.queryForObject(~);//테이블의 내용이 갱신되지 않는 sql 명령을 실행한다. =>실행결과가 1건일 경우.
template.queryForList(~);//테이블의 내용이 갱신되지 않는 sql 명령을 실행한다. =>  여러개 꺼내옴
template.queryForInt(~);// ( 비추천)테이블의 내용이 갱신되지 않는 sql 명령을 실행한다. =>  실행 결과가 정수 1건일 경우 사용한다.

 

 

다른 sql 문을 이용하는 경우를 보자..

 

1
2
String sql = "select count(*) from mvcboard";
return template.queryForObject(sql, Integer.class);
cs
1
2
3
4
5
6
String sql = "select * from ("+
        "select rownum rnum, AA.* from ("+
        "select * from mvcboard order by ref desc,seq asc"+
        ") AA where rownum <="+ hmap.get("endNo")+
        ") where rnum >="+hmap.get("startNo");
return (ArrayList<MvcboardVO>) template.query(sql, new BeanPropertyRowMapper(MvcboardVO.class));
cs

 

1~5 : dbcp template 을 사용하는 경우 select sql 명령에만 "?" 를 사용할 수 없다. => "?" 자리에 데이터가 저장된 변수를 사용한다.

8 : select sql 명령 실행 결과를 BeanPropertyRowMapper 클래스 생성자의 인수로
 MvcboardVO 클래스를 넘겨서 sql 명령 실행 결과를
저장시켜 리턴한다 .
 => List 타입으로 결과가 리턴되기 때문에 메소드의 리턴타입으로  형변환이 필요하다.
테이블의 필드 이름과 MvcboardVO클래스의 멤버 변수 이름이 반드시 같아야 정상적으로 실행된다.

 

-구성도-

-요약-

-마침글-

 

인용

 

728x90

-개발환경-

IDE : Eclipse 2018-12 (4.10.0)
Spring Tool Suite : 3.9.7.RELEASE
WAS : Pivotal tc Server Developer Edition v4.0 (피보탈 톰캣 서버)
DB : Oracle 11g

-설정-

-STS 브라우저 테스트환경 설정해주기-

WINDOW => Web Browser => Chrome 선택해서 테스트 환경을 크롬으로 잡아주기

-한글깨짐방지 태그 추가해주기-
web.xml 파일에서 아래 태그들 추가.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>
        org.springframework.web.filter.CharacterEncodingFilter     
    </filter-class>
    <init-param>
        <param-name>encoding</param-name>   
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>  
        <param-value>true</param-value>
    </init-param>
</filter>    
 
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>                 
</filter-mapping>
cs

DBCP를 위해, sever폴더의 context.xml 에 다음을 추가해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!--
    name : DBCP 이름, 커넥션 풀 이름, "jdbc/"는 항상 똑같이 쓰고 "/" 뒤에 커넥션 풀 이름을 적는다.
    type : 데이테베이스 연결에 사용할 자바 클래스 이름, 반드시 이 클래스를 사용해야 한다.
    auth : DBCP를 톰캣이 관리한다는 의미로 Container라 적어준다.
    maxActive : 데이터베이스 연결 풀의 최대값, 최대 연결 허용 개수
    maxIdle : 접속을 유지하는 데이터베이스 연결 풀의 최대 개수, 항상 연결을 유지하는 풀의 개수
    maxWait : 데이터베이스 접속을 위해서 기다리는 최대 시간, -1을 쓰면 대기 시간 없이 바로 접속한다.
    username : 사용자 계정
    password : 사용자 비밀번호
    driverClassName : 데이터베이스 드라이버 클래스 이름
    url : 데이터베이스 접속을 위한 경로
-->
<Resource
    name = "jdbc/oracle"                            
    auth = "Container"
    type = "javax.sql.DataSource"
    maxActive = "50"
    maxIdle = "20"
    maxWait = "-1"
    url = "jdbc:oracle:thin:@localhost:1521:xe"
    driverClassName = "oracle.jdbc.driver.OracleDriver"
    username = "Shin"
    password = "0000"
/>
cs


DBCP를 위해, pom.xml 에 다음을 추가해준다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<repositories>
    <repository>
        <!-- ORACLE -->
        <id>oracle</id>
        <name>ORACLE JDBC Repository</name>
        <url>http://maven.jahia.org/maven2</url>
    </repository>
</repositories>
<dependencies>
    <!-- MYSQL -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.39</version>
    </dependency>
 
    <!-- oracle -->
    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc6</artifactId>
        <version>12.1.0.1</version>
    </dependency>
 
    <!-- spring dbcp -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.1.4.RELEASE</version>
    </dependency>
</dependencies>
cs


DBCP를 을 위해, web.xml 에 다음을 추가해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- Mysql -->
<resource-ref>
    <description>DB Connection</description>
    <res-ref-name>jdbc/mysql</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>
<!-- Oracle -->
<resource-ref>
    <description>DB Connection</description>
    <res-ref-name>jdbc/oracle</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>
cs

 

 

실습에 앞서 , 개념을 알아보자.

 

DBCP : DB커넥션을 어플리케이션 소스 내에서 제어하면서 DB풀을 가진다.

JDBC는 데이터베이스 커넥션 인터페이스 이다. 

JNDI는 DB커넥션을 WAS단에서 제어하면서 서버에서 하나의 커넥션 풀을 가진다.

 

그럼, DB POOL 은 뭘까?  일단은  DB POOL = (DB) CONNECTION POOL 이라고 알아두고,

잘 설명되어 있는 아래 사이트를 보자.

brownbears.tistory.com/289

 

-구성도-

-MvcboardDAO-

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MvcboardDAO {
 
    DataSource dataSource;
    
    public MvcboardDAO() {
        try {
            Context context = new InitialContext();
            dataSource = (DataSource) context.lookup("java:/comp/env/jdbc/oracle");
            System.out.println("연결됨");
            
        }catch(Exception e) {
            e.printStackTrace();
            System.out.println("연결실패!!!");
        }
    }
cs

 

5 : DBCP 방식으로 DB와의 통신을 위해 ,  DAO서비스를 이용할때 마다 DAO bean을 생성해줘야한다(단점).

 

-MvcboardDAO-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void insert(MvcboardVO mvcboardVO) {
        System.out.println("MvcboardDAO 클래스의 insert() 메소드 -VO사용");
        Connection conn = null;
        PreparedStatement pstmt= null;
        try {
            conn = dataSource.getConnection();
            String sql = "insert into mvcboard (idx,name,subject,content, ref , lev , seq) "
                    + "values (mvcboard_idx_seq.nextval,?,?,?,mvcboard_idx_seq.currval,0,0)";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, mvcboardVO.getName());
            pstmt.setString(2, mvcboardVO.getSubject());
            pstmt.setString(3, mvcboardVO.getContent());
            pstmt.executeUpdate();
        }catch(Exception e) {
            e.printStackTrace();
        }finally {
            if(conn!=null) {
                try {
                    conn.close();
                } catch (SQLException e) { }
            }
        }
    }
cs

 

1 : 여러 DAO 메소드중 하나인 insert 메소드이다.

 

6~ : DataSource 객체에 연결하는 것부터 SQL 수행까지 여러작업들을 수행한다. ( 가장 코드가 김.. ) 

 

-HomeController.java-

1
2
3
4
5
6
7
8
@RequestMapping("/list")
    public String list(HttpServletRequest request, Model model) {
        model.addAttribute("request", request);
        AbstractApplicationContext ctx=new GenericXmlApplicationContext("classpath:applicationCTX.xml");
        MvcboardService service=ctx.getBean("select", MvcboardService.class);
        service.execute(model);
        return "list";
    }
cs

 

3  : Model 객체에 request를 통채로 저장하여 , 6번째 줄 같이 함수에 담아 보낸다. 

그럼 받는 곳에선 request 를 풀기 위해서 

 

1
2
Map<String,Object> map=model.asMap();
HttpServletRequest request=(HttpServletRequest) map.get("request");
cs

 

해당 방식처럼 request를 받는다.

컨트롤클래스에서 , 메소드끼리 만약 model 에 request가 아닌 다른 값을 넣어주고 받으려면

 

1
model.addAttribute("currentPage", Integer.valueOf(request.getParameter("currentPage")));
cs

 

1
request.getParameter("currentPage")
cs

 

이런식으로 이용할수 있다.

 

 

 

-요약-

-마침글-

 

인용

 

728x90

-개발환경-

IDE : Eclipse 2018-12 (4.10.0)
Spring Tool Suite : 3.9.7.RELEASE
WAS : Pivotal tc Server Developer Edition v4.0 (피보탈 톰캣 서버)

-설정-

-STS 브라우저 테스트환경 설정해주기-

WINDOW => Web Browser => Chrome 선택해서 테스트 환경을 크롬으로 잡아주기

-한글깨짐방지 태그 추가해주기-
web.xml 파일에서 아래 태그들 추가.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>
        org.springframework.web.filter.CharacterEncodingFilter     
    </filter-class>
    <init-param>
        <param-name>encoding</param-name>   
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>  
        <param-value>true</param-value>
    </init-param>
</filter>    
 
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>                 
</filter-mapping>
cs

-파일구성-

 

 

-HomeController.java-

1
2
3
4
5
6
7
8
9
10
11
12
    @RequestMapping("/memberView")
    public String memberView(HttpServletRequest request,Model model) {
        System.out.println("HomeController의 memberView() 메소드");
        String id = request.getParameter("id");
        String pw = request.getParameter("pw");
        System.out.println("id : "+id+", pw: "+pw);
        
        model.addAttribute("id",id);
        model.addAttribute("pw",pw);
        
        return "memberView";
    }
cs

 

2 : 뷰 페이지에서 넘어온 데이터는 
    HttpServletRequest 인터페이스 객체에 저장된다.
4,5 : 데이터를 받아온다.

8,9 : controller에서 뷰페이지로 넘겨줄 데이터를 Model인터페이스객체에 저장한다.

 

-HomeController.java-

1
2
3
4
5
6
7
8
9
10
@RequestMapping("/memberLogin")
    public String memberLogin(Model model,@RequestParam("id"String id,
            @RequestParam("pw"String pw) {
        System.out.println("HomeController의 memberLogin() 메소드");
        System.out.println("id : "+id+",pw : "+pw);
        model.addAttribute("id",id);
        model.addAttribute("pw",pw);
        
        return "memberLogin";
    }
cs

 

2,3 : @RequestParam("뷰 페이지에서 컨트롤러로 넘어오는 변수명") 자료형 변수명   꼴로 이용한다.
       id ,pw 같은 소량의 데이터를 받을때 유용.
       뷰 페이지에서 컨트롤러로 넘어오는 id,pw를 받아서  변수에 대입된다.

기존의 HttpServletRequest 객체를 이용하는 것과의 차이를 이해하자!

뷰페이지에서 컨트롤러로 데이터가 넘어오지 않을때,
HttpServletRequest인터페이스객체는  에러 발생하지 않음. 
하지만 @RequestParam 은 400에러 발생함.

 

-HomeController.java-

1
2
3
4
5
6
@RequestMapping("/memberInsert")
     public String memberInsert(HttpServletRequest request,
             Model model,@ModelAttribute("vo") MemberVO memberVO) {
        System.out.println("컨트롤러의 memberInsert메소드");
        return "memberInsert";
    }
cs

 

3 : 어노테이션으로 커맨드객체명을 vo로 지정해주었다.

    어노테이션 지정을 안할것이면 , '@ModelAttribute("vo") MemberVO memberVO' 대신에

    'MemberVO memberVO' 만 작성해주면 된다.

 

-커멘드(데이터) 객체 -

뷰페이지 -> 컨트롤러로 넘어오는 데이터를 클래스 객체에 저장하려는 경우
 커맨드객체를 사용하면 편리하다.
커맨드객체는 아래의 기능들을 합친것과 동일하다.
1.  HttpServletRequest 인터페이스 객체나 @RequestParam 어노테이션으로
    데이터를 받아서 클래스객체에 setter 메소드로 저장한 다음 
2.  Model 인터페이스객체에 넣어주는 동작.

커맨드객체의 이름은 반드시  커맨드객체를 생성할 클래스 이름과 동일하게 작성해야 하고
 첫 문자만 소문자로 바꿔 사용해야한다.
자동으로 객체도 생성이됨

-어노테이션으로 커맨드객체 명 변경하기-

뷰페이지로 넘겨주는 커멘드객체이름을 별도로 지정해서 사용하려면
어노테이션을 이용해 뷰페이지로 넘겨주는 커멘드객체의 이름을 변경할 수 있다.
이 경우 기존 커멘드객체 이름은 사용할 수 없고 @ModelAttribute 어노테이션으로 지정한 
커맨드객체 이름을 사용해야 한다.

 

 

-memberInsert.jsp-

1
2
3
4
5
6
7
8
9
10
11
12
<body>
    ${vo.name}</br>
    ${vo.id}</br>
    ${vo.password}</br>
    ${vo.email}
    <hr/>
    
    ${memberVO.name}</br>
    ${memberVO.id}</br>
    ${memberVO.password}</br>
    ${memberVO.email}
</body>
cs

 

아래 결과를 보면,

어노테이션 커맨드객체명으로 vo로 명시해주었기에  <hr/>기준 윗부분만 결과로 나온것을 확인할수 있다.

 

출력결과

-요약-

-마침글-

 

인용

 

728x90

-개발환경-

IDE : Eclipse 2018-12 (4.10.0)
Spring Tool Suite : 3.9.7.RELEASE
WAS : Pivotal tc Server Developer Edition v4.0 (피보탈 톰캣 서버)

-설정-

-서버 포트번호 변경-


서버가 오라클,SQL 포트번호와 충돌안나게 안쓰는것으로 변경해주는것이 목표.
디폴트로 서버 포트번호는 8080임 
서버들어가서 => Properties의 nio.http.port 를 9090이나 남는 포트번호로 변경하기


-STS 브라우저 테스트환경 설정해주기-
WINDOW => Web Browser => Chrome 선택해서 테스트 환경을 크롬으로 잡아주기

-한글깨짐방지 태그 추가해주기-
web.xml 파일에서 아래 태그들 추가.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>
        org.springframework.web.filter.CharacterEncodingFilter     
    </filter-class>
    <init-param>
        <param-name>encoding</param-name>   
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>  
        <param-value>true</param-value>
    </init-param>
</filter>    
 
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>                 
</filter-mapping>
cs

-파일구성-

 

 

-servlet-context.xml-

1
<context:component-scan base-package="com.koreait.springMVCSample" />
cs

 

server-context.xml 에서
<context:component-scan base-package="com.koreait.springMVCSample" /> 가 의미하는것은 아래와 같다.
controller가 있는 패키지 경로를 잡아준다.
base-package는 프로젝트를 생성할때 사용자가 입력한 내용으로 만들어주는 패키지로
@Controller어노테이션을 붙여준 컨트롤러 클래스 파일을 읽어들이는 기본 위치가 된다. 
즉 , @Controller 어노테이션이 붙어있다고 해서 모두 컨트롤러로 인식되는 것이 아니고 
base-package로 지정된 곳에서 @Controller어노테이션이 붙어 있는 클래스만 컨트롤러로 인식한다.

 

-servlet-context.xml-
1
2
3
4
5
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="suffix" value=".jsp" />
</beans:bean>
cs

 

servlet-context.xml의 <beans:bean> 태그에서,
컨트롤러 클래스의 @RequestMapping 어노테이션이 붙은 메소드가 리턴하는 view 페이지 이름,앞,뒤에 
자동으로 붙여줄 내용을 지정한다.
@RequestMapping 어노테이션이 붙은 메소드가 리턴하는 view 페이지 이름이 "home" 이라면
"/WEB-INF/views/home.jsp" 가 된다.

 

-HomeController.java-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.koreait.springMVCSample;
 
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
 
@Controller
public class HomeController {
    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
 
    @RequestMapping( "/index.nhn")
    public String home() {
        return "home"
    }
}
cs

 

18 : 주소창에 서비스 요청이 들어오면 컨트롤러클래스의 
     @RequestMapping 어노테이션의 인수로 지정된 value 속성(생략가능)과
     일치되는지 비교후,  일치된다면 @RequestMapping 어노테이션이 붙어 있는 
     메소드가 실행된다.

     @RequestMapping 속성으로 RequestMethod.GET 이 지정되면 get 방식의 요청만 
     처리할 수 있고 RequestMethod.POST가  지정되면 post방식의 요청만 처리할 수 있다. 
     추가로 , 요청방식이 일치하지 않으면 405 에러가 발생된다.
     ex) @RequestMapping(value = "/", method = RequestMethod.POST)

     아래와 같이 @RequestMapping 어노테이션에서 method 속성을 생략하면 get방식과 post 방식을
     구분하지 않고 모든 요청을 받아 처리할 수 있다.
     value 속성만 남았을때, 'value=' 는 생략 가능

20 : @RequestMapping 어노테이션이 붙은 메소드는
      수행후 view페이지(jsp파일)이름을 리턴시킨다.
      view 페이지 이름은 문자열이므로 메소드의 리턴 타입은 String 이 되고 
      리턴되는 view 페이지 이름의 앞,뒤에 붙여주는 내용은 servlet-context.xml
      파일에서설정한다

 

-MyController.java-

1
2
3
4
5
6
7
@Controller
public class MyController {
    @RequestMapping("/view")    
    public  String view() {
        System.out.println("MyController의 view() 메소드 실행");
        return "view";
    }
cs

일반적인 SPRING MVC 순서. 
     클라이언트로 부터 서비스 요청이 들어왔을 때 , 컨트롤러로 진입하게 되고 
     컨트롤러는 요청에 따른 작업을 실행한 후 뷰 페이지로 데이터를 전달한다.

컨트롤러 제작순서
1. base-package로 지정된 패키지에 임의의 이름으로 클래스를 만들고 @Controller 어노테이션을 붙여서
   컨트롤러로 사용할 클래스임을 스프링에게 알려준다.
2. @RequestMapping어노테이션의 인수로 클라이언트에서 넘어오는 것을 지정한다.
   3.요청을 처리할 임의의 이름의 메소드를 만든다. 
   뷰 페이지 이름은 문자열이므로 메소드의 리턴 타입은 String으로 지정한다.
4. 작성한 메소드에서 필요한 작업을 모두 완료한 후 뷰 페이지(jsp 파일)의 이름을 리턴시킨다.

 

-MyController.java-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Controller
public class MyController {
 
    ~~~생략~~~
 
@RequestMapping("/model")
    public String model(Model model) {
        System.out.println("MyController의 model() 메소드 실행");
        model.addAttribute("id","asdfg");
        model.addAttribute("pw","12345");
        model.addAttribute("name","홍길동");
        
        return "model/model";
    }
    ~~~생략~~~
cs

 

7 : @RequestMapping 어노테이션이 설정된 메소드는
    Model 인터페이스 객체를 인수로 가질수 있다.
    Model 인터페이스 객체는 컨트롤러에서 뷰 페이지로 넘겨줄 데이터를 저장한다. 
    jsp 의 response객체와 같은 역할을 한다.

9~11 : Model객체변수.addAttribute(key,value) : Model 인터페이스 객체에
          key에 따른  value를 넣어준다.

13 : servlet_context.xml 파일에 의해서 "/WEB-INF/views/model/model.jsp"로 변환된다.
      그리고 해당파일 호출.

-MyController.java-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Controller
public class MyController {
    ~~~ 생략 ~~~
 
@RequestMapping("/modelAndView")
    public ModelAndView modelAndView(Model model) {
        System.out.println("MyController의 modelAndView() 메소드 실행");
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("modelAndView/modelAndView");
        modelAndView.addObject("id","qwert");
        modelAndView.addObject("pw","67890");
        modelAndView.addObject("name","임꺽정");    
        return modelAndView;
    }
}
cs

 

6 : ModelAndView 클래스 객체는 컨트롤러에서 뷰페이지로 
    뷰 페이지 이름과  데이터를 저장한다.
    뷰 페이지 이름과 뷰페이지로 넘겨줄 데이터를 ModelAndView 클래스 객체에 저장해서
    리턴 시켜야 하므로 메소드의 리턴 타입은 ModelAndView를 사용한다.

기존의 방식은 String을 리턴타입으로 하였다. 차이점 숙지.

8 : 뷰 페이지로 넘겨줄 데이터와 뷰페이지 이름을 저장할 ModelAndView 클래스 객체를 생성한다.

9 : setViewName() : 뷰 페이지 이름을 넣어준다.

10~ 12 : addObject(key,value) : 뷰 페이지로 넘겨줄 데이터를 KEY-VALUE로 저장한다.

13 : ModelAndView  객체를 리턴한다.

 

-YourController.java-(자주 사용되지는 않는다.)

1
2
3
4
5
6
7
8
9
10
@Controller
@RequestMapping("/board")
public class YourController {
 
    @RequestMapping("/contentView")
    public String contentView() {
        System.out.println("YourController의 contentView() 메소드 실행");
        return "board/contentView";
    }
}
cs

 

controller클래스에 @RequestMapping 어노테이션이 직접적으로 붙는다면 ,
controller에 붙은 어노테이션과 메소드에 붙은 어노테이션을 합쳐서
요청해야 뷰페이지를 제대로 찾아갈 수 있다.
이 예제에선 /board/contentView 로 요청해야한다.

 

-servlet-context.xml-

1
2
3
4
<resources mapping="/resources/**" location="/resources/" />
<resources mapping="/images/**" location="/WEB-INF/images/" /> 
<resources mapping="/css/**" location="/WEB-INF/css/" /> 
<resources mapping="/js/**" location="/WEB-INF/js/" /> 
cs

 

resources 태그의 mapping 속성에 지정된 요청이 들어오면 controller클래스를 검색하지 않고 
resources 태그의 location 속성에 지정된 경로를 검색한다.
위의 예에서는 image,css,js 경로를 잡아주었다.

 

 

-model.jsp-

1
2
<link rel="stylesheet" type="text/css" href="css/style.css" >
<script type="text/javascript" src="js/script.js"></script>
cs

css폴더와 , js폴더의 경로는 servlet-context.xml에서 미리 mapping된 경로를 따라간다.

 

-model.jsp-

1
2
3
4
5
6
7
8
9
10
<body>
    <h1 onclick="hello()">model.jsp 입니다<br/></h1>
 
    id: ${id}<br/>
    pw: ${pw}<br/>
    name: ${name}<br/>
    
    <img alt="아무이미지" src="./images/download.jpg"/>
</body>
</html>
cs

4~6 : controller에서 Model인터페이스객체에 저장되서 넘어오는 데이터는
        EL 을 사용해서 얻어오면 된다.
8 : 이미지 src 경로는 servlet-context.xml 에서 미리 정의된 resource mapping을 따라간다.

 

-요약-

-마침글-

 

인용

 

728x90

-개발환경-

IDE : Eclipse 2018-12 (4.10.0)
Spring Tool Suite : 3.9.7.RELEASE
WAS : Pivotal tc Server Developer Edition v4.0 (피보탈 톰캣 서버)

-설정-

-서버 포트번호 변경-


서버가 오라클,SQL 포트번호와 충돌안나게 안쓰는것으로 변경해주는것이 목표.
디폴트로 서버 포트번호는 8080임 
서버들어가서 => Properties의 nio.http.port 를 9090이나 남는 포트번호로 변경하기


-STS 브라우저 테스트환경 설정해주기-
WINDOW => Web Browser => Chrome 선택해서 테스트 환경을 크롬으로 잡아주기

-한글깨짐방지 태그 추가해주기-
web.xml 파일에서 아래 태그들 추가.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>
        org.springframework.web.filter.CharacterEncodingFilter     
    </filter-class>
    <init-param>
        <param-name>encoding</param-name>   
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>  
        <param-value>true</param-value>
    </init-param>
</filter>    
 
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>                 
</filter-mapping>
cs

-파일구성-

 

 

-servlet-context.xml-

1
<context:component-scan base-package="com.koreait.springMVCSample" />
cs

 

server-context.xml 에서
<context:component-scan base-package="com.koreait.springMVCSample" /> 가 의미하는것은 아래와 같다.
controller가 있는 패키지 경로를 잡아준다.
base-package는 프로젝트를 생성할때 사용자가 입력한 내용으로 만들어주는 패키지로
@Controller어노테이션을 붙여준 컨트롤러 클래스 파일을 읽어들이는 기본 위치가 된다. 
즉 , @Controller 어노테이션이 붙어있다고 해서 모두 컨트롤러로 인식되는 것이 아니고 
base-package로 지정된 곳에서 @Controller어노테이션이 붙어 있는 클래스만 컨트롤러로 인식한다.

 

-servlet-context.xml-
1
2
3
4
5
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="suffix" value=".jsp" />
</beans:bean>
cs

 

servlet-context.xml의 <beans:bean> 태그에서,
컨트롤러 클래스의 @RequestMapping 어노테이션이 붙은 메소드가 리턴하는 view 페이지 이름,앞,뒤에 
자동으로 붙여줄 내용을 지정한다.
@RequestMapping 어노테이션이 붙은 메소드가 리턴하는 view 페이지 이름이 "home" 이라면
"/WEB-INF/views/home.jsp" 가 된다.

 

-HomeController.java-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.koreait.springMVCSample;
 
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
 
@Controller
public class HomeController {
    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
 
    @RequestMapping( "/index.nhn")
    public String home() {
        return "home"
    }
}
cs

 

18 : 주소창에 서비스 요청이 들어오면 컨트롤러클래스의 
     @RequestMapping 어노테이션의 인수로 지정된 value 속성(생략가능)과
     일치되는지 비교후,  일치된다면 @RequestMapping 어노테이션이 붙어 있는 
     메소드가 실행된다.

     @RequestMapping 속성으로 RequestMethod.GET 이 지정되면 get 방식의 요청만 
     처리할 수 있고 RequestMethod.POST가  지정되면 post방식의 요청만 처리할 수 있다. 
     추가로 , 요청방식이 일치하지 않으면 405 에러가 발생된다.
     ex) @RequestMapping(value = "/", method = RequestMethod.POST)

     아래와 같이 @RequestMapping 어노테이션에서 method 속성을 생략하면 get방식과 post 방식을
     구분하지 않고 모든 요청을 받아 처리할 수 있다.
     value 속성만 남았을때, 'value=' 는 생략 가능

20 : @RequestMapping 어노테이션이 붙은 메소드는
      수행후 view페이지(jsp파일)이름을 리턴시킨다.
      view 페이지 이름은 문자열이므로 메소드의 리턴 타입은 String 이 되고 
      리턴되는 view 페이지 이름의 앞,뒤에 붙여주는 내용은 servlet-context.xml
      파일에서설정한다

 

-요약-



 

-마침글-

 

인용

 

728x90

-개발환경-

IDE : Eclipse 2018-12 (4.10.0)
Spring Tool Suite : 3.9.7.RELEASE

-설정-

SPRING 에서 AOP를 사용하기 위해 AOP 라이브러리를 설치해야 한다. 

여기선 AOP 라이브러리들중 aspectj를 다루고 내용은 아래와 같다.

 

pom.xml 파일의 <dependencies> ~ </dependencies> 사이에 아래의 내용을 추가한다.
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.0</version>
<scope>runtime</scope>
</dependency>

-파일구성-

Student.java - 학생VO클래스+핵심메소드 인 클래스

Worker.java - 직장인VO클래스+핵심메소드 인 클래스

LogAOP.java - AOP어노테이션 + 공통기능 메소드(before,after,...)들 인 클래스

applicationCTX.xml - bean객체관리 , AOP일부 태그이용

MainClass.java

 

-LogAOP.java-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@Aspect
public class LogAOP {
    
    @Pointcut("within(com.koreait.springAOP2_java.Student)")
    public void pointcutMethod() {
    }
    @Before("pointcutMethod()")
    public void before() {
        System.out.println("LogAOP 클래스의 before() 메소드가 실행됨");
    }
    @AfterReturning("pointcutMethod()")
    public void afterReturning() {
        System.out.println("LogAOP 클래스의 afterReturning() 메소드가 실행됨");
    }
    @AfterThrowing("pointcutMethod()")
    public void afterThrowing() {
            System.out.println("LogAOP 클래스의 afterThrowing() 메소드가 실행됨");
    }
    @After("pointcutMethod()")
    public void after() {
        System.out.println("LogAOP 클래스의 after() 메소드가 실행됨");
    }
    
    @Around("execution(* com.koreait.springAOP2_java.Worker.*())")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
            System.out.println("LogAOP 클래스의 around() 메소드가 실행됨 - 핵심 기능 실행 전");
            long startTime = System.currentTimeMillis();
        try {
            System.out.println("LogAOP 클래스의 around() 메소드가 실행됨 - 핵심 기능 실행 중");
            Object object = joinPoint.proceed();
            return object;
        }finally {
            System.out.println("LogAOP 클래스의 around() 메소드가 실행됨 - 핵심 기능 실행 후");
            long endTime=System.currentTimeMillis();
            System.out.println("핵심 기능이 실행되는데 걸린 시간 : "+(endTime-startTime)/1000.+"초");
        }
    }
}
cs

 

 

1 : java 파일을 이용해서 AOP 설정을 하려면 
    AOP를 설정할 클래스에 @Aspect 어노테이션을 붙여준다.

pointcut을 지정하는 첫 번재 방법 
              1. 함수내용이 empty한 적당한 이름을 가진 메소드를 만든다.
              2. empty한 메소드 위에 @Pointcut 어노테이션을 붙여서 인수에 공통함수가 실행될 경로(pointcut)를 지정한다.
              3. AOP 어노테이션(@Before ,@AfterReturning, @AfterThrowing,@After,@Around) 을 의미가 동일한 메소드위에 각각 적어준다. 
              4. AOP 메소드각각에 pointcut(공통함수가 실행될 경로)을 지정하려면
              AOP 어노테이션(@Before ,@AfterReturning, @AfterThrowing,@After,@Around)의 인수로 pointcut 메소드를 적어준다.

4~22 : pointcut을 지정하는 첫 번재 방법이다.

pointcut을 지정하는 두 번재 방법 
1. AOP 어노테이션(@Before ,@AfterReturning, @AfterThrowing,@After,@Around) 을 의미가 동일한 메소드위에 각각 적어준다.
              2. AOP 어노테이션의 인수에 pointcut을 바로 지정할 수 있다.

24~25 : pointcut을 지정하는 두 번재 방법을 이용하였다.

 

-applicationCTX.xml-

1
2
3
4
5
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
cs

 

3 : aop namespace를 잡아준다.

 

-applicationCTX.xml-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    <aop:aspectj-autoproxy/>
    
    <bean id="LogAop" class="com.koreait.springAOP2_java.LogAOP"/>
 
    <bean id="student" class="com.koreait.springAOP2_java.Student">
        <property name="name" value="홍길동"/>
        <property name="age" value="15"/>
        <property name="gradeNum" value="2"/>
        <property name="classNum" value="1"/>
    </bean>
    <bean id="worker" class="com.koreait.springAOP2_java.Worker">
        <constructor-arg value="조세길"/>
        <constructor-arg value="20"/>
        <constructor-arg value="웹개발자"/>
    </bean>
</beans>
cs

 

1 : @Aspect 어노테이션을 붙여서 AOP를 설정한 java클래스를 읽어오기 위해서
    <aop:aspectj-autoproxy/> 태그를 추가한다.

3 : AOP 메소드와 설정이 저장된 @Aspect 어노테이션을 붙여준 클래스의 bean을 만든다.

 

-MainClass.java-

1
2
3
4
5
6
7
8
9
10
AbstractApplicationContext ctx = new GenericXmlApplicationContext("classpath:applicationCTX.xml");
Student student=ctx.getBean("student", Student.class);
Worker worker=ctx.getBean("worker", Worker.class);
System.out.println("=================================");
student.getStudentInfo();
System.out.println("=================================");
worker.getWorkerInfo();
System.out.println("=================================");
student.afternoon();
System.out.println("=================================");
cs

 

1 : AbstractApplicationContext-GenericXmlApplicationContext 형태로 컨테이너를 생성한다.

결과를 보자.

출력결과

 

-요약-



 

-마침글-

 

인용

 

728x90

-개발환경-

IDE : Eclipse 2018-12 (4.10.0)
Spring Tool Suite : 3.9.7.RELEASE

-설정-

SPRING 에서 AOP를 사용하기 위해 AOP 라이브러리를 설치해야 한다. 

여기선 AOP 라이브러리들중 aspectj를 다루고 내용은 아래와 같다.

 

pom.xml 파일의 <dependencies> ~ </dependencies> 사이에 아래의 내용을 추가한다.
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.0</version>
<scope>runtime</scope>
</dependency>

-파일구성-

Student.java - 학생VO클래스+핵심메소드 인 클래스

Worker.java - 직장인VO클래스+핵심메소드 인 클래스

Test.java - 외부패키지에 존재하며 , 단순 IntanceMethod 한기 보유한 클래스

LogAOP.java - 공통기능 메소드(before,after,...)를 모아놓은 클래스

applicationCTX.xml - bean객체 , aop태그들을 다루는 파일

MainClass.java

 

-LogAOP.java-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class LogAOP {    
    public void before() {
        System.out.println("LogAOP 클래스의 before() 메소드가 실행됨");
    }
    public void afterReturning() {
        System.out.println("LogAOP 클래스의 afterReturning() 메소드가 실행됨");
    }
    public void afterThrowing() {
            System.out.println("LogAOP 클래스의 afterThrowing() 메소드가 실행됨");
    }
    public void after() {
        System.out.println("LogAOP 클래스의 after() 메소드가 실행됨");
    }
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
            System.out.println("LogAOP 클래스의 around() 메소드가 실행됨 - 핵심 기능 실행 전");
            long startTime = System.currentTimeMillis();
        try {
            System.out.println("LogAOP 클래스의 around() 메소드가 실행됨 - 핵심 기능 실행 중");
            Object object = joinPoint.proceed();
            return object;
        }finally {
            System.out.println("LogAOP 클래스의 around() 메소드가 실행됨 - 핵심 기능 실행 후");
            long endTime=System.currentTimeMillis();
            System.out.println("핵심 기능이 실행되는데 걸린 시간 : "+(endTime-startTime)/1000.+"초");
        }
    }
}
cs

 

around기능보유한 메소드 작성법 ( 개념은 chewingcandy.tistory.com/80 참고) 은 아래와 같다.

1. around AOP 메소드는 핵심기능이  실행되고 난 후 리턴되는 데이터 타입을 예측할 수 없으므로 반드시 리턴 타입을 Object로 지정해야 한다.
2. around AOP 메소드의 인수로 실행할 핵심 기능(메소드)이 넘어온다. => 반드시 인수로 ProceedingJoinPoint 인터페이스 타입의 변수를 사용한다.
3. around  AOP 메소드는 try ~ finally 형태로 실행되며 catch는 throws Throwable로 대체된다.

16 : 핵심 기능이 실행되기 전의 시간을 저장한다

17~20 : try 블록에서 핵심 기능을 실행한다.


19 : ProceedingJoinPoint 인터페이스 객체로 넘어온 핵심 기능을 실행한다.

20 : 핵심 기능을 실행한 결과를 리턴한다.

21~25 : finally 블록 내에서 핵심 기능이 실행되고 난 후 실행할 내용을 코딩한다.

23 : 핵심 기능이 종료되고 난 후 시간을 저장한다.

 

 

-applicationCTX.xml-

1
2
3
4
5
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
cs

 

3 : beans 태그에 aop namespace 를 추가해준다.

 

 

-applicationCTX.xml-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
     <bean id="logAop" class="com.koreait.springAOP1_xml.LogAOP"/>
        <aop:config>
            <aop:aspect id="logger" ref="logAop">      
                <aop:pointcut expression="within(*)" id="beforeMethod"/>
                <aop:pointcut expression="within(*)" id="afterReturningMethod"/>
                <aop:pointcut expression="within(*)" id="afterThrowingMehod"/>        
                <aop:pointcut expression="execution(* com.koreait.springAOP1_xml.Student.*())" id="afterMethod"/>
                <aop:pointcut expression="execution(* com.koreait.springAOP1_xml.Student.*())" id="aroundMethod"/>
        
                <aop:before method="before" pointcut-ref="beforeMethod"/>
                <aop:after-returning method="afterReturning" pointcut-ref="afterReturningMethod"/>
                <aop:after-throwing method="afterThrowing" pointcut-ref="afterThrowingMehod"/>
                <aop:after method="after" pointcut-ref="afterMethod"/> 
                <aop:around method="around" pointcut-ref="aroundMethod"/> 
            </aop:aspect>
        </aop:config>
</beans>
cs

 

1 : AOP 관련 메소드들이 작성된 클래스의  bean을 생성한다.

2 :  aop:config 태그 내부에 aop:aspect 태그로 공통 기능 메소드를 정의한다. 

3 :  id 속성으로 AOP 메소드모음 객체인 bean을 식별한다. 식별만 가능하면 되므로 뭐를 적어도 상관없다.
     ref속성에는 AOP메소드모음 객체인 bean을 참조시킨다.  bean의 id 속성의 값을 쓴다.

4~8 : AOP가 실제로 시행될 경로를 잡아주고 id를 달아준다.
        먼저 , aop:pointcut 태그에서 공통 기능이 적용될 부분(pointcut)을 지정한다.  
        expression 속성은 within() 또는 execution()을 사용해서 pointcut을 지정한다. 
        within()은 클래스 단위로 pointcut을 지정하고
        execution()은 메소드 단위로 pointcut을 지정한다.  
        <aop:pointcut>의 id 속성은 pointcut을 식별하기만 하면 되기 때문에 뭐를 적어도 상관없다.

within(*) => 프로젝트의 모든 클래스에 AOP가 적용된다.
within(test.*) => test 패키지의 모든 클래스에 AOP가 적용된다.
within(com.koreait.springAOP1_xml.*) =>  com.koreait.springAOP1_xml 패키지의 모든 클래스지정
within(com.koreait.springAOP1_xml.Worker) => com.koreait.springAOP1_xml 패키지의 Worker 클래스지정
within(com.koreait.springAOP1_xml.*d*) => com.koreait.springAOP1_xml 패키지의 "d" 를 포함하는 클래스들 지정
 d* : d로 시작한다는 의미 , *d : d 로 끝나는 , *d* : d를 포함하는

execution() 은 () 안에 "*"을 먼저 입력하고 1칸 띄운 후 pointcut을 지정한다.
execution(* test.*.*()) => 구조를 볼때 ,  패키지이름.클래스이름.메소드이름() 꼴임.
execution(* *.*()) => 프로젝트의 모든 클래스의 모든 메소드.


10~14 :  method 속성에는  AOP메소드모음 클래스의 AOP 메소드이름을  적는다. 
            pointcut-ref 속성에는 <aop:pointcut>태그의 id 값을 써준다.

즉, 예시로 <aop:before>태그에서 수행할 AOP메소드를 결정해주고 , 
<aop:pointcut>태그에서 수행할 경로를 결정해주는 것이다.

10 :  핵심기능 실행전 메소드수행태그
11 :  핵심기능이 정상적으로 종료된 후 메소드수행태그
12 : 핵심 기능 실행중 예외가 발생된 후 메소드수행태그
13 : 핵심 기능이 예외 발생 여부와 관계 없이 종료된 후 수행되는 메소드수행태그
14 : exception 발생 여부와 관계없이 핵심 기능이 실행되기 전과 실행되고 난 후 둘다 수행되는 메소드수행태그

 

 

-MainClass.java-

1
2
3
4
5
6
7
8
9
10
11
12
13
AbstractApplicationContext ctx = new GenericXmlApplicationContext("classpath:applicationCTX.xml");
Student student=ctx.getBean("student", Student.class);
Worker worker=ctx.getBean("worker", Worker.class);
Test test=ctx.getBean("test", Test.class);
System.out.println("=================================");
student.getStudentInfo();
System.out.println("=================================");
worker.getWorkerInfo();
System.out.println("=================================");
test.test();
System.out.println("=================================");
student.afternoon();
System.out.println("=================================");
cs

 

1 : 일반적인 AbstractApplicationContext - GenericXmlApplicationContext 방식을 사용하여 bean을 생성하였다.

2~4 : 각각의 객체를 받아온 후.

6~ : 나름 핵심기능이라고 내 스스로 정의한 메소드를 실행시켜보았다.

 

출력결과

 

-요약-



 

-마침글-

 

인용

 

+ Recent posts