카테고리 없음

Spring Array List Mapping / @InitBinder

Handy Smurf 2020. 8. 25. 12:04
package org.zerock.domain;

import java.util.ArrayList;
import java.util.List;

import lombok.Data;

@Data
public class SampleDTOList {
	private List<SampleDTO> list;
	
	public SampleDTOList() {
		list = new ArrayList<>();
	}
}
​
8월 25, 2020 10:38:41 오전 org.apache.coyote.AbstractProtocol start
정보: 프로토콜 핸들러 ["http-nio-1234"]을(를) 시작합니다.
8월 25, 2020 10:38:41 오전 org.apache.catalina.startup.Catalina start
정보: 서버가 [2,353] 밀리초 내에 시작되었습니다.
INFO : org.zerock.controller.HomeController - Welcome home! The client locale is ko_KR.
WARN : org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Failed to bind request element: org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.util.Date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.web.bind.annotation.RequestParam java.util.Date] for value '2020-10-10'; nested exception is java.lang.IllegalArgumentException
​
	// 134 page
	@GetMapping("/ex02Bean")
	public String ex02Bean(SampleDTOList list) {
		log.info("list dtos: " + list);
		
		return "ex02Bean";
	}
}

http://localhost:1234/sample/ex02 Bean? list%5B0% 5D.name=aaa&list%5B1%5d.name=bbb&list%5B2%5D.name=ccc

8월 25, 2020 10:19:19 오전 org.apache.coyote.AbstractProtocol start
정보: 프로토콜 핸들러 ["http-nio-1234"]을(를) 시작합니다.
8월 25, 2020 10:19:19 오전 org.apache.catalina.startup.Catalina start
정보: 서버가 [2,340] 밀리초 내에 시작되었습니다.
INFO : org.zerock.controller.HomeController - Welcome home! The client locale is ko_KR.
INFO : org.zerock.controller.SampleController - list dtos: SampleDTOList(list=[SampleDTO(name=aaa, age=0), SampleDTO(name=bbb, age=0), SampleDTO(name=ccc, age=0)])

 

 

<a id="my-link" href="#">
/sample/ex02Bean?list[0].name=aaa&list[1].name=bbb&list[2].name=ccc</a>

<script>
var url = document.getElementById("my-link").innerHTML;
var encoded = encodeURI(url.trim());
document.getElementById("my-link").href = encoded;
</script>

url을 encodeURI로 변경 

 

	@RequestMapping("m")
	public void method13(@RequestParam("date") Date date) {
		log.info("m method");
		log.info(date);
	}

http://localhost:1234/arg/m?date=2020-10-10

 

	@RequestMapping("m")
	public void method13(@RequestParam("date") Date date) {
		log.info("m method");
		log.info(date);
	}
	
	@InitBinder //먼저 실행한다. 특별한 타입을 변환해주는 edit를 넣어준다/
	public void initBinder(WebDataBinder binder) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		binder.registerCustomEditor(Date.class, new CustomDateEditor(format, false)); //어떤 타입으로 데이터를 변경해야하면 propertyEditor를 사용
																					 // boolean 타입은 긴타입을 넣느ㅑ 아니냐 
	
	}

http://localhost:1234/arg/m?date=2020-10-10

8월 25, 2020 10:45:52 오전 org.apache.coyote.AbstractProtocol start
정보: 프로토콜 핸들러 ["http-nio-1234"]을(를) 시작합니다.
8월 25, 2020 10:45:52 오전 org.apache.catalina.startup.Catalina start
정보: 서버가 [2,317] 밀리초 내에 시작되었습니다.
INFO : org.zerock.controller.HomeController - Welcome home! The client locale is ko_KR.
INFO : org.zerock.controller.ArgumentController - m method
INFO : org.zerock.controller.ArgumentController - Sat Oct 10 00:00:00 KST 2020

@InitBinder

파리미터의 수집을 다른 용어로는 binding이라고 한다. 변환이 가능한 데이터는 자동으로 변환되지만 경우에 따라서는 파라미터를 변환해서 처리해야 하는 경우도 존재한다. 

 

화면에서 2018-01-01과 같이 문자열로 전달된 데이터를 java.util.Date 타입으로 변환하는 작업이 그렇다.

스프링 Controller에서는 파라미터를 바인딩할 때 자동으로 호출되는 @InitBinder를 이용해서 이러한 변환을 처리할 수 있다.

 

 

 

	@InitBinder //먼저 실행한다. 특별한 타입을 변환해주는 edit를 넣어준다/
	public void initBinder(WebDataBinder binder) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		binder.registerCustomEditor(Date.class, new CustomDateEditor(format, false)); //어떤 타입으로 데이터를 변경해야하면 propertyEditor를 사용
	}
	

	//136, 137page 
	@GetMapping("/ex03")
	public String ex03(TodoDTO todo) {
		
		log.info("todo : " + todo);
		return "ex03";
	}

 

http://localhost:1234/sample/ex03?title=test&dueDate=2019-02-09

8월 25, 2020 11:15:52 오전 org.apache.coyote.AbstractProtocol start
정보: 프로토콜 핸들러 ["http-nio-1234"]을(를) 시작합니다.
8월 25, 2020 11:15:52 오전 org.apache.catalina.startup.Catalina start
정보: 서버가 [2,338] 밀리초 내에 시작되었습니다.
INFO : org.zerock.controller.HomeController - Welcome home! The client locale is ko_KR.
INFO : org.zerock.controller.SampleController - todo : TodoDTO(title=test, dueDate=Sat Feb 09 00:00:00 KST 2019)

 

 

총 정리

package org.zerock.controller;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;

import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.zerock.domain.SampleDTO;
import org.zerock.domain.SampleDTOList;
import org.zerock.domain.TodoDTO;

import lombok.extern.log4j.Log4j;

@Controller
@RequestMapping("/sample/*")
@Log4j
public class SampleController {
	@RequestMapping("")
	public void basic() {
		log.info("basic...................");
	}
	
	@RequestMapping(value="/basic", method = {RequestMethod.GET, RequestMethod.POST})
	public void basicGet() {
		log.info("basic get.............");
	}
	
	@GetMapping("/basicOnlyGet")
	public void basicGet2() {
		log.info("basic get only get ..................");
	}
	
	// 131 page
	@GetMapping("/ex02")
	public String ex02(@RequestParam("name") String name, 
			@RequestParam("age") int age) {
		log.info("name:" + name);
		log.info("age:" + age);
		
		return "ex02";
		
	}
	
	// 130 page
	@GetMapping("/ex01")
	public String ex01(SampleDTO dto) {
		log.info("" + dto);
		return "ex01";
	}
	
	// 132 page
	@GetMapping("/ex02List")
	public String ex02List(@RequestParam("ids") ArrayList<String> ids) {
		log.info("ids: " + ids);
		
		return "ex02List";
	}
	// 133 page
	@GetMapping("/ex02Array")
	public String ex02Array(@RequestParam("ids") String[] ids) {
		log.info("array ids: " + Arrays.toString(ids));
		return "ex02Array";
	}
	
	// 134 page
	@GetMapping("/ex02Bean")
	public String ex02Bean(SampleDTOList list) {
		log.info("list dtos: " + list);
		
		return "ex02Bean";
	
	
	}
	@InitBinder //먼저 실행한다. 특별한 타입을 변환해주는 edit를 넣어준다/
	public void initBinder(WebDataBinder binder) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		binder.registerCustomEditor(Date.class, new CustomDateEditor(format, false)); //어떤 타입으로 데이터를 변경해야하면 propertyEditor를 사용
	}
	

	//136, 137page 
	@GetMapping("/ex03")
	public String ex03(TodoDTO todo) {
		
		log.info("todo : " + todo);
		return "ex03";
	}

}








package org.zerock.controller;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.zerock.domain.Member;
import org.zerock.domain.MemberList;

import lombok.extern.log4j.Log4j;

@Controller
@RequestMapping("/arg/*")
@Log4j
public class ArgumentController {
	
	// /arg/a?name=john
	@RequestMapping("/a")
	public void method1(HttpServletRequest req) {
		log.info(req);
		log.info(req.getParameter("name"));
	}
	
	@RequestMapping("/b")
	public void method2(@RequestParam("name") String name) {
		log.info("b method");
		log.info(name);
	}
	
	@RequestMapping("/c")
	public void method3(@RequestParam String name) {
		log.info("c method");
		log.info(name);
	}
	
	@RequestMapping("/d")
	public void method4(String name) {
		log.info("d method");
		log.info(name);
	}
	
	// /e?name=jane&age=100
	@RequestMapping("/e")
	public void method5(HttpServletRequest req) {
		log.info("e method");
		log.info(req.getParameter("name"));
		log.info(req.getParameter("age"));
	}
	
	@RequestMapping("/f")
	public void method6(String name, String age) {
		log.info("f method");
		log.info(name);
		log.info(age);
		
		int ageInt = Integer.valueOf(age);
	}
	
	@RequestMapping("/g")
	public void method7(String name, int age) {
		log.info("g method");
		log.info(name);
		log.info(age);
	}
	
	@RequestMapping("/h")
	public void method8(String name, int age) {
		log.info("h method");
		
		Member member = new Member();
		member.setName(name);
		member.setAge(age);
		
		log.info(member);
	}
	
	@RequestMapping("/i")
	public void method9(Member member) {
		log.info("i method");
		log.info(member);
	}
	
	@RequestMapping("/j")
	public void method10(@RequestParam String[] name) {
		log.info("j method");
		log.info(name.length);
		for (String n : name) {
			log.info(n);
		}
	}
	
	@RequestMapping("/k")
	public void method11(@RequestParam("n") List<String> name) {
		log.info("k method");
		log.info(name.size());
		for (String n : name) {
			log.info(n);
		}
	}
	
	@RequestMapping("/l")
	public void method12(MemberList member) {
		log.info("l method");
		log.info(member);
		
	}
	
	@RequestMapping("m")
	public void method13(@RequestParam("date") Date date) {
		log.info("m method");
		log.info(date);
		
		
	}
	
	@RequestMapping("/n")
	public void method14(@RequestParam("mem") Member member) {
		log.info("n method");
		log.info(member);
	}
	
	@InitBinder //먼저 실행한다. 특별한 타입을 변환해주는 edit를 넣어준다/
	public void initBinder(WebDataBinder binder) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		binder.registerCustomEditor(Date.class, new CustomDateEditor(format, false)); //어떤 타입으로 데이터를 변경해야하면 propertyEditor를 사용
																					 // boolean 타입은 긴타입을 넣느ㅑ 아니냐 
	
	}


}













package org.zerock.domain;

import lombok.Data;

@Data
public class Member {
	private String name;
	private int age;
}
package org.zerock.domain;

import java.util.ArrayList;
import java.util.List;

import lombok.Data;

@Data
public class MemberList {
	private List<Member> list;
	
	public MemberList() {
		list = new ArrayList<>();
	}
}
package org.zerock.domain;

import lombok.Data;

@Data
public class SampleDTO {
	private String name;
	private int age;
}
package org.zerock.domain;

import java.util.Date;

import org.springframework.format.annotation.DateTimeFormat;

import lombok.Data;

@Data
public class TodoDTO {

  private String title;
  private Date dueDate;
}