Spring Boot parameter 값 전달

송지윤·2024년 4월 9일

Spring Boot

목록 보기
13/71

html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>서버로 파라미터 제출하기</title>
</head>
<body>
    <h1>서버로 파라미터 제출하기</h1>

    <h3>1. HttpServletRequest.getParameter("key") 이용</h3>

    <form action="/param/test1" method="post">
        이름 : <input type="text" name="inputName"> <br>
        나이 : <input type="number" name="inputAge"> <br>
        주소 : <input type="text" name="inputAddress"> <br>

        <button>제출하기</button>
    </form>

	<hr>
	
	<h3>
		2. @RequestParam 어노테이션을 이용
		- 낱개(단수) 파라미터 컨트롤러에서 얻어오는 방법
	</h3>
    
	<form action="/param/test2" method="post">
		책 제목 : <input type="text" name="title"> <br>
        작성자 : <input type="text" name="writer"> <br>
        가격 : <input type="number" name="price"> <br>

        <button>제출하기</button>
	</form>
</body>
</html>

Controller

package com.home.demo.controller;

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 jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;

// Bean : 스프링이 만들고 관리하는 객체

@Controller // 요청 / 응답 제어 역할 명시 + Bean 등록
@RequestMapping("param") // 공통주소 param /param 으로 시작하는 모든 요청이 현재 컨트롤러로 매핑
@Slf4j // log 사용할 거라고 알려주는 거 lombok 에서 지원 log 를 이용한 메세지 출력 시 사용 (Lombok 라이브러리에서 제공)
public class ParameterController {

	@GetMapping("main") // /param/main GET 방식 요청 매핑
	public String paramMain() {
		
		// classpath: src/main/resources
		// 접두사 : classpath:/templates/
		// 접미사 : .html
		// -> src/main/resources/templates/param/param-main.html
		return "param/param-main";
	}

1. HttpServletRequest.getParameter("key") 이용

HttpServletRequest :

  • 요청 클라이언트 정보, 제출된 파라미터 등을 저장한 객체
  • 클라이언트 요청 시 생성

전달인자 해결사 전달인자 Argument 해결사 Resolver

ArgumentResolver (전달 인자 해결사)
Spring Boot 가 매개변수 전달인자 보고 알아서 불러줌

  • Spring 의 Controller 메서드 작성 시
    매개변수에 원하는 객체를 작성하면
    존재하는 객체를 바인딩 또는 없으면 생성해서 바인딩

	@PostMapping("test1") // /param/test1 POST 방식 요청 매핑
	public String paramTest1(HttpServletRequest req) {
		
		String inputName = req.getParameter("inputName");
		int inputAge = Integer.parseInt(req.getParameter("inputAge"));
		String inputAddress = req.getParameter("inputAddress");
		
		// debug : 코드 오류 해결
		// -> 코드 오류 없는데 정상 수행이 안될 때
		// -> 값이 잘못된 경우 -> 값 추적
		// debug 내역을 log 에 띄워줄 거임
		// log 사용하려면 Controller 위에 @Slf4j 로그 추가해줘야함 (Lombok 에서 지원)
		log.debug("inputName : " + inputName);
		log.debug("inputAge : " + inputAge);
		log.debug("inputAddress : " + inputAddress);

log 확인하기
나중에 log 내보내는 파일 만들어서 저장해놓고 추적할 수 있음

inputName : 홍길동
inputAge : 20
inputAddress : 콘솔 창 확인하기

		// redirect
		/* Spring 에서 Redirect(재요청) 하는 방법
		 * 
		 * -Controller 메서드 반환 값에
		 * "redirect:요청주소"; 작성
		 * */
		return "redirect:/param/main";
	}

2. @RequestParam 어노테이션을 이용 - 낱개 파라미터 얻어오기 (쓰고 싶은만큼 써서 가져오면 됨)

  • request 객체를 이용한 파라미터 전달 어노테이션
  • 매개변수 앞에 해당 어노테이션을 작성하면, 매개변수에 값이 주입됨.
  • 주입되는 데이터는 매개변수의 타입에 맞게 형변환/파싱이 자동으로 수행됨

[기본 작성법]
@RequestParam("key") 자료형 매개변수명
key = name값


	@PostMapping("test2")
	public String paramTest2(@RequestParam("title") String title,
			@RequestParam("writer") String writer,
			@RequestParam("price") int price,  // 자동으로 형변환 됨 강제 형변환(파싱) 안해줘도 됨
			@RequestParam(value="publisher", required=false) String publisher
			) {
		
		log.debug("title : " + title);
		log.debug("writer : " + writer);
		log.debug("price : " + price);
		log.debug("publisher : " + publisher);

log 확인하기

title : 어린왕자
writer : 생택쥐베리
price : 11000

@RequestParam("publisher") String publisher 구문 추가 html 에서는 input 받는 창 없음
=> 400 bad request 에러남

@RequestParam
기본 작성법대로 작성하면 요청 받을 때 parameter 값이 꼭 있어야함

[속성 추가 작성법]
@RequestParam(value="name", required="false", defaultValue="1")

value : 전달받은 input 태그의 name 속성값

required : 입력된 name 속성값의 parameter 필수 여부 지정(기본값이 true)
-> false 로 되어있으면 들어온 값이 없어도 에러 안 남
publisher : null
(required=false 작성하고 defaultValue 작성 안하고, input 작성 안했을 때)

defaultValue : 아무것도 입력 안했을 때 default 로 지정해놓은 값 들어감
파라미터 중 일치하는 name 속성값이 없을 경우에 대입할 값 지정
-> required=false 인 경우 사용
defaultValue 적었을 때 publisher : ABC출판사

@ComponentScan

package com.home.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication // Spring Boot Application에 필요한 필수 어노테이션을 모아둔 어노테이션
public class DemoProject3Application {

	public static void main(String[] args) {
		SpringApplication.run(DemoProject3Application.class, args);
	}

}

@SpringBootApplication 어노테이션 들어가보면 안에 @ComponentScan 이 있음

main 메서드 안에서 spring application run 실행했을 때

메서드들을 전체적으로 훑으면서

@Service 어노테이션 보면 @ComponentScan 이 Bean 으로 만들어줌 + Service 객체임을 명시
-> 그 때부터 Spring Container가 관리해줌

@Controller
@Bean
... 등등

application.properties

UTF-8 안 바꿔주면 오류 발생

src/main/java 안에 templates static application.properties 자동으로 생성되어 있음

프로젝트의 전반적 설정 적용하는 곳 : application.properties

templates 안에는 HTML 응답페이지 모아둠 thymeleaf 사용 jsp 사용 안함

static 안에는 resources 안에 css, js, image 모아둘 거

log 레벨 지정

application.properties 에서

logging.level.패키지명=debug

ex)
logging.level.com.home.demo=debug

설정해주고 사용할 클래스 위에 @Slf4j
클래스 안에서 사용할 때는
log.debug(내용);

log 레벨 6가지

  • TRACE : 가장 상세한 로그 레벨로, 상세한 정보를 기록
  • DEBUG : 디버깅에 유용한 정보를 기록 (값 추적) (한 단계 내려서 FETAL 까지 다 뜸)
  • INFO : 일반적인 정보 메세지 기록 (Spring Boot 기본)
  • WARN : 경고 메세지를 기록 (어플리케이션이 예상 못한 에러 발생했을 때)
  • ERROR : 오류 메세지를 기록, 심각한 문제 발생 시 사용
  • FATAL : 가장 심각한 오류, (볼 일 거의 없음) 프로그램 완전 중단, 하드 망가짐 치명적 오류

ViewResolver

Controller method에서 return 값에 forward 하려는 HTML 파일 경로 작성
단, ViewResolver 가 제공하는 Thymeleaf 접두사, 접미사 제외하고 작성

접두사 : classpath:/templates/
접미사 : .html

ArgumentResolver

전달 인자 해결사
Spring 내장 객체 생성해서 주입시켜줌(Spring 이)
Spring 의 Controller 메서드 작성 시 매개변수에 원하는 객체를 작성하면 존재하는 객체를 바인딩 또는 없으면 생성해서 바인딩

3. @ RequestParam 으로 값 여러개 가져오기

String []
List<자료형>
Map<String, Object>

required 속성은 사용 가능하나,
defaultValue 속성은 사용 불가

html

    <h3>
        3. @RequestParam 어노테이션을 이용
        - 여러 개 (복수) 파라미터 컨트롤러에서 얻어오는 방법
    </h3>

    <form action="/param/test3" method="post">
        색상 : 
        Red <input type="checkbox" name="color" value="Red">
        Green <input type="checkbox" name="color" value="Green">
        Blue <input type="checkbox" name="color" value="Blue">

        <br><br>

        과일 : 
        Apple <input type="checkbox" name="fruit" value="Apple">
        Banana <input type="checkbox" name="fruit" value="Banana">
        Orange <input type="checkbox" name="fruit" value="Orange">

        <br><br>
        상품명 : <input type="text" name="productName"> <br>
        유통기한 : <input type="date" name="expirationDate"> <br>

        <br><br>
        <button>제출하기</button>
    </form>
</body>

Controller

	@PostMapping("test3")
	public String paramTest3(@RequestParam(value="color", required=false) String[] colorArr,
			@RequestParam(value="fruit", required=false) List<String> fruitList,
			@RequestParam Map<String, Object> paramMap) {
		
		log.debug("colorArr : " + Arrays.toString(colorArr));
		// colorArr : [Red, Green, Blue]
		
		log.debug("fruitList : " + fruitList);
		// fruitList : [Apple, Banana, Orange]
		
		/* @RequestParam Map<String, Object>
		 * -> 제출된 모든 파라미터가 Map 에 저장된다
		 * -> 단, key(name 속성값)이 중복되면 처음 들어온 값 하나만 저장됨
		 * -> 같은 name 속성 파라미터 String[], List 로 저장 X
		 * */
		log.debug("paramMap : " + paramMap);
		// paramMap : {color=Red, fruit=Apple, productName=키링, expirationDate=2024-05-04}
		// Map 은 key (name 속성값) 가 중복되면 한개만 나옴 낱개들을 가져올 때(name 값이 겹치지 않는 값) 쓰기 좋음
		return "redirect:/param/main";
	}

4. @ModelAttribute 를 이용한 파라미터 얻어오기

@ModelAttribute
DTO(또는 VO)와 같이 사용하는 어노테이션

전달 받은 파라미터의 name 속성 값이 같이 사용되는 DTO의 필드명과 같으면 자동으로 setter 를 호출해서 필드에 값을 세팅

@ModelAttribute를 이용해 값이 필드에 세팅된 객체를 "커맨드 객체" 라고 부름

@ModelAttribute 사용 시 주의사항

  • DTO에 기본생성자, setter 가 필수로 존재해야 함

@ModelAttribute 어노테이션은 생략 가능

html

	<form action="/param/test4" method="POST">
		ID : <input type="text" name="memberId"> <br>
        PW : <input type="password" name="memberPw"> <br>
        NAME : <input type="text" name="memberName"> <br>
        AGE : <input type="number" name="memberAge"> <br>

        <button>제출하기</button>
	</form>

MemberDTO

package com.home.demo.model.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

// Lombok : 자주 사용하는 코드를 컴파일 시 자동 완성 해주는 라이브러리
// -> DTO(기본생성자, getter/setter, toString) + Log

@AllArgsConstructor // 매개변수 생성자
@NoArgsConstructor // 기본생성자
@ToString // toString 오버라이딩 자동완성
@Setter // setter 자동완성
@Getter // getter 자동완성
public class MemberDTO {

	private String memberId;
	private String memberPw;
	private String memberName;
	private int memberAge;
}

Controller

inputMember 커맨드 객체라고 부름

	@PostMapping("test4")
	public String paramTest4(@ModelAttribute MemberDTO inputMember) {
		
		log.debug("inputMember : " + inputMember);

		return "redirect:/param/main";
	}

log 값 확인하기
inputMember : MemberDTO(memberId=user01, memberPw=pass01, memberName=홍길동, memberAge=20)

0개의 댓글