목록전체 글 (33)
참새의 이야기
Bean Validation FieldError 검증을 위해 자바에서 제공하는 애노테이션이 있다. @NotBlank : 빈 값 혹은 공백만 있는 경우를 허용하지 않는다. @NotNull : null을 허용하지 않는다. @Range(min = 1, max = 100) : 값의 범위를 제한. @Max(100), @Min(1) : 최대 혹은 최소 값을 제한. 이는 적절한 라이브러리(spring-boot-starter-validation)만 넣어주면 스프링 부트가 자동으로 Bean Validator를 인지하고 스프링에 통합한다. 검증 순서 @ModelAttribute 애노테이션이 있다면 각각의 필드에 맞게 형 변환을 시도한다. 성공한 경우 validator를 적용하고, 실패한 경우에는 FieldError 추가한..
HTTP request가 항상 정상이라는 보장은 없다. 요구하는 스펙에 맞지 않는 값이 들어오는 경우를 처리하기 위해 검증을 해야 한다. 클라이언트 검증은 조작이 가능하기 때문에 취약하다. 그렇다고 서버 검증만을 활용하면 고객 사용성이 부족하다. 따라서 둘을 적절히 섞어 사용하는 것이 중요하다. 검증 직접 처리 Map을 이용해서 검증 오류를 직접 처리하는 것부터 시작해 보자. 유효하지 않은 값이 들어오면, 서버는 어떤 값에 어떤 문제가 있는지에 대한 설명을 Map인 errors에 담아 반환한다. @PostMapping("/add") public String addItem(@ModelAttribute Item item, RedirectAttributes redirectAttributes, Model mod..
메시지 기획자가 어느 날 문득 화면의 문구가 마음에 들지 않는다며 상품명 을 모두 상품 이름으로 바꿔 달라고 하는 일이 발생했다고 가정하자. HTML의 label의 문구를 하나하나 바꿔야 한다. 작은 서비스라면 금방 바꿀 수 있겠지만 서비스의 규모가 커지면 오랜 시간이 걸리는 작업이 될 것이다. 작은 서비스라도 실수로 몇 개 빠뜨리는 일이 생길 수도 있다. 이런 일을 방지하기 위해 메시지라는 기능이 있다. 우선, messages.properties라는 파일을 만든다. 해당 파일에는 아래와 같이 메시지를 저장한다. label.item=상품 label.item.id=상품 ID label.item.itemName=상품명 label.item.price=가격 label.item.quantity=수량 템플릿에서는 ..
스프링 통합과 폼 입력 폼 처리 public class Item { private Long id; private String itemName; private Integer price; private Integer quantity; } 위와 같은 Item 객체가 있다고 하자. Form을 통해 입력받으려면 HTML이 꽤나 난잡해질 것 같다. 이를 th:object와 th:field로 개선해보자. 상품명 가격 수량 우선, th:object 를 이용해 form 태그 내에서 사용할 객체를 지정할 수 있다. 위의 예시에서는 “item”을 객체로 설정했다. 우리가 입력받으려는 item은 itemName, price, quantity과 같은 멤버 변수를 가진다. 이때 th:field 속성을 이용하면 id, name, ..
타임리프는 스프링과의 자연스러운 통합을 지원하는 템플릿 엔진이다. 이번 글에서는 기본적인 사용법을 알아보고, 이후 Form을 만들 때 필요한 기능까지 알아보려 한다. 기본 기능 텍스트 타임리프에서 텍스트를 출력하는 방법으로는 크게 두 가지가 있다. 첫 번째는 th:text 를 사용하는 방법이다. HTML 태그의 속성으로 추가하면 된다. 아래는 사용 예시이다. HTML 태그가 아닌 문서의 영역에서 출력하고 싶다면 아래와 같이 활용할 수 있다. [[${data}]] 컨트롤러에서는 model.addAttribute("data", "this is data"); 와 같이 넘겨주면 된다. escape HTML에서 사용하는 특수문자가 있다. 같은 경우는 태그로 활용된다. 이런 문자가 텍스트에 포함되어 있다면 개발자의..
Redirect를 할 때 데이터를 넘겨야 하는 경우가 있다. 지금까지는 Model에 담아 넘겼지만, 이보다 redirect 상황에 어울리는 방식이 바로 RedirectAttributes이다. @PostMapping("/add") public String addItemV6(Item item, RedirectAttributes redirectAttributes) { Item savedItem = itemRepository.save(item); redirectAttributes.addAttribute("itemId", 1); redirectAttributes.addAttribute("status", true); return "redirect:/basic/items/{itemId}"; } redirectAttr..
HTTP 메시지 컨버터는 언제 사용하는가 HTML 같은 뷰 템플릿을 생성해서 response 하는 것이 아니라 JSON 형식의 데이터를 처리하는 경우에는 HTTP 메시지 컨버터를 사용한다. 좀 더 간단하게는 아래와 같은 경우로 정리할 수 있다. HTTP request: @RequestBody, HttpEntity(RequestEntity) HTTP response: @ResponseBody, HttpEntity(ResponseEntity) 동작 원리 HTTP request request가 오면 메시지 컨버터의 canRead() 메서드를 호출한다. canRead() 메서드가 읽을 수 있다고 판단한다면 read() 메서드를 호출하여 처리한다. canRead() 메서드가 읽을 수 없다고 판단한 경우에는 다음 ..
스프링 MVC Response HTTP 응답 - ResponseEntity 강의를 들으면서 가장 생소했던 부분이었다. 응답할 내용을 ResponseEntity에 담아서 반환한다. 이는 HTTP 메시지 컨버터를 통해서 JSON 형식으로 변환되어 반환된다. @GetMapping("/response-body-json-v1") public ResponseEntity responseBodyJsonV1() { HelloData helloData = new HelloData(); helloData.setUsername("userA"); helloData.setAge(20); return new ResponseEntity(helloData, HttpStatus.OK); } @ResponseStatus(HttpStatu..