Spring 실습 8일차 (요청 처리)
컨트롤러에 MemberController 클래스를 만들어주자
URL 경로 상의 쿼리 파라미터 정보로부터 요청 데이터를 취득
package kr.or.ddit.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
public class MemberController {
/*
URL 경로 상의 쿼리 파라미터 정보로부터 요청 데이터를 취득
요청URI : /register?userId=hongkd&password=1234
요청 파라미터(쿼리스트링) : userId=hongkd&password=1234
요청 방식 : get
스프링 프레임워크에서는 파라미터를 매개변수로 받을 수 있음
*/
@ResponseBody
@GetMapping("/register")
public String registerByParameter(String userId, String password) {
log.info("registerByParameter");
log.info("userId : " + userId + ", password : " + password);
// @ResponseBody가 없으면 /views/success.jsp를 반환
// @ResponseBody가 있으면 "success" 문자열 데이터를 반환
return "success";
}
}
URL에 register 뒤 데이터를 넣어주지 않아 null값이 뜨게 된다.
URL에 데이터를 넣어주면 잘 받아온다.
URL경로 상의 경로 변수로부터 요청 데이터를 취득
//URL경로 상의 경로 변수로부터 요청 데이터를 취득
/*
요청URI : /register/hongkd
경로 변수 : hongkd
요청방식 : get
*/
@ResponseBody
@GetMapping("/register/{userId}")
public String registerByPath(@PathVariable(value="userId") String userId) {
log.info("registerByPath");
log.info("userId : " + userId); // hongkd
return "success";
}
@PathVariavle의 value값과 경로상 {}안에 있는 변수명은 반드시 동일해야한다.
요청 데이터 처리 애너테이션
formHome.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!--
method 생략 시 get방식이 기본임
method="get"이 생략됨
-->
<form action="/board/register">
<input type="submit" value="register(GET)" />
</form>
<hr />
<!--
요청 URI : /board/register
요청 파라미터 :
요청 방식 : POST
-->
<form action="/board/register" method="POST">
<input type="submit" value="register(POST)" />
</form>
<hr />
<!--
요청URI : /board/modify
요청파라미터 :
요청방식 : get
-->
<form action="/board/modify">
<input type="submit" value="modify(GET)" />
</form>
<hr />
<!--
요청URI : /board/modify
요청파라미터 :
요청방식 : post
-->
<form action="/board/modify" method="post">
<input type="submit" value="modify(POST)" />
</form>
<hr />
<!--
요청URI : /register01
요청파라미터 : {userId=hongkd,password=1234,coin=100}
요청방식 : post
-->
<form action="/register01" method="post">
<p>userId : <input type="text" name="userId" value="hongkd"> </p>
<p>password : <input type="password" name="password" value="1234"> </p>
<p>coin : <input type="text" name="coin" value="100"> </p>
<p><input type="submit" value="register01"> </p>
</form>
전에 만들어두었던 jsp를 활용해서 작업을 해보도록 하자.
submit버튼을 누르면 각 input의 name을 키값으로 value에 들어있는 데이터들이 post방식으로 전송된다.
연결할 컨트롤러 메소드도 하나 만들어줘야한다.
/*
요청URI : /register01
요청파라미터 : {userId=hongkd,password=1234,coin=100}
요청방식 : post
HTML 폼 필드명과 컨트롤러 매개변수명이 일치하면
요청 데이터를 취득
HTML 폼 필드값이 숫자일 경우 컨트롤러 매개변수 타입이
문자열이면 그대로 문자열 형태로 요청 데이터를 취득
반면 매개변수 타입이 숫자형이면 숫자로 타입 변환됌
*/
@ResponseBody
@PostMapping("/register01")
public String register01(String userId, String password, int coin) {
log.info("userId : " + userId + ", password : " + password + ", coin : " + coin);
return "seccess";
}
register01 클릭
Date 타입 처리
스프링 MVC는 Date 타입의 데이터를 처리하는 여러 방법을 제공.
따로 지정하지 않으면 변환에 적합한 문자열 형식은 yyyy/MM/dd
우선 jsp에 Date타입의 input을 추가해주자.
<form action="/register01" method="post">
<p> userId : <input type="text" name="userId" value="hongkd"> </p>
<p> password : <input type="password" name="password" value="1234"> </p>
<p> coin : <input type="text" name="coin" value="100"> </p>
<p> regist Date : <input type="date" name="regDate" value=""> </p>
<p> <input type="submit" value="register01"> </p>
</form>
오류 예시 1)
/*
1) 쿼리 파라미터(dateOfBirth=1234)로 전달받은 값이
날짜 문자열 형식에 맞지 않아 Date 타입으로 변환 실패
요청URI : /registerByGet01?userId=hongkd&dateOfBirth=1234
요청파라미터 : userId=hongkd&dateOfBirth=1234
요청방식 : get
*/
// 오류 예시 1
@GetMapping("/registerByGet01")
public String registerByGet01(String userId,
Date dateOfBirth) {
log.info("userId" + userId);
log.info("dateOfBirth" + dateOfBirth);
return "success";
}
기본 형식과 맞지 않아 오류가 난다.
오류 예시 2)
/*
2) 쿼리 파라미터(dateOfBirth=2018-09-08)로 전달받은 값이
날짜 문자열 형식에 맞지 않아 Date 타입으로 변환 실패
요청URI : /registerByGet0102?userId=hongkd&dateOfBirth=2018-09-08
요청파라미터 : userId=hongkd&dateOfBirth=2018-09-08
요청방식 : get
*/
// 오류 예시 2
@GetMapping("/registerByGet0102")
public String registerByGet0102(String userId,
Date dateOfBirth) {
log.info("userId" + userId);
log.info("dateOfBirth" + dateOfBirth);
return "success";
}
성공 예시 1)
/*
4) 쿼리 파라미터(dateOfBirth=2018/09/08)로 전달받은 값이
날짜 문자열 형식에 맞아 Date 타입으로 변환 성공
따로 지정하지 않으면 변환에 적합한 날짜 문자열 형식은 yyyy/MM/dd이다.
요청URI : /registerByGet0104?userId=hongkd&dateOfBirth=2018/09/08
요청파라미터 : userId=hongkd&dateOfBirth=2018/09/08
요청방식 : get
*/
// 성공 예시
@GetMapping("/registerByGet0104")
public String registerByGet0104(String userId,
Date dateOfBirth) {
log.info("userId : " + userId);
log.info("dateOfBirth : " + dateOfBirth);
return "success";
}
파라미터 형식이 기본 형식과 일치하면 된다.
혹은
/* 6. DateTimeFormat 애너테이션
DateTimeFormat 애너테이션의 pattern 속성값에
원하는 날짜 형식을 지정할 수 있음
*/
/*요청URI : /registerByGet0105?userId=hongkd&dateOfBirth=1225
요청파라미터 : userId=hongkd&dateOfBirth=1225
요청방식 : get
*/
// 성공 예시
@GetMapping("/registerByGet0105")
public String registerByGet0105(String userId,
@DateTimeFormat(pattern="MMdd") Date dateOfBirth) {
log.info("userId : " + userId);
log.info("dateOfBirth : " + dateOfBirth);
return "success";
}
@DataTimeFormat()을 통해 파라미터값을 받아올 수 있다.
만약 dateOfBirth=1225 => 12월 25일로 표현하고싶다면
(pattern="MMdd")라고 표기하면 된다.
※ 월을 표기할땐 대문자로 표기해야한다. MM = 월, mm = 분
폼 방식 요청 처리
- 폼 텍스트 필드 요소값을 기본 데이터 타입인 문자열 타입 매개변수로 처리함
- 폼 텍스트 필드 요소 값을 자바빈즈 매개변수로 처리
- 폼 비밀번호 필드 요소값을 자바빈즈 매개변수로 처리 가능하다.
<form action="/registerUserId" method="post">
<p> userId : <input type="text" name="userId" /> </p>
<p> password : <input type="password" name="password" /> </p>
<p> gender : </p>
<p>
<!--
radio / checkbox => checked 속성
select => selected 속성
-->
<input type="radio" name="gender" id="gender1" value="male" checked />
<label for="gender1">Male</label><br />
<input type="radio" name="gender" id="gender2" value="female" />
<label for="gender2">Female</label><br />
<input type="radio" name="gender" id="gender3" value="other" />
<label for="gender3">Other</label><br />
</p>
<p> nationality :</p>
<p>
<select name="nationality">
<option value="Korea" selected>대한민국</option>
<option value="Germany" >독일</option>
<option value="Australia" >호주</option>
<option value="Canada" selected>캐나다</option>
</select>
</p>
<p> car :</p>
<p>
<!-- 문자열 배열 타입 매개변수로 처리 -->
<!-- 컨트롤러의 매개변수로 String cars -->
<select name="cars" multiple>
<option value="volvo" selected>Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
</p>
<p> car :</p>
<p>
<!-- 문자열 배열 타입 매개변수로 처리 -->
<!-- 컨트롤러의 매개변수로 String[] carArray -->
<select name="carArray" multiple>
<option value="volvo" selected>Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
</p>
<p> car :</p>
<p>
<!-- 문자열 배열 타입 매개변수로 처리 -->
<!-- 컨트롤러의 매개변수로 ArrayList<String> carList -->
<select name="carList" multiple>
<option value="volvo" selected>Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
</p>
<hr />
<!-- 컨트롤러 매개변수로써 String hobby -->
<p>hobby : </p>
<p>
<input type="checkbox" name="hobby" value="Sports">Sports<br />
<input type="checkbox" name="hobby" value="Music">Music<br />
<input type="checkbox" name="hobby" value="Movie">Movie<br />
</p>
<hr />
<!-- 컨트롤러 매개변수로써 String[] hobby -->
<p>hobbyArray : </p>
<p>
<input type="checkbox" name="hobbyArray" value="Sports">Sports<br />
<input type="checkbox" name="hobbyArray" value="Music">Music<br />
<input type="checkbox" name="hobbyArray" value="Movie">Movie<br />
</p>
<hr />
<!-- 컨트롤러 매개변수로써 List<String> hobbyListㅋ -->
<p>hobbyList : </p>
<p>
<input type="checkbox" name="hobbyList" value="Sports">Sports<br />
<input type="checkbox" name="hobbyList" value="Music">Music<br />
<input type="checkbox" name="hobbyList" value="Movie">Movie<br />
</p>
<hr />
<p>
<!-- 문자열 타입 매개변수로 처리 => String developer -->
developer : </p>
<p>
<input type="checkbox" name="developer" value="Y" />
</p>
<p>
<!-- 불리언 타입 매개변수로 처리 => boolean foreigner -->
<!-- value를 true로 초기화 해야 함 -->
foreigner : </p>
<p>
<input type="checkbox" name="foreigner" value="true" />
</p>
<hr />
<p>
postCode : <input type="text" name="postCode" />
<br />
location : <input type="text" name="location" />
</p>
<hr />
<!-- memberVO 안에 있는 address에 데이터 넣기 -->
<p>
postCode : <input type="text" name="address.postCode" />
<br />
location : <input type="text" name="address.location" />
</p>
<p> <input type="submit" value="registerUserId" /> </p>
controller
@ResponseBody
@PostMapping("/registerUserId")
public String registerUserId(String userId, String password
, String gender, String nationality, String cars
, String[] carArray, ArrayList<String> carList
,String hobbys, String[] hobbyArray
, ArrayList<String> hobbyList, String developer
, boolean foreigner, Address address
, Member member) {
log.info("registerUserId");
log.info("userId : " + userId);
log.info("password : " + password);
log.info("gender : " + gender);
log.info("nationality : " + nationality);
log.info("cars : " + cars);
log.info("hobbys : " + hobbys);
log.info("developer : " + developer);
log.info("foreigner : " + foreigner);
log.info("address : " + address);
log.info("member : " + member);
if(carArray != null) {
log.info("------------------");
for(String car : carArray) {
log.info("carArray[" + car + "]");
}
log.info("------------------");
}
if(hobbyArray != null) {
log.info("------------------");
for(String hobby : hobbyArray) {
log.info("hobbyArray[" + hobby + "]");
}
log.info("------------------");
}
// 얜 안됌ㅋㅋㅋㅋ
if(carList != null) {
log.info("------------------");
for(int i = 0; i<carList.size(); i++) {
log.info("carList[" + carList.get(i) + "]");
}
log.info("------------------");
}
// 얘도 안됌ㅋㅋㅋㅋㅋㅋㅋ
if(hobbyList != null) {
log.info("------------------");
for(int i = 0; i<hobbyList.size(); i++) {
log.info("hobbyList[" + hobbyList.get(i) + "]");
}
log.info("------------------");
}
return "success";
}
그리고 VO도 수정을 해줘야 하는데 조금 특이사항이 생겼다.
package kr.or.ddit.vo;
import java.util.ArrayList;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import lombok.Data;
@Data
public class Member {
private String userId;
private String userName = "hongkd";
private String password = "1234";
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date regDate;
private int coin;
private String gender;
private String nationality;
private String cars;
private String[] carArray;
private ArrayList<String> carList;
private String hobbys;
private String[] hobbyArray;
private ArrayList<String> hobbyList;
private String developer;
private boolean foreigner;
// 중첩된(nasted) 자바빈즈
// 많이 사용된다. 중요!
private Address address;
}
package kr.or.ddit.vo;
import lombok.Data;
@Data
public class Address {
private String postCode; // 우편 변호
private String location; // 주소
}
※ 마지막의 Address address는 본문 마지막에서 설명하겠음
Address라는 VO파일을 새로 만들어주고, Member파일을 위와 같이 수정해준다
왜인진 모르겠으나 carList와 hobbyList는 출력이 안되고 있다.
나머지들은 각 name에 맞게 데이터가 들어가고있다
중첩된(nested) 자바빈즈
※ 많이 사용된다. 중요!
package kr.or.ddit.vo;
import java.util.ArrayList;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import lombok.Data;
@Data
public class Member {
// 중첩된(nested) 자바빈즈
// 많이 사용된다. 중요!
private Address address;
}
package kr.or.ddit.vo;
import lombok.Data;
@Data
public class Address {
// Member 자바빈 클래스의 프로퍼티(식별자)
private String userId;
private String postCode; // 우편 변호
private String location; // 주소
}
<p>
postCode : <input type="text" name="postCode" />
<br />
location : <input type="text" name="location" />
</p>
<!-- Member 안에 있는 address에 데이터 넣기 -->
<p>
postCode : <input type="text" name="address.postCode" />
<br />
location : <input type="text" name="address.location" />
</p>
위 코드는 Address VO파일 안에 데이터를 직접 넣는 방식이고
아래 코드는 Member VO파일 안에 있는 Address address에 데이터를 넣는 방법이다.
중첩된 자바빈즈를 사용함으로써 회원 정보를 한 번에 담고 있는 Member 객체 안에 주소 정보를 포함시킬 수 있다.
이렇게 하면 주소 정보에 접근하기 위해 따로 객체를 생성하거나 참조할 필요가 없어지므로 코드가 간결해지고, 유지보수가 용이진다는 장점이 있다.