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";
}
HttpServletRequest :
전달인자 해결사 전달인자 Argument 해결사 Resolver
ArgumentResolver (전달 인자 해결사)
Spring Boot 가 매개변수 전달인자 보고 알아서 불러줌
@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";
}
[기본 작성법]
@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출판사
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
... 등등
UTF-8 안 바꿔주면 오류 발생
src/main/java 안에 templates static application.properties 자동으로 생성되어 있음
프로젝트의 전반적 설정 적용하는 곳 : application.properties
templates 안에는 HTML 응답페이지 모아둠 thymeleaf 사용 jsp 사용 안함
static 안에는 resources 안에 css, js, image 모아둘 거
application.properties 에서
logging.level.패키지명=debug
ex)
logging.level.com.home.demo=debug
설정해주고 사용할 클래스 위에 @Slf4j
클래스 안에서 사용할 때는
log.debug(내용);
Controller method에서 return 값에 forward 하려는 HTML 파일 경로 작성
단, ViewResolver 가 제공하는 Thymeleaf 접두사, 접미사 제외하고 작성
접두사 : classpath:/templates/
접미사 : .html
전달 인자 해결사
Spring 내장 객체 생성해서 주입시켜줌(Spring 이)
Spring 의 Controller 메서드 작성 시 매개변수에 원하는 객체를 작성하면 존재하는 객체를 바인딩 또는 없으면 생성해서 바인딩
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";
}
@ModelAttribute
DTO(또는 VO)와 같이 사용하는 어노테이션
전달 받은 파라미터의 name 속성 값이 같이 사용되는 DTO의 필드명과 같으면 자동으로 setter 를 호출해서 필드에 값을 세팅
@ModelAttribute를 이용해 값이 필드에 세팅된 객체를 "커맨드 객체" 라고 부름
@ModelAttribute 사용 시 주의사항
@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)