JAVA/spring

[1028 FORM 백기선 스프링프레임워크 핵심기술] Validation, 데이터 바인딩.

import static 단축키 

1.  settings > Editor > General > Auto Import

Add unambiguous imports on the fly 

Optimize imports on the fly (for current project)

두개 체크 후 저장

2. 

그리고 status() 뒤  alt + enter 로사용. **() 뒤에서 알트엔터

출처 :hjjungdev.tistory.com/102


스프링목차

스프링 validator org.springframework.validation.Validator;

객체 검증 인터페이스. 
- supports : 검증할수 있는 클래스인지 확인. 
public boolean supports(Class<?> clazz){
    return Event.class.equals(clazz);
}
- validate
public void validate(Object target Errors errors){
    ValidationUtils.rejectIfEmptyOrWhitespace(error, "분별 키","공통 키값", "없을때 메시지 ");
    Event event = (Event)target;
    if(event.getTitle()==null){
         errors.reject("필드", "메시지");...
     }
}

--소스
eventValidator.validate(event, errors);
event.hasErros()
error.getAllErrors().forEach(e->{ Arrays.stream(e.getCodes()).forEach(System.out::println)})
- 스프링부트 2.0.5 이상 스프링 LocalValidatorFactoryBean 자동등록.   - 
@Validator validator;
빈에 추가. 
@NotNull @Min(0) @Size(min=0) @NotEmpty(message = "{email.notempty}")
>> 기본메시지가 출력.  
Bean Validation javax.xml.validation.Validator;
JAVA EE 기능.
beanvalidation.org/
데이터 바인딩 프로퍼티 값을 타겟 객체에 설정하는 기능
사용자 관점 : 사용자 입력값을 애플리케이션 도메인 모델에 동적으로 변환해 넣어주는 기능
해석하자면, 입력값은 대부분 문자열, 그값을 객체가 가지고 있는 타입으로 변환해서 넣어주는 기능. 
PropertyEditor 스프링 3.0 이전까지 DataBinder가 변환 작업 사용하는 인터페이스. 
쓰레드 세이프하지 않음. -상태정보 저장하고 있음, 빈으로 등록해서.. 쓰면... 안됨. 
Object String 간의 변환만 할수 있어 사용범위가 제한적임
public class EventPropertyEditor extends PropertyEditorSupport {
>> 후에 Converter 사용. 
Converter S 타입을 T 타입으로 변환할 수 있는 매우 일반적인 변환기.
상태 정보 없음 == Stateless == 쓰레드세이프
ConverterRegistry에 등록해서 사용
@Component
public class StringToEventConverter implements Converter<String, Event> {
    @Override
    public Event convert(String source) {
        Event event = new Event();
        event.setId(Integer.parseInt(source));
        return event; }
}

public class WebConfig implements WebMvcConfigurer {  >>빈 등록시 부트는 등록안해도됨
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new StringToEventConverter());
    }
}
기본적인것은 자동변환..해줌. 
 Formatter PropertyEditor 대체제
Object와 String 간의 변환을 담당한다.
문자열을 Locale에 따라 다국화하는 기능도 제공한다. (optional)
FormatterRegistry에 등록해서 사용
@Component
public class EventFormatter implements Formatter<Event> {
    @Autowired
    MessageSource messagesource;                                  >> bean 등록 가능. 

    @Override
    public Event parse(String text, Locale locale) throws ParseException {
        Event event = new Event();
        int id = Integer.parseInt(text);
        event.setId(id); return event;
    }
    @Override
    public String print(Event object, Locale locale) {
        return object.getId().toString();
    }
}

public class WebConfig implements WebMvcConfigurer {>>빈 등록시 부트는 등록안해도됨
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatter(new EventFomatter());
    }
}
ConversionService 실제 변환 작업은 이 인터페이스를 통해서 쓰레드-세이프하게 사용할 수 있음.
스프링 MVC, 빈 (value) 설정, SpEL에서 사용한다.
 Default
Formatting
ConversionService
; FormatterRegistry,ConversionService상속. 
- FormatterRegistry(포멧터등록) <-  컨퍼터 ConverterRegistry(컨버터등록) 상속. 

- 여러 기본 컴버터와 포매터 등록 해 줌.
JPA 엔티티에 컨버터가 들어있음. 들어있는
컨버터 전부 보는방법. ConversionService  출력 
스프링 부트 - 웹 애플리케이션인 경우에 DefaultFormattingConversionSerivce를 상속하여 만든
WebConversionService를 빈으로 등록해 준다.
- Formatter와 Converter 빈을 찾아 자동으로 등록해 준다.

 

PropertyEditor

더보기
package com.example.demo;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@ExtendWith(SpringExtension.class)
@WebMvcTest
class DemoControllerTest {
    @Autowired
    MockMvc mockMvc;

    @Test
    void getTest() throws Exception {
        mockMvc.perform(get("/event/1"))
                .andExpect(status().isOk())
                .andExpect(content().string("1"));

    }
}

 

package com.example.demo;

import com.example.demo.event.Event;
import com.example.demo.event.EventEditor;
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.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

    @InitBinder
    public void init(WebDataBinder webDataBinder){
        webDataBinder.registerCustomEditor(Event.class, new EventEditor());
    }

    @GetMapping("/event/{event}")
    public String getEvent(@PathVariable Event event){
        System.out.println(event);
        return event.getId().toString();
    }


}
package com.example.demo.event;

public class Event {
    private Integer id;

    public Event(Integer id) {
        this.id = id;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
}
package com.example.demo.event;

import java.beans.PropertyEditorSupport;

public class EventEditor extends PropertyEditorSupport {
    @Override
    public String getAsText() {
        Event evnet = (Event)getValue();
        return evnet.getId().toString();
    }

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        setValue(new Event(Integer.parseInt(text)));

    }
}