Skip to content

2022 01 23

Crow edited this page Jan 23, 2022 · 25 revisions

oher

Controller의 파라미터에서 이어짐
오류 디버깅 노트를 이렇게 위에 적어야 할지 아니면 오류가 발생한 곳에 적어야할지 고민임
하이퍼링크로 올리는거도 나쁘진 않아보임

ex02Bean 오류

ex02Bean의 http://localhost:8080/sample/ex02Bean?list[0].name=aaa&list[2].name=bbb 매핑을 사용해보면 HTTP Status 400 – Bad Request 오류가 야기됨
이유는 tomcat 버전에 따라서 '[]' 문자열을 사용하지 못하는대 톰캣 9.0버전도 사용 불가능함

해결방법은 '['문자는 %5B로 ']'문자는 %5D로 변경해서 사용하면됨
또 다른 방법으론 JavaScript를 이용하는 경우엔 encodeURIComponnt()와 같은 방법으로도 해결가능

여기서 궁금증이 생겨서 list[0]배열에 이름과 나이 모두를 입력해보려고 했음
http://localhost:8080/sample/ex02Bean?list%5B0%5D.name=aaa&age=26
뒤에 엔드로 age를 붙여봤지만 실패함
http://localhost:8080/sample/ex02Bean?list%5B0%5D.name=aaa&list%5B0%5D.age=26
이방식은 성공했지만 너무 매핑이 길어지는거 같아서 반절짜리 성공임
아마 더 좋은방식이 있어보임 그리고 []두개면 될 문자열이 %5B,%5D로 6개로 늘어나서 길어보이는거 뿐이지 충분히 사용 가능성 있어 보이는 매핑임

지금이 5시 17분이니 30분까지만 고민해보기로 하겠음
http://localhost:8080/sample/ex02Bean?list%5B0%5D.name=aaa&.age=33
이 매핑도 실패함 지금 든 생각인대 원래 배열도 배열명과주소값을 같이 적어야지 값이 들어가니까 아까 생각한 방식이 맞는 방식 같음 물론 더 좋은방법이 있을수도 있지만 지금은 이렇게 결론을 내겠음 http://localhost:8080/sample/ex02Bean?list%5B0%5D.name=aaa&list%5B0%5D.age=26
배열방을 두번 호출하고 다른 요소에 각각 값을 넣어주는방식

java.util.Date와 java.sql.Date의 차이

큰 관점에선 sql패키지의 date는 util패키지를 상속받아서 사용하지만
toString으로 세부적으로 보면 sql의 date는 시/분/초에 대한 내용이 없다.

SimpleDateFormat 형식 오류

@InitBinder 내용중 발생
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 라고 선언해야할것을 패턴쪽에서 ("yyyy-mm-dd);라고 선언해서 년도 4자리 분2자리 일 2자리로 출력됨..
달을 2자리로 표시할땐 대문자 MM으로 표시해야함

객체 리스트

만일 전달하는 데이터가 SampleDTO와 같이 객체타입이고 여러 개를 처리해야 한다면
약간의 작업을 통해서 한 번에 처리를 할 수 있음
예를 들어 SampleDTO를 여러 개 전달받아 처리하고 싶다면 SampleDTO의 리스트를 포함하는 SampleDTOList 클래스를 설계함
(처음 설계할때 그냥 DTO를 사용할지 DTOList를 사용할지 제대로 판단할줄 알아야할꺼 같음)

SampleDTOList 클래스

private로 List를 만드는대 이때 매개변수로는 SampleDTO 클래스를 이용함
또한 public으로 SampleDTOList() 메서드를 만들어서 private List를 사용하게 하는거 같음 생각해보면 당연한 구조같음 DTO는 data transfer object니까 해당 인터페이스 or 클래스
는 변하지 않아야함 하지만 호출을 받은 클래스는 값이 변해도 상관없음
이게 맞는이해인지는 모르겠지만 우리가 원본 파일을 수정하는게 아닌 사본 파일을 수정해서
사용하는것과 같음

@InitBinder

파라미터 수집을 다른용어로는 'binding(바인딩)'이라고함
변환이 가능한 데이터는 자동으로 변환되지만 경우에 따라서는 파라미터를 변환해서 처리해야함
예를 들어 화면에 '2022-01-23'과 같이 문자열로 전달된 데이터를 java.util.Date 타입으로
변환하는 작업이 그러함

스프링 Controller에서는 파라미터를 바인딩할 때 자동으로 호출되는 @InitBinder를 이용해서
이러한 변환을 처리할 수 있음
com.crow.domain 패키지에 TodoDTO라는 클래스를 작성

TodoDTO 클래스

private 변수로 String형의 title과 Date형의 dueDate를 선언해줌
여기서 Date는 java.util.Date타입을 사용함
만일 사용자가 2022-01-23 과 같이 들어오는 데이터를 변환하고자 하면 문제가 발생함
이걸 해결하기 위해서 사용하는 간단한 해결책이 @InitBinder임

SampleController 클래스

public 형식의 void initBinder 메서드를 선언해줌 매개변수는 WebDataBinder타입으로
메서드에 @InitBinder어노테이션선언
SimpleDateFormat을 이용해 "yyyy-mm-dd"포맷생성 WebDataBinder를 이용해서 커스텀에디터 등록(java.util.Date.class를 대상으로
새로운 커스텀 데이트에디터를 만들어줌 이때 데이터 포맷은 아까 SimpleDateFormat으로 만든포맷이용
false를 선택해서 null값은 불가능으로 만들어줌

만일 브라우저에서 'http://localhost:8080/sample/ex03?title=crow&dueDate=2022-01-23'
과 같이 호출했다면 서버에서는 정상적으로 파라미터를 수집해서 처리함

반면에 @InitBinder 처리가 되지 않는다면 브라우저에서는 400 에러가 발생하는 것을 볼 수있음
(400에러는 요청 구문(syntax)이 잘못되었다는 의미임)
날짜가 정상적으로 처리되어도 아직 jsp 페이지는 없으므로 404에러는 발생함

@DateTimeFormat

@InitBinder를 이용해서 날짜를 변환할 수도 있지만, 파라미터로 사용되는 인스턴스 변수에
@DateTimeFormat을 적용해도 변환이 가능함
@DateTimeFormat을 이용할 경우에는 @InitBinder는 필요하지 않음

TodoDTO 클래스

기존내용에서 dueDate위에 @DateFormat(pattern = "yyyy/MM/dd") 어노테이션 추가
두개를 중복 사용시 InitBinder를 우선하는거 같음 @DateFormat으로 url을 넘길시 400에러가 나옴

EC2

서버설정
서버 리부팅

Controller 테스트 구현

MockMvc

코드로 배우는 스프링 웹 프로젝트 공부

코드로 배우는 스프링부트 웹 프로젝트 공부

Clone this wiki locally