2.1 정보 보여주기
타코 식자재를 정의하기 위한 모델을 생성해보자.
@Data
@RequiredArgsConstructor
public class Ingredient {
private final String id;
private final String name;
private final Type type;
public static enum Type {
WRAP, PROTEIN, VEGGIES, CHEESE, SAUCE
}
}
식자재를 나타내는데 필요한 3개의 속성을 정의한다.
Ingredient 클래스에서 특이한 점은 final 속성들을 초기화하는 생성자는 물론이고
속성들의 getter 와 setter 메서드가 없다는 것과 equals(), hashCode(), toString() 등의
유용한 메서드도 정의하지 않았다는 것이다.
@Data 애노테이션을 지정하면 소스 코드에 누락된 final 속성들을 초기화하는 생성자는 물론이고,
속성들의 getter 와 setter 등을 생성하라고 Lombok에 알려준다.
Lombok 를 사용하여 코드량을 줄일 수 있다.
Lombok 주요 기능
어노테이션(Annotation)이란 자바 소스 코드에 추가하여 사용할 수 있는 메타데이터의 일종을 말한다.
롬복 어노테이션(Lombok Annotation)은 어노테이션 기반으로 코드를 자동완성 해주는 라이브러리이다.
롬복을 사용하면 getter/setter처럼 반복되는 메서드의 작성 코드를 줄임으로서 코드의 가독성을 높일 수 있다.
롬복 어노테이션 중, 많이 사용되는 어노테이션의 종류와 사용 방법을 알아보자.
@Getter/@Setter
특정 필드 위에서 어노테이션을 붙여주면, 자동으로 생성된 접근자와 설정자 메소드를 사용할 수 있다.
클래스 위에 붙여주는 경우에는 모든 필드에 접근자와 설정자가 자동으로 생성된다.
@NoArgsConstructor/@AllArgsConstructor/@RequiredArgsConstructor
생성자를 자동으로 생성해주는 어노테이션으로, @NoArgsConstructor 는 파라미터가 없는 기본 생성자를 생성한다.
@AllArgsConstructor는 필드 값을 모두 포함한 생성자를 생성해준다.
또, @RequiredArgsConstructor는 final필드와 @NonNull 어노테이션이 붙은 필드에 대한 생성자를 생성하여 특정 변수만을 활용하는 생성자를 생성해 준다.
@ToString
필드를 기반으로 ToString 메소드를 자동생성하며, 클래스명(필드1 이름 = 필드 1 값, 필드2 이름 = 필드 2값)으로 출력된다.
@ToString(exclude = “필드명”)을 사용하여 원하지 않는 필드는 제외할 수 있다.
@EqualsAndHashCode
Equals와 hashCode 메소드를 자동으로 생성해주며, callSuper를 사용해서 메소드 자동 생성 시
부모 클래스의 필드까지 고려할 것인지를 설정할 수 있다.
callSuper=true이면 부모 클래스 필드 값도 동일한지 고려하고, callSuper=false(기본값)로 설정하면
자신 클래스의 필드 값들만 고려한다.
@Data
@Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor를 한번에 생성해준다.
@Data, @ToString, @Setter 등의 기능은 성능 또는 객체 안정성 이슈로 인해 주의하여 사용해야한다.
@Slf4j
@Controller
@RequestMapping("/orders")
public class OrderController {
@GetMapping("/current")
public String orderForm(Model model) {
model.addAttribute("order", new Order());
return "orderForm";
}
@PostMapping
public String processOrder(@Valid Order order, Errors errors) {
if (errors.hasErrors()) {
return "orderForm";
}
log.info("Order submitted : " + order);
return "redirect:/designs";
}
}
@Controller
스프링이 해당 클래스를 찾은 후 컨텍스트의 bean 으로 이 클래스의 인스턴스를 자동 생성되게 한다.
@Slf4j
Slf4j Logger 생성한다.
아래랑 같은 효과다.
private static final org.slf4j.Logger log =
org.slf4j.LoggerFactory.getLogger(DesignTacoController.class);
스프링 MVC 요청-대응 어노테이션
스프링은 JSP, Thymeleaf, FreeMarker, Mustache, Groovy 기반 템플릿 등을 제공하여 뷰를 정의한다.
2.2 폼 제출 처리
@PostMapping
public String processDesign(@Valid Taco design, Errors errors) {
if (errors.hasErrors()) {
return "design";
}
// 타코 디자인(선택된 식자재 내역)을 저장한다…
log.info("### Processing design: " + design);
return "redirect:/orders/current"; // 현재 주문 페이지 orders/current 로 리다이렉트
}
2.3 유효성 검사하기
if-else 로 지저분하게 체크 하지 말고 Bean Validation API 쓰자.
spring boot 2.3 이상 부터는 spring-boot-starter-validation 라이브러리 추가 필요하다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
@Entity
public class User {
@NotBlank(message = "Name is mandatory")
private String name;
@NotBlank(message = "Email is mandatory")
private String email;
@CreditCardNumber(message = "Not a valid credit card number")
private String ccNumber;
@Pattern(regexp = "^0[1-9]|1[0-2]([\\/])([1-9][0-9])$", message = "Must be formatted MM/YY")
private String ccExpiration;
@Digits(integer = 3, fraction = 0, message = "Invalid CVV") // integer: 자릿수, fraction: 소수점자리수
private String ccCVV;
}
@NotNull, @NotEmpty, @NotBlank 차이점
1. String test = null;
@NotNull: false
@NotEmpty: false
@NotBlank: false
2. String test = "";
@NotNull: true
@NotEmpty: false
@NotBlank: false
3. String test = " ";
@NotNull: true
@NotEmpty: true
@NotBlank: false
4. String name = "Some text";
@NotNull: true
@NotEmpty: true
@NotBlank: true
스프링 MVC 예제
@PostMapping
public String processDesign(@Valid Taco design, Errors errors) {
if (errors.hasErrors()) {
return "design";
return "redirect:/orders/current";
}
RestController 예제
@RestController
public class UserController {
@PostMapping("/users")
ResponseEntity<String> addUser(@Valid @RequestBody User user) {
// persisting the user
return ResponseEntity.ok("User is valid");
}
}
2.4 뷰 컨트롤러로 작업하기
일반적인 패턴이다.
WebMvcConfigurer 를 통해 간단하게 처리도 가능하다.
@Configuration
class WebConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// WebMvcConfigurer 로 "/" 경로 요청 시 view 지정
registry.addViewController("/").setViewName("home");
}
}
요약
Thymeleaf / jsp 호환해서 사용하는 법
RestController messageconverter
Slf4j 원리