source

스프링 MVC 유형 변환: PropertyEditor 또는 Converter?

factcode 2022. 11. 26. 13:54
반응형

스프링 MVC 유형 변환: PropertyEditor 또는 Converter?

봄 MVC에서 데이터를 가장 쉽고 간단하게 바인드하고 변환할 수 있는 방법을 찾고 있습니다.가능한 경우 xml 설정을 하지 않습니다.

지금까지 PropertyEditor를 다음과 같이 사용하고 있습니다.

public class CategoryEditor extends PropertyEditorSupport {

    // Converts a String to a Category (when submitting form)
    @Override
    public void setAsText(String text) {
        Category c = new Category(text);
        this.setValue(c);
    }

    // Converts a Category to a String (when displaying form)
    @Override
    public String getAsText() {
        Category c = (Category) this.getValue();
        return c.getName();
    }

}

그리고.

...
public class MyController {

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Category.class, new CategoryEditor());
    }

    ...

}

단순합니다. 두 변환 모두 같은 클래스에 정의되며 바인딩은 간단합니다.모든 컨트롤러에서 일반 바인딩을 수행할 경우 xml 설정에 3줄을 추가할 수 있습니다.


그러나 Spring 3.x에서는 Converters를 사용한 새로운 방법이 도입되었습니다.

스프링 컨테이너 내에서 이 시스템은 PropertyEditor의 대안으로 사용할 수 있습니다.

Converters가 "최신 대안"이기 때문에 Converters를 사용하려고 합니다.2개의 컨버터를 작성해야 합니다.

public class StringToCategory implements Converter<String, Category> {

    @Override
    public Category convert(String source) {
        Category c = new Category(source);
        return c;
    }

}

public class CategoryToString implements Converter<Category, String> {

    @Override
    public String convert(Category source) {
        return source.getName();
    }

}

번째 단점: 나는 두 개의 수업을 만들어야 한다.장점 : 범용성 덕분에 캐스팅할 필요가 없습니다.

그럼 어떻게 하면 간단하게 변환기를 바인드 할 수 있을까요?

번째 단점: 컨트롤러에서 실행할 수 있는 간단한 방법(주석 또는 기타 프로그래밍 기능)을 찾지 못했습니다.someSpringObject.registerCustomConverter(...);.

제가 찾은 유일한 방법은 지루하고 단순하지 않으며 일반적인 크로스 컨트롤러 바인딩에 대해서만 찾을 수 있습니다.

  • XML 구성:

    <bean id="conversionService"
      class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="somepackage.StringToCategory"/>
                <bean class="somepackage.CategoryToString"/>
            </set>
        </property>
    </bean>
    
  • Java 설정(Spring 3.1+만):

    @EnableWebMvc
    @Configuration
    public class WebConfig extends WebMvcConfigurerAdapter {
    
        @Override
        protected void addFormatters(FormatterRegistry registry) {
            registry.addConverter(new StringToCategory());
            registry.addConverter(new CategoryToString());
        }
    
    }
    

이러한 모든 단점이 있지만 왜 Converters를 사용합니까?내가 뭘 빼놓았나요?내가 모르는 다른 속임수들이 있나요?

PropertyEditors를 계속 사용하고 싶습니다.바인딩이 훨씬 쉽고 빠릅니다.

이러한 모든 단점이 있지만 왜 Converters를 사용합니까?내가 뭘 빼놓았나요?내가 모르는 다른 속임수들이 있나요?

아니요, PropertyEditor와 Converter를 모두 매우 포괄적으로 설명하셨다고 생각합니다.각각의 선언 및 등록 방법에 대해 설명합니다.

PropertyEditor는 범위가 한정되어 있습니다.String을 유형으로 변환하는데 도움이 됩니다.이 문자열은 일반적으로 UI에서 유래합니다.따라서 @InitBinder를 사용하여 WebDataBinder를 사용하여 PropertyEditor를 등록하는 것은 의미가 있습니다.

반면 Converter는 더 일반적이며 UI 관련 변환(String to target type)뿐만 아니라 시스템 내 모든 변환에 사용됩니다.예를 들어, Spring Integration은 메시지 payload를 원하는 유형으로 변환하기 위해 컨버터를 광범위하게 사용합니다.

UI 관련 흐름의 경우 PropertyEditor는 특히 특정 명령 속성에 대해 커스텀을 수행해야 하는 경우에 적합합니다.다른 경우에는 Spring 레퍼런스에서 추천을 받아 대신 변환기를 작성합니다(예: Long id에서 엔티티로 변환합니다).

  1. 문자열 변환의 경우 포맷터를 사용합니다(implement org.springframework).변환기 대신 format.Formatter)를 사용합니다.print(...) 메서드와 parse(...) 메서드가 있기 때문에 2개의 클래스가 아닌 1개의 클래스만 필요합니다.이들을 등록하려면 Conversion Service Factory Bean 대신 Formating Conversion Service Factory Bean을 사용합니다.Formating Conversion Service Factory Bean은 변환기와 포맷터를 모두 등록할 수 있습니다.
  2. 새로운 포메터 제품에는 몇 가지 추가적인 이점이 있습니다.
    • 포메터 인터페이스는 local 객체를 print(...) 메서드와 parse(...) 메서드로 제공하므로 문자열 변환은 로케일에 의존할 수 있습니다.
    • FormatingConversionServiceFactoryBean에는 미리 등록된 포메터 외에 주석을 통해 추가 포맷 파라미터를 지정할 수 있는 몇 가지 편리한 사전 등록된 AnnotationFormatterFactory 객체가 포함되어 있습니다.예: @RequestParam @DateTimeFormat(pattern=")MM-dd-yy") LocalDate baseDate...AnnotationFormatterFactory 클래스를 직접 만드는 것은 어렵지 않습니다. 봄의 번호를 참조하십시오.간단한 예에서는 Format Annotation Formatter Factory 를 참조해 주세요.이것에 의해, 컨트롤러 고유의 포메터/에디터가 불필요하게 된다고 생각합니다.모든 컨트롤러에 대해 하나의 Conversion Service를 사용하고 주석을 통해 형식을 사용자 지정합니다.
  3. 컨트롤러별 문자열 변환이 필요한 경우에도 커스텀프로퍼티 에디터를 사용하는 것이 가장 간단한 방법이라는 점에 동의합니다.('바인더'를 호출하려고 했습니다).@InitBinder 메서드에서는 setConversionService(...)가 사용되지만 바인더 오브젝트가 이미 '글로벌' 변환 서비스가 설정되어 있기 때문에 실패합니다.봄 3에서는 컨트롤러별 변환 클래스가 권장되지 않는 것 같습니다).

가장 간단한 프레임워크를 할 때)은(퍼시스텐스 프레임워크 사용)를합니다.ConditionalGenericConverter메타데이터를 사용하여 엔티티를 변환하는 인터페이스입니다.

예를 들어 JPA를 사용하는 경우 이 컨버터는 지정된 클래스에서 다음 클래스가 있는지 여부를 확인할 수 있습니다.@Entity주석 및 사용@Id주석 필드를 사용하여 정보를 추출하고 제공된 String 값을 조회 ID로 사용하여 검색을 자동으로 수행합니다.

public interface ConditionalGenericConverter extends GenericConverter {
    boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType);
}

ConditionalGenericConverterSpring 변환 API의 "최종 무기"이지만 엔티티 변환을 대부분 처리할 수 있게 되면 구현되므로 개발자 시간이 절약됩니다.컨트롤러의 파라미터로 엔티티 클래스를 지정하기만 하면 새로운 컨버터(커스텀 타입과 비엔티티 타입 제외)를 구현할 생각은 전혀 하지 않아도 됩니다.

2개의 Converter를 정적 내부 클래스로 구현함으로써 2개의 Converter 클래스를 별도로 보유할 필요성을 회피할 수 있습니다.

public class FooConverter {
    public static class BarToBaz implements Converter<Bar, Baz> {
        @Override public Baz convert(Bar bar) { ... }
    }
    public static class BazToBar implements Converter<Baz, Bar> {
        @Override public Bar convert(Baz baz) { ... }
    }
}

그래도 둘 다 따로 등록해야 하지만 변경 시 수정해야 하는 파일 수는 줄어듭니다.

언급URL : https://stackoverflow.com/questions/12544479/spring-mvc-type-conversion-propertyeditor-or-converter

반응형