728x90

강좌에서 bean이 아닌, beans:bean으로 써서, 무슨 의미인지 찾아보니,

아웃태그를 줄여서 쓰는 것이라고 한다.

 

즉, 아래는

<beans:bean id="test" class="testclass">
  <property name="pw" value="pw"/>
  <property name="id" value="id"/>
</beans:bean>​

다음과 동일하다.

<beans>
  <bean id="test" class="testclass">
    <property name="pw" value="pw"/>
    <property name="id" value="id"/>
  </bean>
</beans>

 

 

 

 

Reference

https://okky.kr/article/478569

728x90
728x90

Reference

 

[스프링] Spring 프레임워크에서 @RequestBody 사용해서 vo를 따로 만들지 않고 Map으로 파라미터 값 자동 매핑(mapping)하기

https://zzznara2.tistory.com/761

 

@ResponseBody 이해하기

https://ismydream.tistory.com/140

 

 

 

 

 

메소드에 @ResponseBody 로 어노테이션이 되어 있다면 메소드에서 리턴되는 값은 View 를 통해서 

출력되지 않고 HTTP Response Body 에 직접 쓰여지게 됩니다.

이때 쓰여지기 전에 리턴되는 데이터 타입에 따라 MessageConverter 에서 변환이 이뤄진 후 쓰여지게 됩니다.

 

MessageConverter 의 종류

- StringHttpMessageConverter

- FormHttpMessageConverter

- ByteArrayMessageConverter

- MarshallingHttpMessageConverter

- MappingJacksonHttpMessageConverter

Jackson's ObjectMappter 를 사용하여 request, response 를 JSON 으로 변환할때 사용되는 MessageConverter 이다.

applicaton/json 을 지원한다.

- SourceHttpMessageConverter

- BufferedImagedHttpMessageConverter

 

아래는 MessageConvert 와 View 를 같이 사용하는 예제

getByIdInJSON 메소드의 경우 @ResponseBody 어노테이션이 있는 반면에 getByidInHTML 은 어노테이션이 없다.

@ResponseBody 가 있는 getByIdInJSON 메소드는 리턴값이 UserModel 객체가 MessageConvert 로 설정된  MappingJacksonHttpMessageConverter 에서 JSON 으로 변환 작업이 이뤄지고

@ResponseBody 가 없는 getByIdInHTML 메소드는 ViewResolver 에 의해 선택된 /WEB-INF/jsp/user.jsp 에서 처리가 이뤄지게 됩니다.

 

자바 코드

@Controller

@RequestMapping("/user")

public class UserController {

 

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

@ResponseBody

public UserModel getByIdInJSON( @PathVariable String id){

 

UserModel user = new UserModel();

user.setId( id);

user.setName( "ellie");

 

return user;

}

 

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

public String getByIdInHTML( @PathVariable String id, ModelMap model){

UserModel user = new UserModel();

user.setId( id);

user.setName( "ellie");

 

model.addAttribute( "user", user);

 

return "user";

}

}

 

xxx-servler.xml 파일

 

<bean id="jsonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">

<property name="messageConverters">

  <list>

<ref bean="jsonHttpMessageConverter"/>

  </list>

</property>

</bean>

 

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

<property name="prefix" value="/WEB-INF/jsp/"></property>

<property name="suffix" value=".jsp" />

</bean>

 

 

 

728x90
728x90

1. Application Context와 Servlet Context 설정과 Transaction
출처: https://hoonmaro.tistory.com/31 [훈마로의 보물창고]

Application Context

  • 전체 계층구조에서 최상단에 위치한 컨텍스트
  • 서로 다른 서블릿 컨텍스트에서 공유해야하는 Bean들을 등록해놓고 사용할 수 있다.
  • 웹 애플리케이션 전체에 적용 가능한 프로퍼티, DB 연결, 로깅 기능 등에 이용한다.
  • Servlet Context에 등록된 Bean은 이용할 수 없다.
  • Servlet Context에 동일한 Bean이 있을 경우 Servlet Context Bean이 우선된다.
  • 하나의 컨텍스트에 정의된 AOP 설정은 다른 컨텍스트의 Bean에는 영향을 미치지 않는다.

Servlet Context

  • 서블릿에서만 이용되는 컨텍스트
  • 다른 서블릿과 공유하기 위한 Bean들은 Application Context에 등록해놓고 사용해야 한다.
  • DispatcherServlet은 자신만의 컨텍스트를 생성, 초기화하고 동시에 Application Context를 찾아서 자신의 부모 컨텍스트로 사용한다.

 

IoC 컨테이너 구성방법

  1. Application Context만 이용
  2. Servlet Context만 이용
  3. Application Context와 Servlet Context 하나씩 이용
  4. Application Context와 Servlet Context여러 개 이용
  5. 여러 Application Context와 Servlet Context 하나 이용
    •  Application Context 설정을 목적에 맞게 분류 (Property, Validation, sqlMap, datasource, aop 등)

Component Scan 사용시 컨텍스트 설정 방법

  • Application Context에 Service, Repository, Servlet Context에 Controller만 등록해야한다.
  • Application Context 설정

    • Service와 Repository는 Include 하고 Controller는 Exclude 한다.
  • Servlet Context 설정
    • Service와 Repository는 Exclude 하고 Controller는 Include 한다.

 

  • 이렇게 설정하는 이유는 스프링이 Transaction을 적용하기 위해서이다.
  • 스프링 트랜잭션은 AOP를 이용해서 해당 빈의 proxy를 만들어서 tx가 적용되는 bean을 바꿔치기 한다. 그러면 원래 @Service(또는 @Transactional) 어노테이션이 붙은 빈은 뒤로 숨고 tx가 적용된 proxy bean이 @Service가 붙은 bean으로 대치된다.
  • 만약 Application Context와 Servlet Context가 모든 stereotype의 컴포넌트를 풀 스캔 할 경우, tx 설정은 Application Context에만 적용되어 있기 때문에 Application Context의 @Service는 트랜잭션이 적용이 되지만 Servlet Context의 @Service는 트랜잭션이 적용이 안된다.
  • Bean 객체는 Servlet Context가 우선되므로 @Controller가 동작하여 같은 context(Servlet Context)안에서 검색을 하고, @Service가 지정된 bean이 있으므로 이 bean을 사용한다. 이 @Service가 지정된 bean은 트랜잭션 적용이 안 되어 있어 트랜잭션 처리가 안된다.



 

Reference

https://hoonmaro.tistory.com/31

 

 

 

728x90
728x90

1. ViewResolver 설정

 

뷰 영역 구현

컨트롤러는 최종적으로 결과를 출력할 뷰와 뷰에 전달할 객체를 담고 있는 ModelAndView 객체를 리턴한다.

DispatherServlet은 ViewResolver를 사용하여 결과를 출력할 View 객체를 구하고, 구한 View 객체를 이용하여 내용을 생성한다.

 

JSP를 뷰 기술로 사용할 경우 다음과 같이 InternalResourceViewResolver 구현체를 빈으로 등록해주면 된다.

 

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="WEB-INF/view"/>
<property name="suffix" value=".jsp/>
// 이는 ViewResolver가 "WEB-INF/view/뷰이름.jsp"를 뷰 JSP로 사용한다는 것을 의미한다. 
// 즉, 앞의 예에서 HelloController는 뷰 이름으로 "hello"를 리턴하므로, 
// 실제로 사용되는 뷰 파일은 "WEB-INF/view/hello.jsp"파일이 된다.
</bean>

InternalResourceViewResolver는 컨트롤러가 지정한 뷰 이름으로부터 실제로 사용될 뷰를 선택하는데, 이 때 컨트롤러가 지정한 뷰 이름 앞뒤로 prefix 프로퍼티와 suffix 프로퍼티를 추가한 값이 실제로 사용될 자원의 경로가 된다.



 

2. ViewResolver 구현 클래스

스프링 컨트롤러는 뷰에 의존적이지 않다. 컨트롤러는 아래 코드와 같이 결과를 생성할 뷰의 이름만 지정할 뿐이다.

컨트롤러가 지정한 뷰 이름으로부터 응답 결과 화면을 생성하는 View 객체는 ViewResolver가 구한다.

스프링은 몇 가지 ViewResolver 구현 클래스를 제공하고 있는데, 이중 주료 ViewResolver 구현 클래스는 다음과 같다.

 


3. ContentNegotiatingViewResolver 이해하기

 

ContentNegotiatingViewResolver 는 View 를 찾기위해 요청 URL의 확장자와 AcceptHeader를 사용하는 ViewResolver 입니다.

자체적으로 View 를 찾지는 않으며 viewResolvers 에 설정된 ViewResolver 를 사용하여 View 를 찾습니다.

 

ContentNegotiatingViewResolver의 기본적인 설정방법은 아래와 같습니다.

 

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">

<!-- 확장자와 contentType 을 연결해 준다. -->

<property name="mediaTypes">

<map>

  <entry key="atom" value="application/atom+xml"/>

  <entry key="html" value="text/html"/>

  <entry key="json" value="application/json"/>

</map>

</property>

<property name="viewResolvers">

<list>

  <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>

  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

<property name="prefix" value="/WEB-INF/jsp/"/>

<property name="suffix" value=".jsp"/>

  </bean>

</list>

</property>

<!-- 위의 viewResolvers 에 의해 view를 얻지 못했을 경우에 사용되는 view -->

<property name="defaultViews">

<list>

  <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />

</list>

</property>

<property name="defaultContentType" value="application/json" />

</bean>

 

mediaType 은 URL 의 확장자와 contentType 을 연결해주는 일종의 맵입니다.

http://localhost/user.html 이 들어왔을 경우에는 URL 의 확장자인 html 에 연결된 text/html (ContentType) 을 처리하는 View 를 찾게되고 

http://localhost/user.json 이 요청되었을 경우에는 위와 마찬가지로 URL의 확장자인 json 과 연결된 application/json (ContentType) 을 처리하는 View 를 찾습니다.

 

viewResolvers ContentNegotiatingViewResolver 가 View 를 찾기위해 사용하는 ViewResolver 들

 

defaultViews 는 viewResolvers 에 의해 view 를 찾지 못했을 경우에 사용되는 view 입니다.

 

 

json 이 MappingJacksonJsonView 와 연결되는 방법

 

org.springframework.web.servlet.View

org.springframework.web.servlet.AbstractView

org.springframework.web.servlet.view.json.MappingJacksonJsonView

 

MappingJacksonJsonView 상속 관계를 보면 최상위에 org.springframework.web.servlet.View 인터페이스가 있습니다.

org.springframework.web.servlet.View 인터페이스 내에는 해당 View 가 처리할 수 있는 ContextType 를 정의해야 하는 getContentType() 메소드가 있는데 여기서 리턴되는 값을 통해서 해당 View 가 처리해야할 ContentType 을 정의하고 있습니다.

 

MappingJacksonJsonView 에서 직접적으로 getContentType() 메소드를 구현하지 않는데 구현은 AbstractView 에 이미 들어가 있습니다.

AbstractView 소스를 들여다보면 setContextType( String contextType), getContextType() 메소드가 존재합니다.

따라서 MappingJacksonJsonView 에서는 

setContentType( "application/json"); 메소드로 해당 View 에서 처리해야할 ContextType을 정의하게 됩니다.

 

 

4. @ResponseBody

@ResponseBodysms @RequestBody와 비슷한 방식으로 동작함

@ResponseBody가 메서드 레벨에 부여되면, 메서드가 리턴하는 객체는 바로 HTTP 응답의 메시지 본문으로 전환됨. (뷰를 통해 결과를 만들어내는 모델로 사용되지 않음)

 

@RequestMapping("/hello")
@ResponseBody
public String hello(){
	return "<html><body>Hello Spring</body></html>";
}

 

만약 메서드에 @ResponseBody가 없다면, 스트링 타입의 리턴값은 뷰이름으로 인식 될것.

하지만 @ResponseBody가 붙었으므로, HttpServletResponse의 출력 스트림에 넣어 버림.

 

 

 


Reference

https://devbox.tistory.com/entry/Spring-ViewResolver-설정

https://ismydream.tistory.com/139

https://m.blog.naver.com/todoskr/220856216311

728x90

+ Recent posts