본문 바로가기
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을 지원한다.

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

- 나중엔 부트 프로젝트를 할건데 그때는 @RequestMapping을 못 쓰게 막아놨다.

@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> 태그를 사용한다.

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

 

 

 

 

 

 

ㅁ 회원등록 해보기

 

 

 

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

 

 

 

 

 

 

 

 

ㅁ 

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

 

 

 

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

 

 

 

(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의 필드명을 바꾸든지 일치시키면 주소값도 잘 담긴다.

 

 

 

 

 

ㅁ 그런데 문제는 required 속성이 없어서 특정값을 입력하지 않을 수도 있다.

 



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

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

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

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

그래서 값이 누락되면 이런 오류가 빈번를 방지하고자 dto에 이런 오류를 방지하고자 String형으로 둔다.

값이 누락되면 오류가 빈번해서 다 String형으로 두는 경우가 많다. db에서 number타입이어도 크게 상관 없다.

 

 

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

- 뒤늦게 필드를 추가, 생성할 때도 생성자, getter, setter 전부 추가해야 한다. 상당히 번거롭다.

그런 기능의 라이브러리가 있다. Lombok. 쓰지 않는 회사면 일일이 다 만들고 수정해야 한다.

스프링 기능이 아니다.

생성자, getter, setter 등을 전부 쓰지 않아도 된다.

이제부터 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