data bind
사용자가 String
으로 입력한 다양한 도메인타입의 데이터를 변환해주는 녀석
주로 WebMVC 에서 사용하지만 이전에 xml 파일의 데이터를 변환할때도 사용했음.
먼저.. 변환 대상인
Event class
package herdin.boot;
public class Event {
private Integer id;
private String title;
public Event(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Override
public String toString() {
return this.id + " : " + this.title;
}
}
PropertyEditorSupport 를 사용할 경우.
package herdin.boot;
import java.beans.PropertyEditorSupport;
/* Thread safe 하지 않다. 그래서 Bean 으로 등록하지말고
* Thread Scope 의 Bean 으로 사용 하던지, 아예 Bean 으로 등록하지 않도록 한다.
* 그리고 String, Objec 간의 변환만이 가능하여 Spring 3.0 이후로는
* interface Converter, Formatter 가 나왔다. */
public class EventEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(new Event(Integer.parseInt(text))); //이곳의 setValue
}
@Override
public String getAsText() {
Event event = (Event) getValue(); //이곳의 getValue 는 공유하는 value 가 있다.
return event.getId().toString();
}
}
음 Spring Legacy 에선
WebBindingInitializer
를 implements 하여 bean 으로 등록하여 사용하면 되는 것 같다. 안해봤음 찡긋.
package herdin.boot;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 EventController {
private Logger logger = LoggerFactory.getLogger(EventController.class);
/* Controller 에서 등록한 Binder 를 사용하여 변환한다. */
@InitBinder
public void init(WebDataBinder webDataBinder) {
webDataBinder.registerCustomEditor(Event.class, new EventEditor());
}
@GetMapping("/event/{event}")
public String getEvent(@PathVariable Event event) {
this.logger.debug(event.toString());
return event.getId().toString();
}
}
Converter 를 사용해보자
String <--> Event 객체를 변환해주는 class 들을
Converter<S, T>
를 implements 하여 만든다.
package herdin.boot;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.convert.converter.Converter;
public class EventConverter {
/* 상태가 없기때문에 Bean 으로 등록해도 무방함
* 하지만 등록해서 사용하는 방법이 있음.
*/
public static class StringToEventConverter implements Converter<String, Event> {
private static Logger logger = LoggerFactory.getLogger(StringToEventConverter.class);
@Override
public Event convert(String source) {
StringToEventConverter.logger.debug("SOURCE STRING {}", source);
return new Event(Integer.parseInt(source));
}
}
public static class EventToStringConverter implements Converter<Event, String> {
private static Logger logger = LoggerFactory.getLogger(EventToStringConverter.class);
@Override
public String convert(Event source) {
EventToStringConverter.logger.debug("EVENT OBJECT {}", source);
return source.getId().toString();
}
}
}
그리고 Spring Legacy 에서는
WebMvcConfigurer
를 implements 한 설정 class 에서 등록해준다. Spring Boot 에서는 자동으로 등록이 된다. 이렇게 사용하는 법만 알아도 되는걸까..
package herdin.boot;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new EventConverter.StringToEventConverter());
registry.addConverter(new EventConverter.EventToStringConverter());
}
}
아무튼 등록만하면
Controller
에서 자동형변환이 되게 된다.
Formatter 를 사용해보자.
package herdin.boot;
import java.text.ParseException;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.format.Formatter;
public class EventFormatter implements Formatter<Event> {
private Logger logger = LoggerFactory.getLogger(EventFormatter.class);
@Override
public String print(Event object, Locale locale) {
this.logger.debug(object.toString());
return object.getId().toString();
}
@Override
public Event parse(String text, Locale locale) throws ParseException {
this.logger.debug(text);
this.logger.debug(text);
return new Event(Integer.parseInt(text));
}
}
위에서 사용한 설정 class 에서 등록 method 만 변경해주면 된다. 이게 대체 뭔차이지..냐면
Formatter
는Locale
기반으로 사용할 수 있음.
package herdin.boot;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
// registry.addConverter(new EventConverter.StringToEventConverter());
// registry.addConverter(new EventConverter.EventToStringConverter());
registry.addFormatter(new EventFormatter());
}
}
위에서 등록한
Converter
나Formatter
들을 이용하여ConversionService
가 변환 작업을 한다. Spring Boot 에선 기본적으로 등록되는ConversionService
는WebConversionService
이고, Spring Legacy 에서 기본적으로 등록되는 것은DefaultFormattingConversionService
이다.
class WebConversionService/*1*/ extends DefaultFormattingConversionService/*2*/
class DefaultFormattingConversionService/*2*/ extends FormattingConversionService/*3*/
class FormattingConversionService/*3*/ extends GenericConversionService implements FormatterRegistry/*4*/, EmbeddedValueResolverAware
interface FormatterRegistry/*4*/ extends ConverterRegistry/*5*/
ConversionService.toString()
을 찍어보면 등록된 Converter 들을 볼 수 있다.
Last updated
Was this helpful?