본문 바로가기
Spring

[Spring] MVC (4) 요청시 parameter 처리

by moca7 2024. 10. 16.

 

 

ㅁ 요청시 전달값(parameter)들을 뽑아서 변수에 담거나 dto에 담아서 넘겼었다.

ㅁ 요청시 전달되는 데이터들이 많은데 그 데이터들을 어떻게 처리할지 (요청시 데이터를 뽑는 과정)

 

 

 

ㅁ 요청시 파라미터를 처리하는 방법 3가지

 

(1) HttpServletRequest 방법

(2) @RequestParam 방법

(3) 커맨드 객체 방법

- 1번째 기능은 스프링 이전의 전통적인 방법이다. 2번째 기능부터 스프링 프레임워크의 기능이라고 생각하면 된다.

 

 

 

 

(1) HttpServletRequest 방법

 

 

 

 

ㅁ main.jsp

 

 
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
   
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>

<script src="${ contextPath }/resources/js/sample.js"></script>

<script src="${ contextPath }/assets/js/jquery-3.7.1.min.js"></script>

</head>
<body>

    <!-- / 또는 /main.do라는 url mapping으로 요청시 해당 /WEB-INF/views/main.jsp가 보여지도록 한다. -->
    <h1>메인페이지입니다</h1>

    <h3>1. 정적 자원 확인</h3>
    <img src="${ contextPath }/resources/images/1.jpeg" width="100" onclick="test();">
    <img src="${ contextPath }/assets/images/2.jpg" width="100" id="img">
   
    <script>
        $(function(){
            $('#img').on("click", () => {
                alert("어서오세요");
            })
        })
    </script>
   
    <hr>


    <h3>2. 응답페이지 보여지게 하는 연습 (포워딩, redirect)</h3>

    <!-- <a href="${contextPath}/list.bk">도서목록페이지로 이동</a> -->
    <a href="${contextPath}/book/list.do">도서목록페이지로 이동</a> <br>
    <a href="${contextPath}/book/enrollForm.do">도서등록페이지로 이동</a>



    <hr>


    <h3>3. 요청시 전달되는 파라미터 처리하는 연습 (request의 parameter)</h3>

    <!-- <a href="${contextPath}/detail.mem?no=1">회원상세조회</a> -->
    <a href="${contextPath}/member/detail.do?no=1">회원상세조회</a> <br>





</body>
</html>
 

 

 

 

 

 

 

 

ㅁ controller 패키지에 MemberController 일반 클래스를 만든다.

 

 
package com.br.mvc.controller;

import javax.servlet.http.HttpServletRequest;

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

@RequestMapping("/member")
@Controller
public class MemberController {


    // 1. HttpServletRequest 방법
    @RequestMapping("/detail.do")
    public String memberDetail(HttpServletRequest request) {
        int no = Integer.parseInt(request.getParameter("no"));
        System.out.println("조회할 회원번호: " + no);
       
       
        return "main"; // 응답은 메인페이지로 포워딩. 이게 중요한 건아닌데 404 거슬리니까.
    }


}
 

 

 

- 컨트롤러 패키지는 항상 클래스 상단에 @Controller를 써서 빈으로 등록한다.

- @RequestMapping("/member")

 

 

 

 

 

 

 

 

- 기존에 하던 방식대로 request에서 값을 뽑아서, 형변환해서 변수에 대입시켰다.

- 이번엔 하나의 데이터 말고 다수의 데이터를 요청시 넘겨본다.

 

 

 

 

 

ㅁ main.jsp 수정

 

 
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
   
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>

<script src="${ contextPath }/resources/js/sample.js"></script>

<script src="${ contextPath }/assets/js/jquery-3.7.1.min.js"></script>

</head>
<body>

    <!-- / 또는 /main.do라는 url mapping으로 요청시 해당 /WEB-INF/views/main.jsp가 보여지도록 한다. -->
    <h1>메인페이지입니다</h1>

    <h3>1. 정적 자원 확인</h3>
    <img src="${ contextPath }/resources/images/1.jpeg" width="100" onclick="test();">
    <img src="${ contextPath }/assets/images/2.jpg" width="100" id="img">
   
    <script>
        $(function(){
            $('#img').on("click", () => {
                alert("어서오세요");
            })
        })
    </script>
   
    <hr>


    <h3>2. 응답페이지 보여지게 하는 연습 (포워딩, redirect)</h3>

    <!-- <a href="${contextPath}/list.bk">도서목록페이지로 이동</a> -->
    <a href="${contextPath}/book/list.do">도서목록페이지로 이동</a> <br>
    <a href="${contextPath}/book/enrollForm.do">도서등록페이지로 이동</a>



    <hr>


    <h3>3. 요청시 전달되는 파라미터 처리하는 연습 (request의 parameter)</h3>

    <!-- <a href="${contextPath}/detail.mem?no=1">회원상세조회</a> -->
    <a href="${contextPath}/member/detail.do?no=1">회원상세조회</a> <br><br><br>
 
    <!-- (1) HttpServletRequest 방법 -->
    <form action="${ contextPath }/member/enroll1.do" method="post">
        이름 : <input type="text" name="name"> <br>
        나이 : <input type="text" name="age"> <br>
        주소 : <input type="text" name="address"> <br>
        <button>등록</button>
    </form>



</body>
</html>
 

 

 

 

 

 

 

ㅁ MemberController 수정

 

 
package com.br.mvc.controller;

import javax.servlet.http.HttpServletRequest;

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

@RequestMapping("/member")
@Controller
public class MemberController {


    // 1. HttpServletRequest 방법
    @RequestMapping("/detail.do")
    public String memberDetail(HttpServletRequest request) {
        int no = Integer.parseInt(request.getParameter("no"));
        System.out.println("조회할 회원번호: " + no);
       
       
        return "main"; // 응답은 메인페이지로 포워딩. 이게 중요한 건아닌데 404 거슬리니까.
    }

   
    // @RequestMapping(value="/enroll1.do", method=RequestMethod.GET) - 405 에러 발생
    // @RequestMapping(value="/enroll1.do", method=RequestMethod.POST) - 이렇게 해도 되고,
    @PostMapping("/enroll1.do") // 스프링이 버전업되며 새로 나온 방식
    public String memberEnroll1(HttpServletRequest request) {

        // request.setCharacterEncoding("utf-8"); -> 스프링에서 제공하는 인코딩 필터 등록 (web.xml)
        String name = request.getParameter("name");
        int age = Integer.parseInt(request.getParameter("age"));
        String address = request.getParameter("address");
       
        System.out.println("이름: " + name);
        System.out.println("나이: " + age);
        System.out.println("주소: " + address);
       
        return "main";
    }

}
 

 

- Sping이 버전업 되면서 @GetMapping, @PostMapping을 지원한다.

메소드 속성을 생략할 수 있다.

 

- Spring Boot에서는 HTTP 메서드에 따라 더 명확한 @GetMapping, @PostMapping 같은 어노테이션이 제공되기 때문에, 이러한 어노테이션을 사용하는 것이 권장된다.

 

- request.setCharacterEncoding("utf-8") 

빨간줄 뜬다. 서블릿에서 할 때는 throws로 던졌다. 

- 필터 클래스를 등록한다. 직접 만들 필요 없이 스프링이 제공하는 인코딩 필터를 web.xml에 등록한다.

 

 

 

 

 

- post방식 요청인데 메소드를 get으로 설정해본다.

 

 

- 요청 전송 방식이 맞지 않을 경우 405 에러가 발생한다.

 

 

 

 

 

 

 

ㅁ web.xml

 

 
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"

    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/root-context.xml</param-value>
    </context-param>
   
    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Processes application requests -->
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
       
    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>


    <!-- 스프링에서 제공하는 인코딩 필터 등록 -->
    <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>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>



</web-app>
 

 

- 서블릿 등록에 <servlet>, <servlet-mapping> 태그를 사용하듯이

필터 등록엔 <filter>, <filter-mapping> 태그를 사용한다.

- 서버가 시작될 때 해당 설정이 바로 로드되므로, 설정 파일에 오타나 오류가 있으면 애플리케이션이 시작되지 않고 오류가 발생할 수 있다.

 

- Spring Boot는 자동으로 UTF-8 인코딩을 설정하므로, 별도의 설정이 필요하지 않습니다.

 

 

 

 

 

ㅁ 회원등록 해보기

 

 

 

- 이름, 나이, 주소를 입력하고 '등록' 버튼을 누른다.

 

 

 

 

 

 

 

 

ㅁ 

- 스프링을 쓰는 이유가 별로 없다. 내가 직접 뽑고 직접 변수에 담았다.

 

 

 

==================================================================================

 

 

 

(2) @RequestParam 방법

 

 

ㅁ main.jsp 수정

 

 
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
   
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>

<script src="${ contextPath }/resources/js/sample.js"></script>

<script src="${ contextPath }/assets/js/jquery-3.7.1.min.js"></script>

</head>
<body>

    <!-- / 또는 /main.do라는 url mapping으로 요청시 해당 /WEB-INF/views/main.jsp가 보여지도록 한다. -->
    <h1>메인페이지입니다</h1>

    <h3>1. 정적 자원 확인</h3>
    <img src="${ contextPath }/resources/images/1.jpeg" width="100" onclick="test();">
    <img src="${ contextPath }/assets/images/2.jpg" width="100" id="img">
   
    <script>
        $(function(){
            $('#img').on("click", () => {
                alert("어서오세요");
            })
        })
    </script>
   
    <hr>


    <h3>2. 응답페이지 보여지게 하는 연습 (포워딩, redirect)</h3>

    <!-- <a href="${contextPath}/list.bk">도서목록페이지로 이동</a> -->
    <a href="${contextPath}/book/list.do">도서목록페이지로 이동</a> <br>
    <a href="${contextPath}/book/enrollForm.do">도서등록페이지로 이동</a>



    <hr>


    <h3>3. 요청시 전달되는 파라미터 처리하는 연습 (request의 parameter)</h3>

    <!-- <a href="${contextPath}/detail.mem?no=1">회원상세조회</a> -->
    <a href="${contextPath}/member/detail.do?no=1">회원상세조회</a> <br><br><br>

    <!-- (1) HttpServletRequest 방법 -->
    <form action="${ contextPath }/member/enroll1.do" method="post">
        이름 : <input type="text" name="name"> <br>
        나이 : <input type="text" name="age"> <br>
        주소 : <input type="text" name="address"> <br>
        <button>등록</button>
    </form>

    <br><br>

    <!-- (2) @RequestParam 방법 -->
    <form action="${ contextPath }/member/enroll2.do" method="post">
        이름 : <input type="text" name="name"> <br>
        나이 : <input type="text" name="age"> <br>
        주소 : <input type="text" name="address"> <br>
        <button>등록</button>
    </form>



</body>
</html>
 

 

 

 

 

 


 MemberController 수정

 

 
package com.br.mvc.controller;

import javax.servlet.http.HttpServletRequest;

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

@RequestMapping("/member")
@Controller
public class MemberController {


    // 1. HttpServletRequest 방법
    @RequestMapping("/detail.do")
    public String memberDetail(HttpServletRequest request) {
        int no = Integer.parseInt(request.getParameter("no"));
        System.out.println("조회할 회원번호: " + no);
       
       
        return "main"; // 응답은 메인페이지로 포워딩. 이게 중요한 건아닌데 404 거슬리니까.
    }

   
    // @RequestMapping(value="/enroll1.do", method=RequestMethod.GET) - 405 에러 발생
    // @RequestMapping(value="/enroll1.do", method=RequestMethod.POST) - 이렇게 해도 되고,
    @PostMapping("/enroll1.do") // 스프링이 버전업되며 새로 나온 방식
    public String memberEnroll1(HttpServletRequest request) {

        // request.setCharacterEncoding("utf-8"); -> 스프링에서 제공하는 인코딩 필터 등록 (web.xml)
        String name = request.getParameter("name");
        int age = Integer.parseInt(request.getParameter("age"));
        String address = request.getParameter("address");
       
        System.out.println("이름: " + name);
        System.out.println("나이: " + age);
        System.out.println("주소: " + address);
       
        return "main";
    }

   
   
    // (2) @RequestParam 방법
    // request.getParameter()를 자동으로 실행하는 어노테이션
    @PostMapping("/enroll2.do")
    public String memberEnroll2(@RequestParam(value="name") String name
                              , @RequestParam(value="age") int age
                              , @RequestParam(value="address") String addr) {
       
        System.out.println("이름: " + name);
        System.out.println("나이: " + age);
        System.out.println("주소: " + addr);
       
        return "main";
    }
   
   
   
   
}
 

 

 

- @RequestParam 어노테이션 하나하나가 곧 request.getPrameter()다.

- 내가 형변환하지 않아도 자동으로 parsing되서 담긴다.

 

 

 

- 이름, 나이, 주소를 입력하고 '등록' 버튼을 누른다.

 

 

 

 

 

 

 

 

 

ㅁ MemberController 수정

 

   
    // (2) @RequestParam 방법
    // request.getParameter()를 자동으로 실행하는 어노테이션
    @PostMapping("/enroll2.do")
    public String memberEnroll2(/*@RequestParam(value="name")*/ String name
                              , @RequestParam(value="age") int age
                              , @RequestParam(value="address") String addr) {
       
        System.out.println("이름: " + name);
        System.out.println("나이: " + age);
        System.out.println("주소: " + addr);
       
        return "main";
    }
   

 

 

- 매개변수 name 처럼 요청시 전달되는 key값과 매개변수의 이름이 같으면 @RequestParam 어노테이션을 생략할 수 있다.

- 매개변수 addr은 요청시 전달되는 key값과 매개변수 이름이 달라서 @RequestParam 어노테이션을 생략할 수 없다.

 

 

 

 

 

   
    // (2) @RequestParam 방법
    // request.getParameter()를 자동으로 실행하는 어노테이션
    @PostMapping("/enroll2.do")
    public String memberEnroll2(/*@RequestParam(value="name")*/ String name
                              , /*@RequestParam(value="age")*/ int age
                              , @RequestParam(value="address") String addr) {
       
        System.out.println("이름: " + name);
        System.out.println("나이: " + age);
        System.out.println("주소: " + addr);
       
        return "main";
    }
   

 

 

- 그런데 String형이 아닌 int형 변수는 @RequestParam 어노테이션을 생략하면 오류가 발생할 수 있다.

int형은 null이 담길 수가 없고 숫자만 담긴다.

자동으로 파싱되는 과정이 있기 때문에 null이 오면 오류가 발생할 수 있다.

 

 

- int형 변수 age의 @RequestParam 어노테이션을 생략했을 때, 숫자

 

- 텍스트 상자에 아무 값도 입력하지 않고 요청을 보내면 빈 문자열이 담긴다.

 

 

 

 

 

 

- 400 오류가 발생한다.

 

 

 

- 콘솔에도 MethodArgumentTypeMismatchException이 발생했다고 출력된다.

- HTTP 요청에서 받은 파라미터의 타입이 메서드에서 요구한 타입과 맞지 않아서 발생.

- String 타입을 int로 변환하려고 했는데, 변환하려는 값이 빈 문자열이어서, 정수형(int)으로 변환할 수 없기 때문에 발생.

 

 

 

 

 

   
    // (2) @RequestParam 방법
    // request.getParameter()를 자동으로 실행하는 어노테이션
    @PostMapping("/enroll2.do")
    public String memberEnroll2(/*@RequestParam(value="name")*/ String name
                              , @RequestParam(value="age", defaultValue="10") int age
                              , @RequestParam("address") String addr) {
       
        System.out.println("이름: " + name);
        System.out.println("나이: " + age);
        System.out.println("주소: " + addr);
       
        return "main";
    }
   
   

 

 

- 그런데 @RequestParam 어노테이션을 생략했을 때만 400에러가 발생하는 것은 아니다. 

@RequestParam 어노테이션이 있어도 내부적으로 파싱돼서 매개변수에 담기기 때문에 빈문자열이 올 경우 400 에러가 발생한다.

- defaultValue 속성으로 기본값을 지정하면 오류가 나지 않는다.

 

- 그리고 value 속성 하나만 사용할거면 "value="을 생략할 수 있다. 알아서 value로 인식된다.

 

- 마이바티스를 쓰면 데이터를 하나만 넘길 수 있다. DTO에 담거나 Map에 담아서 넘긴다.

 

 

 

 

 

 

 

 

ㅁ com.br.mvc.dto 패키지에 MemberDto 일반 클래스 생성

 

 
package com.br.mvc.dto;

public class MemberDto {

    private String name;
    private int age;
    private String addr;
   
    public MemberDto() {
        super();
    }

    public MemberDto(String name, int age, String addr) {
        super();
        this.name = name;
        this.age = age;
        this.addr = addr;
    }

    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 String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }

    @Override
    public String toString() {
        return "MemberDto [name=" + name + ", age=" + age + ", addr=" + addr + "]";
    }
   
   
   
}
 

 

 

- 스프링 넘어오면서 필드명을 제시하면 내가 직접 게터 세터 메소드를 호출하지 않아도 내부적으로 실행되는 경우가 있다. 그래서 명명규칙을 잘 지켜야 한다. 이클립스는 자동완성 기능을 제공한다.

 

 

 

ㅁ MemberController 수정

 
package com.br.mvc.controller;

import javax.servlet.http.HttpServletRequest;

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

import com.br.mvc.dto.MemberDto;

@RequestMapping("/member")
@Controller
public class MemberController {


    // 1. HttpServletRequest 방법
    @RequestMapping("/detail.do")
    public String memberDetail(HttpServletRequest request) {
        int no = Integer.parseInt(request.getParameter("no"));
        System.out.println("조회할 회원번호: " + no);
       
       
        return "main"; // 응답은 메인페이지로 포워딩. 이게 중요한 건아닌데 404 거슬리니까.
    }

   
    // @RequestMapping(value="/enroll1.do", method=RequestMethod.GET) - 405 에러 발생
    // @RequestMapping(value="/enroll1.do", method=RequestMethod.POST) - 이렇게 해도 되고,
    @PostMapping("/enroll1.do") // 스프링이 버전업되며 새로 나온 방식
    public String memberEnroll1(HttpServletRequest request) {

        // request.setCharacterEncoding("utf-8"); -> 스프링에서 제공하는 인코딩 필터 등록 (web.xml)
        String name = request.getParameter("name");
        int age = Integer.parseInt(request.getParameter("age"));
        String address = request.getParameter("address");
       
        System.out.println("이름: " + name);
        System.out.println("나이: " + age);
        System.out.println("주소: " + address);
       
        return "main";
    }

   
   
    // (2) @RequestParam 방법
    // request.getParameter()를 자동으로 실행하는 어노테이션
    @PostMapping("/enroll2.do")
    public String memberEnroll2(/*@RequestParam(value="name")*/ String name
                              , @RequestParam(value="age", defaultValue="10") int age
                              , @RequestParam(value="address") String addr) {
       
        System.out.println("이름: " + name);
        System.out.println("나이: " + age);
        System.out.println("주소: " + addr);
       
        MemberDto mem = new MemberDto();
        mem.setName(name);
        mem.setAge(age);
        mem.setAddr(addr);
       
        System.out.println(mem);
       
        return "main";
    }
   


    @GetMapping("/detail2.do")
    public String memberDetail2(int no) {
        System.out.println("조회할 회원번호: " + no);
       
        return "main";
    }
   
   
   
}
 

 

- main의 2번째 form 가지고 요청해본다.

 

 

 

 

 

 

=====================================================================================

 

 

 

ㅁ main.jsp 수정

 

 
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
   
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>

<script src="${ contextPath }/resources/js/sample.js"></script>

<script src="${ contextPath }/assets/js/jquery-3.7.1.min.js"></script>

</head>
<body>

    <!-- / 또는 /main.do라는 url mapping으로 요청시 해당 /WEB-INF/views/main.jsp가 보여지도록 한다. -->
    <h1>메인페이지입니다</h1>

    <h3>1. 정적 자원 확인</h3>
    <img src="${ contextPath }/resources/images/1.jpeg" width="100" onclick="test();">
    <img src="${ contextPath }/assets/images/2.jpg" width="100" id="img">
   
    <script>
        $(function(){
            $('#img').on("click", () => {
                alert("어서오세요");
            })
        })
    </script>
   
    <hr>


    <h3>2. 응답페이지 보여지게 하는 연습 (포워딩, redirect)</h3>

    <!-- <a href="${contextPath}/list.bk">도서목록페이지로 이동</a> -->
    <a href="${contextPath}/book/list.do">도서목록페이지로 이동</a> <br>
    <a href="${contextPath}/book/enrollForm.do">도서등록페이지로 이동</a>



    <hr>


    <h3>3. 요청시 전달되는 파라미터 처리하는 연습 (request의 parameter)</h3>

    <!-- <a href="${contextPath}/detail.mem?no=1">회원상세조회</a> -->
    <a href="${contextPath}/member/detail.do?no=1">회원상세조회</a> <br><br><br>

    <!-- (1) HttpServletRequest 방법 -->
    <form action="${ contextPath }/member/enroll1.do" method="post">
        이름 : <input type="text" name="name"> <br>
        나이 : <input type="text" name="age"> <br>
        주소 : <input type="text" name="address"> <br>
        <button>등록</button>
    </form>

    <br><br>


    <!-- (2) @RequestParam 방법 -->
    <form action="${ contextPath }/member/enroll2.do" method="post">
        이름 : <input type="text" name="name"> <br>
        나이 : <input type="text" name="age"> <br>
        주소 : <input type="text" name="address"> <br>
        <button>등록</button>
    </form>

    <!-- <a href="${contextPath}/detail2.mem?no=1">회원상세조회</a> -->
    <a href="${contextPath}/member/detail2.do?no=1">회원상세조회</a> <br><br><br>

</body>
</html>
 

 

- detail2.do 만들었음.

 

 

 

ㅁ MemberController 수정

 

 
package com.br.mvc.controller;

import javax.servlet.http.HttpServletRequest;

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

@RequestMapping("/member")
@Controller
public class MemberController {


    // 1. HttpServletRequest 방법
    @RequestMapping("/detail.do")
    public String memberDetail(HttpServletRequest request) {
        int no = Integer.parseInt(request.getParameter("no"));
        System.out.println("조회할 회원번호: " + no);
       
       
        return "main"; // 응답은 메인페이지로 포워딩. 이게 중요한 건아닌데 404 거슬리니까.
    }

   
    // @RequestMapping(value="/enroll1.do", method=RequestMethod.GET) - 405 에러 발생
    // @RequestMapping(value="/enroll1.do", method=RequestMethod.POST) - 이렇게 해도 되고,
    @PostMapping("/enroll1.do") // 스프링이 버전업되며 새로 나온 방식
    public String memberEnroll1(HttpServletRequest request) {

        // request.setCharacterEncoding("utf-8"); -> 스프링에서 제공하는 인코딩 필터 등록 (web.xml)
        String name = request.getParameter("name");
        int age = Integer.parseInt(request.getParameter("age"));
        String address = request.getParameter("address");
       
        System.out.println("이름: " + name);
        System.out.println("나이: " + age);
        System.out.println("주소: " + address);
       
        return "main";
    }

   
   
    // (2) @RequestParam 방법
    // request.getParameter()를 자동으로 실행하는 어노테이션
    @PostMapping("/enroll2.do")
    public String memberEnroll2(/*@RequestParam(value="name")*/ String name
                              , @RequestParam(value="age", defaultValue="10") int age
                              , @RequestParam(value="address") String addr) {
       
        System.out.println("이름: " + name);
        System.out.println("나이: " + age);
        System.out.println("주소: " + addr);
       
        return "main";
    }
   


    @GetMapping("/detail2.do")
    public String memberDetail2(int no) {
        System.out.println("조회할 회원번호: " + no);
       
        return "main";
    }
   
   
   
}
 

 

- detail2.do 만들었음.

 

 

 

 

=======================================================================================

 

 

 

(3) 커맨드 객체 방법

- 요청 파라미터들을 각 필드에 담고자하는 객체에, 즉 전달값들을 특정 dto 객체에 바로 담는 경우 사용한다.

- 메소드의 매개변수로 전달값들을 담고자하는 객체를 작성하고,

요청 파라미터의 key값을 담고자하는 객체의 필드명으로 작성한다.

 

 

 

 

ㅁ 커맨드 객체는 ~다.

 

ㅁ 이제부턴 key값(name 속성값)도 중요하다.

어떤 필드에 담고 싶은지에 맞춰서 key값을 작성한다.

스프링이 내부적으로 setter메소드를 수행한다.

 

- /member/enroll3.do?name=홍길동&age=20&addr=서울 이라는 url 요청시

매개변수로 있는 DTO 객체를 기본생성자로 생성하고,

파라미터의 key값을 가지고 setter 메소드를 찾아서 실행한다.

 

(내부적으로 실행되는 내용)

MemberDto mem = new MemberDto();

mem.setName("홍길동");

mem.setAge(Integer.parseInt("20"));

mem.setAddr("서울");

 

- 그래서 dto 객체에 기본생성자와 setter 메소드가 존재해야 한다.

 

 

 

ㅁ main.jsp

 

 
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
   
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>

<script src="${ contextPath }/resources/js/sample.js"></script>

<script src="${ contextPath }/assets/js/jquery-3.7.1.min.js"></script>

</head>
<body>

    <!-- / 또는 /main.do라는 url mapping으로 요청시 해당 /WEB-INF/views/main.jsp가 보여지도록 한다. -->
    <h1>메인페이지입니다</h1>

    <h3>1. 정적 자원 확인</h3>
    <img src="${ contextPath }/resources/images/1.jpeg" width="100" onclick="test();">
    <img src="${ contextPath }/assets/images/2.jpg" width="100" id="img">
   
    <script>
        $(function(){
            $('#img').on("click", () => {
                alert("어서오세요");
            })
        })
    </script>
   
    <hr>


    <h3>2. 응답페이지 보여지게 하는 연습 (포워딩, redirect)</h3>

    <!-- <a href="${contextPath}/list.bk">도서목록페이지로 이동</a> -->
    <a href="${contextPath}/book/list.do">도서목록페이지로 이동</a> <br>
    <a href="${contextPath}/book/enrollForm.do">도서등록페이지로 이동</a>



    <hr>


    <h3>3. 요청시 전달되는 파라미터 처리하는 연습 (request의 parameter)</h3>

    <!-- <a href="${contextPath}/detail.mem?no=1">회원상세조회</a> -->
    <a href="${contextPath}/member/detail.do?no=1">회원상세조회</a> <br><br><br>

    <!-- (1) HttpServletRequest 방법 -->
    <form action="${ contextPath }/member/enroll1.do" method="post">
        이름 : <input type="text" name="name"> <br>
        나이 : <input type="text" name="age"> <br>
        주소 : <input type="text" name="address"> <br>
        <button>등록</button>
    </form>

    <br><br>


    <!-- (2) @RequestParam 방법 -->
    <form action="${ contextPath }/member/enroll2.do" method="post">
        이름 : <input type="text" name="name"> <br>
        나이 : <input type="text" name="age"> <br>
        주소 : <input type="text" name="address"> <br>
        <button>등록</button>
    </form>

    <!-- <a href="${contextPath}/detail2.mem?no=1">회원상세조회</a> -->
    <a href="${contextPath}/member/detail2.do?no=1">회원상세조회</a> <br><br><br>


    <br><br>


    <!-- (3) 커맨드 객체 방법 -->
    <form action="${ contextPath }/member/enroll3.do" method="post">
        이름 : <input type="text" name="name"> <br>
        나이 : <input type="text" name="age"> <br>
        주소 : <input type="text" name="address"> <br>
        <button>등록</button>
    </form>



</body>
</html>
 

 

 

 

 

 

ㅁ MemberController 수정

 

 
package com.br.mvc.controller;

import javax.servlet.http.HttpServletRequest;

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

import com.br.mvc.dto.MemberDto;

@RequestMapping("/member")
@Controller
public class MemberController {


    // 1. HttpServletRequest 방법
    @RequestMapping("/detail.do")
    public String memberDetail(HttpServletRequest request) {
        int no = Integer.parseInt(request.getParameter("no"));
        System.out.println("조회할 회원번호: " + no);
       
       
        return "main"; // 응답은 메인페이지로 포워딩. 이게 중요한 건아닌데 404 거슬리니까.
    }

   
    // @RequestMapping(value="/enroll1.do", method=RequestMethod.GET) - 405 에러 발생
    // @RequestMapping(value="/enroll1.do", method=RequestMethod.POST) - 이렇게 해도 되고,
    @PostMapping("/enroll1.do") // 스프링이 버전업되며 새로 나온 방식
    public String memberEnroll1(HttpServletRequest request) {

        // request.setCharacterEncoding("utf-8"); -> 스프링에서 제공하는 인코딩 필터 등록 (web.xml)
        String name = request.getParameter("name");
        int age = Integer.parseInt(request.getParameter("age"));
        String address = request.getParameter("address");
       
        System.out.println("이름: " + name);
        System.out.println("나이: " + age);
        System.out.println("주소: " + address);
       
        return "main";
    }

   
   
    // (2) @RequestParam 방법
    // request.getParameter()를 자동으로 실행하는 어노테이션
    @PostMapping("/enroll2.do")
    public String memberEnroll2(/*@RequestParam(value="name")*/ String name
                              , @RequestParam(value="age", defaultValue="10") int age
                              , @RequestParam(value="address") String addr) {
       
        System.out.println("이름: " + name);
        System.out.println("나이: " + age);
        System.out.println("주소: " + addr);
       
        MemberDto mem = new MemberDto();
        mem.setName(name);
        mem.setAge(age);
        mem.setAddr(addr);
       
        System.out.println(mem);
       
        return "main";
    }
   


    @GetMapping("/detail2.do")
    public String memberDetail2(int no) {
        System.out.println("조회할 회원번호: " + no);
       
        return "main";
    }
   
   




    // (3) 커맨드 객체 방법
    @PostMapping("/enroll3.do")
    public String memberEnroll3(MemberDto mem){
        System.out.println(mem);

        return "main";
    }

   
}
 

 

 

- 그냥 매개변수에 dto 객체만 주면 끝이다.

- main의 3번째 form 가지고 요청해본다.

 

 

 

 

 

 

- 그런데 주소는 안담겼다.

- key값과 dto 객체의 필드명이 달라서 담기지 않았다. 

넘어오는 key값을 바꾸든지 dto의 필드명을 바꾸든지 일치시키면 주소값도 잘 담긴다.

 

 

 

 

 

그런데 input 태그에 required 속성이 없어서 특정값을 입력하지 않을 수도 있다.

 

 



- 이름과 주소는 입력하지 않아도 텍스트 상자는 빈 문자열이 온다. null이 아니다.

- 그런데 나이를 입력하지 않으면 400 에러가 발생한다. 보통 parsing에서 문제가 생기면 400에러가 발생한다.

빈 문자열을 parsing하려해서 오류가 발생했다. 빈 문자열에 숫자가 없으니 parsing할 수 없다.

 

- 나이를 입력하지 않으면 빈 문자열을 숫자로 parsing하려해서 오류가 발생한다.

- dto 객체의 age 필드가 int형이어서 문제가 된다. String형이었으면 그냥 빈 문자열이 담기고 끝이다.

값이 누락되면 이런 오류가 빈번하게 발생해서 dto의 필드들을 다 String형으로 두는 경우가 많다.

db에서 number타입이어도 크게 상관 없다.

 

 

- MemberDto에서 age 필드만 수정하면 되는게 아니고, 매개변수 생성자, getter, setter 등 int age가 쓰인 곳은 모두 수정해야 한다.

- 뒤늦게 필드를 수정할 때 그 필드만 수정하면 되는게 아니고 매개변수 생성자, getter, setter 등 그 필드가 쓰인 모든 곳을 수정해야 한다.

뒤늦게 필드를 추가할 때도 생성자, getter, setter를 전부 추가해야 한다.

- Lombok이라는 라이브러리를 사용하면 생성자, getter, setter 등을 일일이 작성하지 않아도 된다.

Lombok을 사용하지 않는 회사면 일일이 작성해야 한다.

- Lombok은 스프링의 기능이 아니다.

 

- 이제부터는 DTO 객체에 필드만 작성한다. 그러면 필드를 바탕으로 자동으로 생성자, getter, setter를 만들어 준다.

필드를 수정하면 알아서 생성자, getter, setter도 전부 바뀐다.

 

 

'Spring' 카테고리의 다른 글

[Spring] MVC (6) 응답페이지 이동시 응답데이터 담기  (1) 2024.10.17
[Spring] MVC (5) Lombok 사용  (1) 2024.10.17
[Spring] MVC (3) book 서비스  (1) 2024.10.16
[Spring] MVC (2) resources 등록  (0) 2024.10.16
[Spring] MVC (1)  (0) 2024.10.16