Spring WebMVC: 

페이지 컨트롤러 만들기 II


───────
Spring webMVC: Request Handler의 리턴값 다루기


/* Spring webMVC: Request Handler의 리턴값 다루기
 */   
package control;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller  
@RequestMapping("/control/controller15/")
public class Controller15 {
  
  // 1) void: 요청 핸들러에서 직접 출력하기
  @RequestMapping("ok1")
  public void ok1(HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("ok1(): 안녕하세요!"); 
  }

  // 2) String: 리턴 값을 클라이언트로 출력하기
  @RequestMapping(path="ok2", produces="text/plain;charset=UTF-8")
  @ResponseBody
  public String ok2(HttpServletResponse response) throws Exception {
    return "ok2(): 안녕하세요!"; 
  }

  // 3) String: 리턴 값을 클라이언트로 출력하기 - error
  @RequestMapping(path="ok3")
  @ResponseBody // <=== 리턴 값이 응답 데이터임을 표시하는 애노테이션
                // 리턴 값을 바로 출력할 때는 @RequestMapping의 produces 속성을 이용하여
                // 출력 내용의 타입과 인코딩을 지정한다.
  public String ok3(HttpServletResponse response) throws Exception {
    //@ResponseBody를 사용하여 리턴 값을 바로 클라이언트로 출력할 때는
    // 다음과 같이 UTF-8 처리를 지정할 수 없다.
    // 해결책? 위의 ok2() 메서드에서처럼 @RequestMapping의 produces 속성으로 지정해야 한다.
    response.setContentType("type/plain;charset=UTF-8");
    return "ok3(): 안녕하세요!"; 
  }

  // 4) String: JSP로 포워딩하기
  //    => @ResponseBody가 붙지 않으면 리턴 값을 JSP URL로 취급한다.
  @RequestMapping(path="ok4")
  public String ok4() throws Exception {
    return "/controller15_ok4.jsp"; 
  }
}



application-context.xml 파일에 다음과 같은 bean 객체를 등록해줍니다.


<!-- 페이지 컨트롤러가 JSP URL을 리턴할 때, 해당 JSP를 찾아 실행하는 객체 -->
    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    <property name="prefix" value="/"/>
    <property name="suffix" value=".jsp"/>
    </bean>


이렇게 JSP를 실행할 객체를 명시적으로 등록하게 되면 페이지 

컨트롤러에서 JSP URL을 리턴할 때 이 설정을 고려하게 됩니다.


그러나 String을 리턴 값으로 설정해주고 JSP로 포워딩 해준 4번 예제의 

코드를 바꿔야 합니다. 이유는 다음의 주석을 참고해주세요. 

* Controller15의 ok4() 메서드를 다음과 같이 정의해야 합니다.


@RequestMapping(path="ok4")
  public String ok4() throws Exception {

// return "/controller15_ok4.jsp"; // InternalResourceViewResolver를 설정하기 전에는 괜찮다. // InternalResourceViewResolver를 설정한 후에는 오류가 발생한다. // why? 리턴 값 앞 뒤에 문자열이 붙기 때문이다. // "/" + "controller15_ok4.jsp" + ".jsp" // 그래서 최종 url은 "/controller15_ok4.jsp.jsp"가 된다. return "controller15_ok4"; // 이렇게 InternalResourceViewResolver의 설정을 고려하여 리턴 값을 작성해야 한다. }


webapp 폴더 안에 controller15_ok4.jsp 파일을 만들고 다음처럼 작성합니다.


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta charest="UTF-8">
<title>test</title>
</head>
<body>
<h1>contoller_ok4()</h1>
</body>
</html>


실행 방법 :

http:localhost:8080/spring-web01/control/controller15/ok4.do




───────

클라이언트로 리턴 값을 출력하지도 않고, JSP URL로도 지정하지 않을 때

 앞서 application-context.xml 파일에 jspViewResolver bean 객체를 등록

    해주었기에 다음과 같은 예제를 추가해주고 실행해보면 정상적으로 실행

    되는 것을 알 수 있습니다.



// 5) void: 클라이언트로 리턴 값을 출력하지도 않고, JSP URL로도 지정하지 않으면 
  //    => 기본 JSP URL로 현재 URL을 사용한다.
  //    => 단 이럴 경우 스프링 설정 파일에 JSP를 어디에서 찾을 것인지 지정해야 한다.
  //       지정하지 않으면 URL이 
  @RequestMapping(path="ok5")
  public void ok5() throws Exception {
    System.out.println("ok5()");
  }


 실행 방법 :

http:localhost:8080/spring-web01/control/controller15/ok5.do





───────

JSP URL을 바구니에 담아 리턴하기


// 6) JSP URL을 바구니에 담아 리턴하기
  @RequestMapping(path="ok6")
  public ModelAndView ok6() throws Exception {
    ModelAndView mv = new ModelAndView();
    mv.setViewName("controller15_ok6");
    return mv;
  }


기존 예제에 위 코드를 추가하고 webapp 폴더 안에 controller15_ok6.jsp 파일을 만듭니다. 만든 파일에는 아래와 같이 작성합니다.


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta charest="UTF-8"> <title>test</title> </head> <body> <h1>contoller_ok6()</h1> </body> </html>


 실행 방법 :

http:localhost:8080/spring-web01/control/controller15/ok6.do



───────

JSP URL과 JSP 사용할 데이터도 함께 ModelAndView 바구니에 담아 리턴하기


// 7) JSP URL과 JSP 사용할 데이터도 함께 ModelAndView 바구니에 담아 리턴하기
  @RequestMapping(path="ok7")
  public ModelAndView ok7() throws Exception {
    ModelAndView mv = new ModelAndView();
    mv.setViewName("controller15_ok7");
    mv.addObject("title", "제목이네요!");
    
    Member member = new Member();
    member.setName("홍길동");
    member.setAge(20);
    member.setWorking(true);
    mv.addObject("member", member);
    
    /* 이렇게 ModelAndView 바구니에 값을 담아 두면,
     * 프론트 컨트롤러는 이 바구니에 담긴 값을 꺼내
     * JSP 가 사용할 수 있도록 ServletRequest 바구니에 옮겨 싣는다.
     */


기존 예제에 위 코드를 추가하고 webapp 폴더 안에 controller15_ok7.jsp 파일을 만듭니다. 만든 파일에는 아래와 같이 작성합니다.


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta charest="UTF-8">
<title>test</title>
</head>
<body>
<h1>contoller_ok7()</h1>
${title}<br>
${member.name}<br>
${member.age}<br>
${member.working}<br>
</body>
</html>


 실행 방법 :

http:localhost:8080/spring-web01/control/controller15/ok7.do



실행 결과 :

contoller_ok7()

제목이네요!
홍길동
20
true



───────

JSP URL은 리턴 값으로,  JSP 사용할 데이터는 Model 바구니에 담아 리턴하기



// 8) JSP URL은 리턴 값으로, JSP가 사용할 데이터는 Model 바구니에 담는다.
  @RequestMapping(path="ok8")
  public String ok8(Model model) throws Exception {
    model.addAttribute("title", "제목이네요!");
    
    Member member = new Member();
    member.setName("홍길동");
    member.setAge(20);
    member.setWorking(true);
    model.addAttribute("member", member);
    
    /* 이렇게 ModelAndView 바구니에 값을 담아 두면,
     * 프론트 컨트롤러는 이 바구니에 담긴 값을 꺼내
     * JSP 가 사용할 수 있도록 ServletRequest 바구니에 옮겨 싣는다.
     */
    return "controller15_ok8";
  }


기존 예제에 위 코드를 추가하고 webapp 폴더 안에 controller15_ok8.jsp 파일을 만듭니다. 만든 파일은 아래와 같이 작성합니다.


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta charest="UTF-8">
<title>test</title>
</head>
<body>
<h1>contoller_ok8()</h1>
${title}<br>
${member.name}<br>
${member.age}<br>
${member.working}<br>
</body>
</html>


 실행 방법 :

http:localhost:8080/spring-web01/control/controller15/ok8.do



───────

Model 대신 Map 객체를 바구니로 사용해서 리턴 값을 받기


// 9) Model 대신 Map 객체를 바구니로 사용할 수 있다.
  @RequestMapping(path="ok9")
  public String ok9(Model model) throws Exception {
    model.addAttribute("title", "제목이네요!");
    
    Member member = new Member();
    member.setName("홍길동");
    member.setAge(20);
    member.setWorking(true);
    model.addAttribute("member", member);
    
    /* 이렇게 Map 바구니에 값을 담아 두면,
     * 프론트 컨트롤러는 이 바구니에 담긴 값을 꺼내
     * JSP 가 사용할 수 있도록 ServletRequest 바구니에 옮겨 싣는다.
     */
    return "controller15_ok8";
  }


기존 예제에 위 코드를 추가하고 webapp 폴더 안에 controller15_ok9.jsp 파일을 만듭니다. 만든 파일은 아래와 같이 작성합니다.



블로그 이미지

필로그래머

,

 Spring WebMVC: 

페이지 컨트롤러 만들기


Spring에서 제공하는 프론트 컨트롤러와 협업할 페이지 컨트롤러 만들기



 Spring WebMVC 프로젝트 설정 방법


1) web.xml에 Spring webmvc의 프론트 컨트롤러를 설정합니다.


<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>project01</display-name> <!-- 프론트 컨트롤러 등록 --> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:control/application-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> <!-- 클라이언트가 요청하지 않아도 init() 함수가 호출. 즉 servlet 객체가 생성한다. --> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>



2) Spring 설정 파일을 준비합니다.

/src/main/src/control/application-context.xml


<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- Spring IoC 컨테이너를 위한 객체 등록 --> <context:component-scan base-package="control"/> <!-- Spring WebMVC 관련 기능을 처리할 객체를 등록한다. (RequsetMapping 되어 있는 객체를 등록) --> <mvc:annotation-driven/> </beans>



3) Gradle 설정 파일을 준비합니다. (프로젝트 폴더 바로 아래에 위치시켜 주세요.)

    build.gradle


apply plugin: 'java' 
apply plugin: 'eclipse-wtp' 
apply plugin: 'war'       

compileJava {
  options.encoding = 'UTF-8'  
  sourceCompatibility = '1.8' 
}

repositories {
  mavenCentral() 
}

dependencies {
  compile 'org.slf4j:slf4j-api:1.7.22'
  compile group: 'commons-fileupload', name: 'commons-fileupload', version: '1.3.2'
  compile group: 'javax.servlet', name: 'jstl', version: '1.2'
  compile group: 'org.springframework', name: 'spring-webmvc', version: '4.3.9.RELEASE'
  
  providedCompile group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0'
  
  testCompile 'junit:junit:4.12'
}


4) cmd 명령창에서 해당 프로젝트 폴더로 경로를 설정한 후 "gradle eclipse" 

   명령어를 입력해 실행시킵니다.

* 이 글의 예제에서의 프로젝트 폴더는 spring-web01입니다.



 페이지 컨트롤러 만들기


1) 클래스를 페이지 컨트롤러로 표시하기

   - @Controller 애노테이션을 붙입니다.


2) 요청을 처리할 메서드를 표시하기 

    - @RequestMapping(URL) 애노테이션을 붙입니다.



/* Spring webMVC: 페이지 컨트롤러 만들기 * */ package step01; import java.io.PrintWriter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller // 페이지 컨트롤러 클래스임을 표시 public class Controller01 { @RequestMapping("/control/controller01") // 어떤 요청을 처리할지 표시 public void service(HttpServletRequest request, HttpServletResponse response) throws Exception { response.setContentType("text/plain;charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("Hello, world!"); } }



결과 : 

    웹 브라우저 url 주소에 http://localhost:8080/프로젝트명/패키지명/controller01.do 를 입력하면 

    화면에 "Hello, world!"가 출력되는 것을 확인하실 수 있습니다.





설정 파일은 남겨둔 채 Controller01 파일을 다음 Controller02 파일로

    업그레이드 시켜보겠습니다. 메소드의 이름은 꼭 service()일 필요가

    없다는 것을 알 수 있습니다. @RequestMapping에서 설정해준 경로의

    이름이 메소드 이름이 되면 됩니다.


/* Spring webMVC: 페이지 컨트롤러 만들기
 * 
 */
package control;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller  // 페이지 컨트롤러 클래스임을 표시
public class Controller02 {
  @RequestMapping("/control/controller02/a") // 어떤 요청을 처리할지 표시
  public void a(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("aaaa");
  }

  @RequestMapping("/control/controller02/b") // 어떤 요청을 처리할지 표시
  public void b(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("bbbb");
  }

  @RequestMapping("/control/controller02/c") // 어떤 요청을 처리할지 표시
  public void c(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("cccc");
  }
}



위 예제는 다음 Controller03의 예제와 똑같은 결과를 호출합니다.

    공통되는 경로가 있다면 @RequestMapping을 통해 묶어줄 수 있습니다.

     요청 URL 계산하기 = class에 붙은 URL + 메소드에 붙은 URL


/* Spring webMVC: 페이지 컨트롤러 만들기
 * 
 */
package control;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller  // 페이지 컨트롤러 클래스임을 표시
@RequestMapping("/control/controller03/")
public class Controller03 {
  @RequestMapping("a") // 어떤 요청을 처리할지 표시
  public void a(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("aaaa");
  }

  @RequestMapping("b") // 어떤 요청을 처리할지 표시
  public void b(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("bbbb");
  }

  @RequestMapping("c") // 어떤 요청을 처리할지 표시
  public void c(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("cccc");
  }
}


▶ 호출될 메서드가 한 개일 경우에는 첫번째 @RequestMapping의 경로만

    설정해줘도 웹 브라우저에서 처리해줄 수 있습니다.

    요청 URL 계산하기 = class에 붙은 URL + 메소드에 붙은 URL


/* Spring webMVC: 한 페이지 컨트롤러에서 요청 처리하기
 * 
 */
package control;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller  // 페이지 컨트롤러 클래스임을 표시
@RequestMapping("/control/controller04/ok")
public class Controller04 {
  @RequestMapping // 어떤 요청을 처리할지 표시
  public void a(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("aaaa");
  }
}




요청 http method 구분하여 처리하기 I


/* Spring webMVC: 요청 http method 구분하여 처리하기
 * 
 */
package control;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller  // 페이지 컨트롤러 클래스임을 표시
@RequestMapping("/control/controller05/ok")
public class Controller05 {
 
  @RequestMapping(method=RequestMethod.GET)
  public void get(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("get");
  }

  @RequestMapping(method=RequestMethod.POST)
  public void post(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("post");
  }
}



GET 요청과 POST 요청을 가능하게 해주는 html 코드 I

*참고 : .html 같은 정적파일은 webapp 폴더 아래에 생성해줘야 합니다.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="control/controller05/ok.do" method="GET">
    <button>GET 요청</button>
</form>
<hr>
<form action="control/controller05/ok.do" method="POST">
    <button>POST 요청</button>
</form>
</body>
</html>


▶ 실행 방법 : http://localhost:8080/spring-web01/controller05.html
GET 요청 버튼을 클릭하면 화면에 get 문장이 출력되고 
POST 요청 버튼을 클릭하면 화면에 post 문장이 출력됩니다.



요청 http method 구분하여 처리하기 II


/* Spring webMVC: 요청 http method 구분하여 처리하기
 * 
 */
package control;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller  // 페이지 컨트롤러 클래스임을 표시
@RequestMapping("/control/controller06/")
public class Controller06 {
 
  //@RequestMapping(value="ok", method=RequestMethod.GET) // 이렇게 해도 되고
  @RequestMapping(path="ok", method=RequestMethod.GET) // 이렇게 해도 된다.
  public void get(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("get");
  }

  //@RequestMapping(value="ok", method=RequestMethod.POST) // 이렇게 해도 되고
  @RequestMapping(path="ok", method=RequestMethod.POST)
  public void post(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("post");
  }
}


GET 요청과 POST 요청을 가능하게 해주는 html 코드 II


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="control/controller06/ok.do" method="GET">
    <button>GET 요청</button>
</form>
<hr>
<form action="control/controller06/ok.do" method="POST">
    <button>POST 요청</button>
</form>
</body>
</html>




요청 URL에 주는 파라미터에 따라 호출 메서드 제한하기

- 파라미터의 존재 유무로 요청을 구분합니다.


/* Spring webMVC: 요청 URL에 주는 파라미터에 따라 호출 메서드 제한하기
 * 
 */
package control;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller  
@RequestMapping("/control/controller07/")
public class Controller07 {
 
  @RequestMapping(path="ok", params={"name"}) 
  public void get(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("name 있어요!");
  }

  @RequestMapping(path="ok", params={"age", "tel"})
  public void post(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("age와 tel 있어요!");
  }
}


@RequestMapping의 params 속성에 지정한 값과 일치하는 요청 

파라미터가 있을 경우에 호출됩니다.


▶ 실행 방법: 

http://localhost8080:/spring-web01/control/controller07/ok.do?&age=20&tel=111



HTTP 요청 프로토콜에 지정한 이름의 헤더가 있을 경우에 호출됩니다.


/* Spring webMVC: 요청 프로토콜의 헤더 이름을 요청 조건으로 지정
 * => HTTP 요청 프로토콜에 지정한 이름의 헤더가 있을 경우에 호출된다.
 * 
 */
package control;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller  
@RequestMapping("/control/controller08/")
public class Controller08 {
 
  @RequestMapping(path="ok", headers="aaaa") 
  public void get(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("aaaa 있어요!");
  }

  @RequestMapping(path="ok", headers={"bbbb", "cccc"})
  public void post(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("bbbb, cccc 있어요!");
  }
}



AJAX 요청을 통해 헤더 값을 넘겨주는 코드 

* 참고 : 그냥 html을 통해선 헤더 값을 넘겨줄 수 없어요.


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<button id="btn1">"aaaa" 헤더 요청</button>
<button id="btn2">"bbbb", "cccc" 헤더 요청</button>
<div>
<textarea id="ta" cols="80" rows="8"></textarea>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$("#btn1").click(function() {
    $.ajax("control/controller08/ok.do", {
        method: "get",
        headers: {"aaaa":"hello"},
        dataType: "text"})
        .done(function(result) {
            $("#ta").val(result)
        })
        .fail(function(xhr, status, error) {
            $("#ta").val(xhr.responseText)
        })
})
$("#btn2").click(function() {
    $.ajax("control/controller08/ok.do", {
        method: "get",
        headers: {"bbbb":"hello", 
                   "cccc":"hello"}, // 한글은 헤더로 넘겨줄 수 없습니다.
        dataType: "text"})
        .done(function(result) {
            $("#ta").val(result)
        })
        .fail(function(xhr, status, error) {
            $("#ta").val(xhr.responseText)
        })
})
</script>
</body>
</html>


▶ 실행 방법: 

http://localhost8080:/spring-web01/controller08.html




요청 프로토콜의 Accept 헤더의 값에 따라 호출될 메서드 결정


/* Spring webMVC: 요청 프로토콜의 Accept 헤더의 값에 따라 호출될 메서드 결정
 * 
 */
package control;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller  
@RequestMapping("/control/controller09/")
public class Controller09 {
  
  @RequestMapping(path="ok", produces="text/plain") 
  public void get(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("text/plain 보냄!");
  }

  @RequestMapping(path="ok", produces="application/json")
  public void post(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("application/json 보냄!");
  }
}


▶ Accept 요청 헤더

     - 웹 브라우저가 웹 서버에게 요구하는 콘텐트의 타입을 가리킵니다.


produces란?
    - 이 메서드를 생산하는 콘텐트의 타입을 가리킵니다.


Accept 헤더의 값에 따라 호출될 메서드를 결정하는 html 코드


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<button id="btn1">"text/plain" 콘텐트 요청</button>
<button id="btn2">"application/json" 콘텐트 요청</button>
<div>
<textarea id="ta" cols="80" rows="8"></textarea>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$("#btn1").click(function() {
    $.ajax("control/controller09/ok.do", {
        method: "get",
        headers: {"Accept":"text/plain"},
        dataType: "text"})
        .done(function(result) {
            $("#ta").val(result)
        })
        .fail(function(xhr, status, error) {
            $("#ta").val(xhr.responseText)
        })
})
$("#btn2").click(function() {
    $.ajax("control/controller09/ok.do", {
        method: "get",
        headers: {"Accept":"application/json"},
        dataType: "json"})
        .done(function(result) {
            $("#ta").val(result)
        })
        .fail(function(xhr, status, error) {
            $("#ta").val(xhr.responseText)
        })
})
</script>
</body>
</html>



▶ 실행 방법: 

http://localhost8080:/spring-web01/controller09.html



요청 프로토콜의 Content-Type 헤더 값에 따라 호출될 메서드를 결정하기


/* Spring webMVC: 요청 프로토콜의 Content-Type 헤더 값에 따라 호출될 메서드 결정
 * => Content-Type 요청 헤더?
 *    - 웹 브라우저가 웹 서버에게 보내는 데이터의 형식을 의미한다.
 */   
package control;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller  
@RequestMapping("/control/controller10/")
public class Controller10 {
  
  @RequestMapping(path="ok", consumes="text/plain") 
  public void get(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("text/plain 데이터를 받아서 처리했음!");
  }

  @RequestMapping(path="ok", consumes="application/json")
  public void post(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("application/json 데이터를 받아서 처리했음!");
  }
}

cosumes 란?

    - 클라이언트가 보낸 데이터의 형식 중에서 이 메서드가 처리할 수 있는

      형식을지정



<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<button id="btn1">"text/plain" 콘텐트 요청</button>
<button id="btn2">"application/json" 콘텐트 요청</button>
<div>
<textarea id="ta" cols="80" rows="8"></textarea>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$("#btn1").click(function() {
    $.ajax("control/controller10/ok.do", {
        method: "post",
        data: "hello!",
        headers: {"Content-Type":"text/plain"},
        dataType: "text"})
        .done(function(result) {
            $("#ta").val(result)
        })
        .fail(function(xhr, status, error) {
            $("#ta").val(xhr.responseText)
        })
})
$("#btn2").click(function() {
    $.ajax("control/controller10/ok.do", {
        method: "post",
        data: '{"name":"hong", "age":"20", "tel":"1111-1111"}',
        headers: {"Content-Type":"application/json"},
        dataType: "json"})
        .done(function(result) {
            $("#ta").val(result)
        })
        .fail(function(xhr, status, error) {
            $("#ta").val(xhr.responseText)
        })
})
</script>
</body>
</html>


▶ 실행 방법: 

http://localhost8080:/spring-web01/controller10.html




Request Handler(요청을 처리하는 메서드)의 파라미터들 I

  프론트 컨트롤러는 페이지 컨트롤러의 메서드를 호출할 때,

   그 메서드가 어떤 파라미터 값을 요구하는 지를 분석하여

   그에 해당하는 값을 자동으로 꼽아줍니다.

 

 ▶ Request Handler의 파라미터로 선언할 수 있는 것

    1) HttpServletRequest, ServletRequest

    2) HttpServletResponse, ServletResponse

    3) HttpSession

    4) Map, Model 

    5) 요청 파라미터 



/* Spring webMVC: Request Handler(요청을 처리하는 메서드)의 파라미터들 I
 * => Request Handler의 파라미터로 선언할 수 있는 것
 *    1) HttpRequestServlet, ServletRequest
 */   
package control;

import java.io.FileInputStream;
import java.io.PrintWriter;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller  
@RequestMapping("/control/controller11/")
public class Controller11 {
  
  @RequestMapping("ok1") 
  public void ok1() throws Exception {
    System.out.println("ok1(): 프론트 컨트롤러로부터 아무것도 받지 않는다.");
  }

  @RequestMapping("ok2")
  public void ok2(HttpServletRequest request) throws Exception {
    System.out.println("ok2()");
  }

  @RequestMapping("ok3")
  public void ok3(HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("ok3()");
  }

  @RequestMapping("ok4")
  public void ok4(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("ok4()");
  }

  @RequestMapping("ok5")
  public void ok5(HttpSession session, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("ok5()");
  }
  
  // 프론트 컨트롤러가 줄 수 없는 값을 메서드에서 요구할 경우,
  // 즉 파라미터에 선언할 경우,
  // 실행할 때 오류가 발생한다!
  // 예) 다음 메서드에서 FileInputStream 파라미터가 이런 경우이다.
  @RequestMapping("ok6")
  public void ok6(FileInputStream in, HttpServletResponse response) throws Exception {
    System.out.println(in);
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("ok6()");

  }
  
  // 이 메서드에서 실행한 결과를 담을 빈 바구니를 요구할 수 있다.
  // 이 바구니에 값을 담으면, JSP에서 꺼내 쓸 수 있다.
  // 바구니의 타입은 Map 또는 Model 등이 가능하다.
  @RequestMapping("ok7")
  public void ok7(Map<String, Object> store, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("ok7()");
    
    store.put("name", "홍길동");
    store.put("age", 20);
  }
  // 이렇게 바구니에 담은 데이터는
  // 스프링의 프론트 컨트롤러가 ServletRequest에 보관한다.
  // 그래서 JSP에서 꺼내 쓸 수 있는 것이다.

  @RequestMapping("ok8")
  public void ok8(Model store, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("ok8()");
    
    store.addAttribute("name", "홍길동");
    store.addAttribute("age", 20);
      
    // Model이나 Map이나 쓰임새는 같다.
    // 이렇게 바구니에 담은 데이터는
    // 스프링의 프론트 컨트롤러가 ServletRequest에 보관한다.
    // 그래서 JSP에서 꺼내 쓸 수 있는 것이다.
  }

  // 클라이언트가 보낸 데이터를 꺼내기
  // => 예전처럼 문자열을 원하는 형식을 직접 형변환 해야 한다.
  @RequestMapping("ok9")
  public void ok9(HttpServletRequest request, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("ok9()");
    
    out.printf("name: %s\n", request.getParameter("name"));
    out.printf("age: %d\n", Integer.parseInt(request.getParameter("age")));
    out.printf("working: %b\n", Boolean.parseBoolean(request.getParameter("working")));
      
  }

  // 클라이언트가 보내는 데이터의 이름과 동일한 이름으로 파라미터 변수를 선언한다.
  // 그러면, 프론트 컨트롤러가 파라미터 이름과 같은 데이터를 찾아서 호출할 때 꼽아준다.
  // 프론트 컨트롤러는 문자열을 원시타입의 값으로 자동으로 바꿔준다.
  // 그 외의 타입에 대해서는 오류가 발생한다.
  // 해결책? => 웹 파라미터 타입 변환기를 설치해야 한다.
  @RequestMapping("ok10")
  public void ok10(String name, int age, boolean working, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("ok10()");
    out.printf("name: %s\n", name);
    out.printf("age: %d\n", age);
    out.printf("working: %b\n", working);
    
  }
}


▶ 실행 방법: 

http://localhost8080:/spring-web01/control/controller11/ok숫자.do?파라미터명=값&파라미터명=값



Request Handler(요청을 처리하는 메서드)의 파라미터들 II


/* Spring webMVC: Request Handler(요청을 처리하는 메서드)의 파라미터들 II - 
 */  
package control;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller  
@RequestMapping("/control/controller12/")
public class Controller12 {
  // 클라이언트가 보낸 파라미터 값을 받는 방법
  
  // 1) 보내는 데이터(요청 파라미터)의 이름과 같은 이름으로 아규먼트 이름을 짓는다.
  @RequestMapping("ok1")
  public void ok1(String name, int age, boolean working, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("ok1()");
    out.printf("name: %s\n", name);
    out.printf("age: %d\n", age);
    out.printf("working: %b\n", working);
  }
  
  // 2) 보내는 데이터(요청 파라미터)의 이름과 아규먼트 이름이 다를 경우
  //    @RequestParam 애노테이션을 사용하여 그 이름을 지정할 수 있다.
  //    단, @RequestParam을 붙이는 순간 필수 항목이 된다. URL에 파라미터로 넘겨주지 않으면 오류 발생!
  @RequestMapping("ok2")
  public void ok2(
      @RequestParam(name="name") String n, 
      @RequestParam(name="age")int a, 
      @RequestParam(name="working")boolean w, 
      HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("ok2()");
    out.printf("name: %s\n", n);
    out.printf("age: %d\n", a);
    out.printf("working: %b\n", w);
  }

  // 3) @RequestParam 애노테이션에서 요청 파라미터 값을 선택 항목으로 만들기
  @RequestMapping("ok3")
  public void ok3(
      @RequestParam(name="name", required=false) String n, 
      @RequestParam(name="age", required=false)int a, 
      @RequestParam(name="working", required=false)boolean w, 
      HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("ok3()");
    out.printf("name: %s\n", n);
    out.printf("age: %d\n", a);
    out.printf("working: %b\n", w);
  }

  // 4) @RequestParam 애노테이션에서 요청 파라미터의 기본(default) 값 지정하기
  @RequestMapping("ok4")
  public void ok4(
      @RequestParam(name="name", required=false) String n, 
      @RequestParam(name="age", required=false, defaultValue="0")int a, 
      @RequestParam(name="working", required=false, defaultValue="false")boolean w, 
      HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("ok4()");
    out.printf("name: %s\n", n);
    out.printf("age: %d\n", a);
    out.printf("working: %b\n", w);
  }

  // 5) 요청 파라미터 값을 바로 값 객체(Value Object; VO)에 저장하기
  //    VO 객체의 프로퍼티 이름과 일치하는 요청 파라미터를 찾아서 그 값을 넣어준다.
  //    누가? 프론트 컨트롤러가 Member 객체를 생성한 다음에 값을 넣어준다.
  @RequestMapping("ok5")
  public void ok5(Member member, HttpServletResponse response) throws Exception {
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("ok5()");
    out.printf("name: %s\n", member.getName());
    out.printf("age: %d\n", member.getAge());
    out.printf("working: %b\n", member.isWorking());
  }
}



ok5() 메서드 파라미터의 Member.class 작성하기


package control; public class Member { String name; int age; boolean working; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public boolean isWorking() { return working; } public void setWorking(boolean working) { this.working = working; } }


▶ 실행 방법: 

http://localhost8080:/spring-web01/control/controller12/ok숫자.do?파라미터명=값&파라미터명=값



블로그 이미지

필로그래머

,