Spring 실습

Spring 실습 8일차 (요청 처리)

choco2706 2024. 5. 1. 21:50

컨트롤러에 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값이 뜨게 된다.

 

요청 결과 (2)

 

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";
	}

 

formHome.jsp

 

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";
	}

 

파라미터 형식이 기본 형식과 일치하면 된다.

요청 URI
regist Date에 파라미터 값이 들어갔다.

 

혹은

/* 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에 맞게 데이터가 들어가고있다

 

넣은 데이터(1)
넣은 데이터
받아온 데이터들

 

중첩된(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 객체 안에 주소 정보를 포함시킬 수 있다.

이렇게 하면 주소 정보에 접근하기 위해 따로 객체를 생성하거나 참조할 필요가 없어지므로 코드가 간결해지고, 유지보수가 용이진다는 장점이 있다.