728x90

@Controller

public class HelloAnnotationMultiRequestMappingController {

@RequestMapping("/hello3")

public String hello3() {

return "forward:/WEB-INF/views/hello3.jsp";

}

 

/*************redirect**********************/

@RequestMapping("/hello_redirect_servlet")

public String hello_redirect_servlet() {

return "redirect:hello_redirected_servlet";

}

}

기본적으로 Controller는 Dispatcher로 redirect 또는 forward path를 String으로 반환한다.

forward:forwardPath

redirect:redirectPath

forwardPath는 contextPath를 붙여주어야한다. /WEB-INF/views/ 

redirectPath는 mapping된 uri만 있으면 된다. 

 

forwarding 하는 경우에도 다른 controller로 다시 forward 시킬 경우 redirect와 마찬가지로 mapping된 uri만 반환하면 된다.

/*************forward********************/

@RequestMapping("/hello_servlet_forward")

public String hello_servlet_forward() {

return "forward:hello_servlet_forwarded";

}

@RequestMapping("/hello_servlet_forwarded")

public String hello_servlet_forwarded() {

return "forward:/WEB-INF/views/hello_servlet_forwarded.jsp";

}

 

Spring에서는 forwarding 할 때 데이터를 뷰로 전달할 객체를 제공해준다. 

- model, modelMap, modelAndView, map, request, session...

 

map은 자바에서 제공하는 Map Interface로 직접적으로 뷰로 데이터를 제공하기 위해 사용된다. 

web에서 사용하던 request와 session도 사용할 수 있다. 

 

model과 modelMap은 Map처럼 데이터를 설정하고 뷰에서 사용할 수 있게 해준다.

 

사용방법은 모두 비슷하다.

@RequestMapping("/model_all")

public String model_all(HttpServletRequest request,Model model,Map map,ModelMap modelMap){

request.setAttribute("req","리퀘스트데이타");

model.addAttribute("model", "모델데이타");

map.put("map", "맵데이타");

modelMap.addAttribute("modelmap", "모델맵데이타");

return "forward:/WEB-INF/views/spring_model.jsp";

}

set 또는 addAttribute 메소드를 사용하여 속성에 key와 value를 넣고 view에서 사용하면 된다. 

 

modelAndView 객체가 특이한데 

@RequestMapping("/model_modelandview")

public ModelAndView modelandview() {

ModelAndView modelAndView=new ModelAndView();

 

modelAndView.setViewName("forward:/WEB-INF/views/spring_model.jsp");

modelAndView.addObject("modelandview","모델앤드뷰데이타" );

return modelAndView;

}

 modelAndView는 반환할 forwardPath와 데이터를 함께 저장한다. 

그래서 다른 Controller처럼 String forwardPath를 반환하는 것이 아니라 ModelAndView객체를 반환한다. 

 

지금까지는 forwardPath를 반환하여 view Resolver로  View를 찾아 응답하는 방식을 보았다. 

 

 

++

View 응답하는 방식

1. Controller가 DispatcherServlet에 String을 반환하면 View 객체를 얻기 위해 ViewResolver객체를 찾는다.

설정된 view Resolver가 없다면 default resolver인 InternalResourceViewResolver객체를 생성한 후 

viewName을 url로 설정한 후 InternalResourceViewResolver객체의 renderMergedOutputModel()메소드를 호출하고 url로 forwarding 또는 redirect한다.

@RequestMapping("response_forward_view_name")

public String response_forward_view_name() {

return "forward:/WEB-INF/views/response_forward_view_name.jsp";

}

 

2. Controller가 DispatcherServlet에 setUrl로 url을 가진 View객체를 반환하면 반환받은 View객체의 renderMergedOutputModel()메소드를 호출하고 url로 forwarding 또는 redirect한다.

XmlView를 반환한 경우 renderMergedOutputModel()메소드가 xml을 출력한다.

 

@RequestMapping("/response_forward_view_object")

public View response_forward_view_object() {

InternalResourceView internalResourceView=new InternalResourceView();

internalResourceView.setUrl("/WEB-INF/views/response_forward_view_object.jsp");

return internalResourceView;

}

View객체를 등록하는 법

@Component("xmlView")

public class XMLView extends AbstractView {

@Override

protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,

HttpServletResponse response) throws Exception {

List<String> friendList = (List<String>) model.get("friendList");

response.setContentType("text/xml;charset=UTF-8");

PrintWriter out=response.getWriter();

out.println("<?xml version='1.0' encoding='UTF-8'?>");

out.println("<friends>");

for(String friend:friendList) {

out.println("<friend>");

out.println(friend);

out.println("</friend>");

}

out.println("</friends>");

}

}

1.@Component("ViewName")

AbstractView를 상속받은 View클래스를 만들고

PrintWriter를 이용해서 출력할 텍스트를 입력하는 renderMergedOutputModel메소드를 재정의한다.

 

2.WebMvcConfigurer Interface를 구현한 WebConfig 클래스를 만든다.

addViewControllers메소드와 configureViewResolvers메소드를 구현한다.

@Configuration

public class WebConfig implements WebMvcConfigurer{

/********************WebMvcConfigurer재정의*********************/

@Override

public void addViewControllers(ViewControllerRegistry registry) {

registry.addViewController("/").setViewName("forward:/index.jsp");

}

 

@Override

public void configureViewResolvers(ViewResolverRegistry registry) {

registry.jsp("/WEB-INF/views/",".jsp");

}

ViewResolver객체가 필요하다면 WebConfig에 Bean객체를 등록한다.

@Bean

public BeanNameViewResolver beanNameViewResolver() {

BeanNameViewResolver beanNameViewResolver=new BeanNameViewResolver();

beanNameViewResolver.setOrder(0);

return beanNameViewResolver;

}

 

텍스트를 직접 응답하는 방법

@ResponseBody

@GetMapping(value = "/response_string", produces = {"text/plain;charset=UTF-8"})

public String response_string() {

return "hello string for javascipt ajax request[한글]";

}

 

@ResponseBody

@GetMapping(value = "/response_html", produces="text/html;charset=UTF-8")

public String response_html() {

return "<h3>hello string for javascript ajax request[한글]</h3><hr>";

}

 

@ResponseBody

@RequestMapping(value="/response_xml" ,produces="text/xml;charset=UTF-8")

public Guest response_xml() {

Guest guest =Guest.builder().guest_no(1).guest_name("name").guest_title("title").guest_content("content").guest_homepage("homepage").build();

return guest;

}

@ResponseBody

@GetMapping(value="/response_json",produces = "application/json;charset=UTF-8")

public Guest response_json() {

Guest guest=Guest.builder().guest_name("name").guest_no(2).guest_content("cont").build();

return guest;

}

@ResponseBody 어노테이션을 붙이고 

@RequestMapping도 기존 URI value에 추가로 produces 속성도 지정해준다. 

 

++ Controller 내에 모두 @ResponseBody이 붙는다면 

@Controller 대신 @RestController를 사용하면 @ResponseBody를 붙이지 않아도 된다.

 

- produces API

Narrows the primary mapping by media types that can be produced by the mapped handler. Consists of one or more media types one of which must be chosen via content negotiation against the "acceptable" media types of the request. Typically those are extracted from the "Accept" header but may be derived from query parameters, or other. Examples:

 produces = "text/plain"
 produces = {"text/plain", "application/*"}
 produces = MediaType.TEXT_PLAIN_VALUE
 produces = "text/plain;charset=UTF-8"
 

If a declared media type contains a parameter (e.g. "charset=UTF-8", "type=feed", "type=entry") and if a compatible media type from the request has that parameter too, then the parameter values must match. Otherwise, if the media type from the request does not contain the parameter, it is assumed the client accepts any value.

Expressions can be negated by using the "!" operator, as in "!text/plain", which matches all requests with a Accept other than "text/plain".

 

produces에 type과 charset을 입력해준다.

 

url이나 jsp, html 등 파일 주소를 반환하는 것이 아니라 출력할 텍스트나 데이터를 반환한다. 

 

text : text/plain;

html: text/html;

xml: text/xml;

json: application/json;

 

xml과 json 형식은 데이터를 전송하고 표현하기 위한 포맷으로 

데이터를 반환해준다. 

 

요즘은 거의 json 방식으로 데이터를 보낸다.

'Java > Spring Boot' 카테고리의 다른 글

Spring Boot Request Controller  (0) 2023.09.13
Spring JSP 국제화  (0) 2023.09.13
Spring Boot Exception Handler  (0) 2023.09.12
Spring Boot  (0) 2023.09.12
Spring Boot에서 JSP 사용하기  (0) 2023.09.12

+ Recent posts