728x90

자바클래스로 Spring 기본 설정할 때 사용된다.

 

-web.xml을 대신할 클래스로 톰캣 실행시 기본설정하는 역할을 한다.

 

WebAppInitConfig 클래스는 WebApplicationInitializer 인터페이스를 상속하여 

onStartup 메소드를 구현한다. 

 

onStartup 메소드는 톰캣 실행하자마자 실행되므로 설정의 역할을 하게 된다. 

이 메소드에서 dispatcherServlet도 등록하고 ApplicationConfig, Listener, WebConfig, encodingFilter도 설정할 수 있다. 

 

Spring에서 application.properties 파일로 설정을 하면 불필요한 액션인것 같다.

 

public class WebAppInitConf implements WebApplicationInitializer {

@Override

public void onStartup(ServletContext servletContext) throws ServletException {

/**********1.DispatcherServlet등록***************/

AnnotationConfigWebApplicationContext context =

new AnnotationConfigWebApplicationContext();

context.register(WebConfig.class);

ServletRegistration.Dynamic dynamic=

servletContext.addServlet("dispatcherSevlet", new DispatcherServlet(context));

dynamic.setLoadOnStartup(0);

dynamic.addMapping("/");

 

/********2.config 설정 클래스[ApplicationConfig.java,WebConfig.java]를사용한설정******/

//ApplicationConfig.java

AnnotationConfigWebApplicationContext applicationContext =

new AnnotationConfigWebApplicationContext();

applicationContext.register(ApplicationConfig.class);

//Listener등록

servletContext.addListener(new ContextLoaderListener(applicationContext));

//WebConfig.java

AnnotationConfigWebApplicationContext servletConfig = new AnnotationConfigWebApplicationContext();

servletConfig.register(WebConfig.class);

ServletRegistration.Dynamic dispatcherServlet = servletContext.addServlet("dispatcherServlet", new DispatcherServlet(servletConfig));

dispatcherServlet.setLoadOnStartup(1);

dispatcherServlet.addMapping("/");

//encodingFilter설정

FilterRegistration.Dynamic filterRegistration = servletContext.addFilter("encodingFilter", new CharacterEncodingFilter("UTF-8", true));

filterRegistration.addMappingForUrlPatterns(null, true, "/*");

}

}

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

Spring Boot Controller Type of Parameters  (0) 2023.09.13
Spring Boot DataSource 설정  (0) 2023.09.13
Spring Boot Request Controller  (0) 2023.09.13
Spring JSP 국제화  (0) 2023.09.13
Spring Boot Controller Mapping + View Resolver  (0) 2023.09.12
728x90

RequestMapping

@Controller

@RequestMapping("/user")

public class RequestMappingUserController {

@RequestMapping("/list")

public String user_list() {

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

}

 

@RequestMapping("/view")

public String user_view() {

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

}

 

}

RequestMapping은  Get방식과 Post방식 관계없이 들어오는 모든 요청을 받는다.

 

기본적으로 맵핑은 

메소드 위에 Annotation을 붙여 한다. 

 

하지만, 위의 코드는 클래스 레벨에 RequestMapping하여 패키지 단위를 맵핑하였다. 

예를들어 

/user_list

/user_view

/guest_list

/guest_view

가 있다면 

/list와 /view는 /user와 /guest를 반복하므로 

user와 guest를 한번더 폴더링하여 

/user/list

/user/view

/guest/list

/guest/view

로 맵핑하는게 더 관리하기 좋을 수 있다.

 

Get, Post Mapping

@Controller

public class RequestMappingController {

@GetMapping("/login")

public String get_form() {

 

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

}

@PostMapping("/login")

public String post_login_action(@RequestParam(name="id") String id,@RequestParam(name="password") String password, HttpSession session) {

System.out.println("id param"+id);

System.out.println("password param"+password);

boolean isLogin= true;

if(isLogin) {

session.setAttribute("sUserId", id);

}else {

 

}

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

}

}

 

@GetMapping("/login")

public String get_login_form() {

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

}

GetMapping("/login")

Get방식으로 /login에 들어오면 get_login_from()이 실행되고 get_login_form.jsp 반환 

get_login_form 에서는 아이디와 패스워드를 입력받고 

Post방식으로 /login으로 다시 보낸다.

 

@PostMapping("/login")

public String post_login_action(@RequestParam(name="id") String id, @RequestParam(name="password") String password,HttpSession session) {

 

session.setAttribute("userId", id);

 

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

}

PostMapping("/login")

위와 같은 /login으로 들어오더라도 Post방식으로 들어오면 post_login_action()이 실행된다. 

같은 uri를 맵핑하더라도 메소드 이름은 달라야한다.

@RequestParam(name="id") String id 

파라메터 식별자를 request 의 속성 key와 일치시키면 웬만하면 Spring이 파라메터를 잘 binding하지 

그렇지 않은 경우 @RequestParam으로 명시할 수 있다.

 

위 메소드에선 session도 받아와 userId를 session의 속성에 추가하고 post_login_result.jsp로 forwarding했다.

 

@PostMapping("/user_join_form")

public String model_attribute_user_write_action(@ModelAttribute(name="user") User user) {

User user =new UserService().joinUser(user);

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

}

request에 userId, password, name이 등록되어있다면

@ModelAttribute 어노테이션으로 User user 객체를 바로 가져올 수 있다. 

 

스프링은 내부적으로 

requestParam에 userId와 password, name을 가져와서 

 User user = new User();

user Setter() 메소드로 user에 데이터를 담아 

user객체를 request.setAttribute("user",user); 로 담아 준다. 

 

model_attribute_user_write_action()메소드 내부에서 

user 객체를 사용하면 된다. 

 

*request는 forwarding 할 때 동일 request를 그대로 가져가기 때문에 

파라메타로 받은 user는 다음 액션이 forward 이라면 request나 model에서  "user"라는 키로 그대로 다시 꺼내올 수도 있다. 

 

++model.addAttribute() 하면 request에도 자동으로 .setAttribute() 된다. 

 

@PostMapping("/guest_write_action")

public String guest_write_action(@ModelAttribute Guest guest,RedirectAttributes redirectAttributes) throws Exception {

int guest_no=guestService.insertGuest(guest);

redirectAttributes.addAttribute("guest_no",guest_no);

return "redirect:guest_view";

}

RedirectAttributes 

redirect 할 때 가지고 갈 파라메터가 필요할 때 사용할 수 있다. 

redirectAttributes객체에 addAttribute 메서드를 사용해 guest_no를 넘겨주었다. 

redirect할 guest_view는 guest_no를 받을 수 있다. 

 

// parameter에 guest_no가 존재하지 않으면

@GetMapping(value = "/guest_view", params = "!guest_no")

public String guest_view() throws Exception {

 

return "redirect:guest_main";

}

//parameter에 guest_no가 존재하면

@GetMapping(value="/guest_view", params="guest_no")

public String guest_view(@RequestParam int guest_no, Model model) throws Exception {

Guest guest = guestService.selectByNo(guest_no);

if(guest==null) {

model.addAttribute("GUEST_NOT_FOUND_MSG","게시물이 존재하지 않습니다.");

return "guest_view_not_found";

}

model.addAttribute("guest",guest);

return "guest_view";

}

 

guest_view로 넘어올때 guest_no가 필요하기 때문에 

guest_no가 있는 경우와 없는 경우를 나누어 맵핑해준다. 

 

이전까진 @GetMapping("/guest_view") 로 value값만 넣어줘서 value=를 명시하지 않았지만 

params 속성도 넣어야 하기 때문에 value=를 명시해준다. 

params Get방식으로 넘어 올때 필요한 param들을 지정해주는데 

!연산자를 이용해 존재하지 않는 경우와  존재하는 경우를  표현할 수 있다.

 

 

@GetMapping(value={"/user_write_action","/user_login_action",

"/user_logout_action","/user_modify_form",

"/user_modify_action","/user_remove_action"})

public String get_mapping() {

return "redirect:user_main";

}

매핑할때 value=은 배열로 받기 때문에 값을 여러개 줄 수 있다. 

->PostMapping하고 GetMapping을 막을 때 GetMapping으로 들어오는 요청들을 다 main페이지로 redirection시켰다.

 

 

 

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

Spring Boot DataSource 설정  (0) 2023.09.13
Java WebAppInitConfig  (0) 2023.09.13
Spring JSP 국제화  (0) 2023.09.13
Spring Boot Controller Mapping + View Resolver  (0) 2023.09.12
Spring Boot Exception Handler  (0) 2023.09.12
728x90

- 국제화 텍스트 properties 파일을 resources에 생성한다. 

 

 

messages.properties 파일

 

++ResourceBundle Editor

http://essiembre.github.io/eclipse-rbe/

 

messages_en.properties 파일 

jsp파일을 parsing 하다 fmt 태그에서 key값을 발견하면 value값을 꺼내 반환해준다.

 

- ApplicationConfig에 MessageSource Bean을 설정한다.

@Bean("messageSource")

public MessageSource messageSource() {

ResourceBundleMessageSource resourceBundleMessageSource=

new ResourceBundleMessageSource();

resourceBundleMessageSource.setBasenames("messages/messages","messages/user");

return resourceBundleMessageSource;

}

messageSource()메소드는 

resourceBundleMessageSource를 생성하고 Basenames에 messages(route)/messages(.properties 기술하지 않음) 을 setting 해준다. 위 코드에서는 messages 뿐만 아니라 user도 ','로 구분하여 함께 등록했다.

그 후 resourceBundleMessageSource를 반환해준다.

 

 

 

 

JSTL 태그

<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<%

request.setAttribute("id", "아이디");

request.setAttribute("pass", "비밀번호");

request.setAttribute("name", "이");

%>

<%-- 1.Locale객체설정(JSTL)--%>

<fmt:setLocale value="${pageContext.request.locale.language}"/>

<%-- 2.ResourceBundle 의 properties파일지정(JSTL) 페이지전역 --%>

<fmt:setBundle basename="messages/messages"/>

 

<fmt:message key="password.mismatch.exception">

<fmt:param value="${id}"/>

<fmt:param value="${pass}"/>

<fmt:param value="${name}"/>

</fmt:message>

JSTL 태그는 JSP에서 사용하는 국제화 태그이다. 

<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

taglib directive로 태그 라이브러리를 import 해주면 prefix로 태그를 사용할 수 있다.

<%-- 1.Locale객체설정(JSTL)--%>

<fmt:setLocale value="${pageContext.request.locale.language}"/>

locale(지역)을 fmt:setLocale 태그로 설정해준다.

<%-- 2.ResourceBundle 의 properties파일지정(JSTL) 페이지전역 --%>

<fmt:setBundle basename="messages/messages"/>

resourceBundle의 basename을 지정해준다.

password.mismatch.exception = {0} {1} {2} 사용자의 비밀번호가 일치하지 않습니다.

messages.properties에 password.mismatch.exception은 

파라메터 3개를 받아서 텍스트를 뿌린다.

 

<fmt:message key="password.mismatch.exception">

<fmt:param value="${id}"/>

<fmt:param value="${pass}"/>

<fmt:param value="${name}"/>

</fmt:message>

파라메터가 필요없다면 

<fmt:param>태그는 필요없다.

 

 

 

 

다음은 Spring에서 제공하는 국제화 태그이다.

<%@ taglib prefix="s" uri="http://www.springframework.org/tags" %>

 

<s:message

code="exception.userexisted"

arguments="${id}" />

s:message 태그에

code="KEY"

파라메타를 받는다면 

arguments="param"

<s:message code="nv.bc"

arguments="user,list"

argumentSeparator=","/>

파라메타가 여러개면

arguments에 파라메타를 구분자와 함께 기술하고

argumentSeparator에 구분자를 지정해준다.

Spring Container에 등록된 MessageSource 빈객체를 @를 이용해서 JSP에서직접호출

<s:eval expression="@messageSource.getMessage('nv.bc',new Object[]{'유저','리스트'},new java.util.Locale('en','US'))"/>

messageSource.getMessage('key',['param','param'],locale('language','locale'))

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

Java WebAppInitConfig  (0) 2023.09.13
Spring Boot Request Controller  (0) 2023.09.13
Spring Boot Controller Mapping + View Resolver  (0) 2023.09.12
Spring Boot Exception Handler  (0) 2023.09.12
Spring Boot  (0) 2023.09.12
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