복붙노트

[SPRING] Spring의 ConversionService

SPRING

Spring의 ConversionService

나는 Spring 애플리케이션에서이 스키마를 따르고있다.

나는이 다른 질문에서 요청의 매개 변수를 채우기 전에 객체를 준비하는 가장 좋은 방법은 무엇인지 물었다. 가장 좋은 방법은 @ModelAtribute 주석이 달린 메서드 나 initBinder의 편집기에서 변환 서비스를 사용하는 것이 었습니다.

그래서 저는 변환기를 사용하려고했지만 비슷한 예제를 찾지 못했고 조금 갇혀 있습니다. 아래 코드를 작성했습니다 : init 바인더에 변환 서비스를 등록합니다. 따라서 User 객체에 값을 채우기 전에 convert () 메서드가 호출되어 데이터베이스에서 객체를로드합니다. 문제는 개체 사용자의 ID (사용자 이름 필드)를 Object 사용자로 변환하기 때문에이 구성이 작동하지 않지만 개체와 setUsername ()을 만들려고하므로 "java.lang .IllegalArgumentException : 인수 유형이 일치하지 않습니다. "

아무도 나에게 단서 또는 원하는 동작을 얻기 위해 ConversionService를 사용하는 방법의 예를 줄 수 있습니까?

감사.

@Autowired
private ConversionService conversionService;

@InitBinder("user")
public void initBinder(@RequestParam("username")String username, WebDataBinder binder){
    binder.setConversionService(conversionService);
}

@RequestMapping(value="/user/save", method=RequestMethod.POST)
public String save(@ModelAttribute("user") User user, Model model) {        
    ...
}

같이 뭔가 :

@Component
public class UserConversionService implements ConversionService{
    ...        
    @Override
    public Object convert(Object name, TypeDescriptor arg1, TypeDescriptor arg2) {
        return userService.find((String)name); 
    }
}

해결법

  1. ==============================

    1.String과 User 객체 간의 변환을 수행하기 위해 ConversionService를 구현하려고합니다. 그러나이 부분을 수행하는 Converter 구현입니다. 당신이하고 싶은 것은 :

    String과 User 객체 간의 변환을 수행하기 위해 ConversionService를 구현하려고합니다. 그러나이 부분을 수행하는 Converter 구현입니다. 당신이하고 싶은 것은 :

    귀하의 변환기는 다음과 같습니다 :

    final class UserConverter implements Converter<String, User> {
        ...
        public User convert(String username) {
            return userService.find(username);
        }
    
    }
    

    그런 다음 해당 변환기를 등록해야합니다. 자신 만의 ConversionServiceFactoryBean을 작성하거나 기본값을 재정의 할 수 있습니다.

    <bean id="conversionService"
          class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <list>
                <bean class="example.UserConverter"/>
            </list>
        </property>
    </bean>
    

    ConversionService를 명시 적으로 사용하려면 autowired 일 수있는 그대로 두십시오. 봄과 그 factoryby 정의는 나머지를 처리 ​​할 것입니다.

    그러나 컨텍스트에서 이미 태그를 사용하고 있다면 ConversionServiceFactoryBean을 참조하기 위해 conversion-service 속성을 사용할 수 있습니다. 그런 다음 클래스에서 InitBinder 또는 ConversionService를 사용할 필요가 없습니다. @RequestMapping 매개 변수를 사용하면 타겟 유형 인 User 만 있으면 사용자가 개입 할 필요없이 변환이 수행됩니다.

  2. ==============================

    2.나는 게리가 위에 말한 것과 똑같은 일을했다.

    나는 게리가 위에 말한 것과 똑같은 일을했다.

    솔루션에 몇 가지 정보를 추가하고 싶습니다. 여기 Spring 문서에 따라 URI 템플릿 변수는 Converter / ConversionService를 사용하여 대상 객체로 변환됩니다. @RequestParam ( "id") @ModelAttribute ( "contact") 연락처를 사용하려고 시도했지만 IllegalStateException이 발생했습니다 : BindingResult 또는 빈 이름 'contact'에 대한 일반 대상 객체가 모델이없는 요청 속성으로 사용할 수 없습니다. 내 view edit.jsp에서 객체 접촉. 이것은 Model 모델과 model.addAttribute (contact);를 선언하면 쉽게 해결할 수 있습니다. 그러나 더 좋은 방법이 있습니다. URI 템플릿 변수를 사용합니다. @RequestParam이 작동하지 않는 이유는 이상합니다.

    작동하지 않았다

    @RequestMapping("edit") //Passing id as .. edit?id=1
    public String editWithConverter(@RequestParam("id") @ModelAttribute("contact") Contact contact){
        logger.info("edit with converter");
         return "contact/edit";
    }
    

    무엇이 일 했는가?

    @RequestMapping("edit/{contact}") //Passing id as .. edit/1
    public String editWithConverter(@PathVariable("contact") @ModelAttribute("contact") Contact contact){ // STS gave a warning for using {contact} without @PathVariable 
        logger.info("edit with converter");
         return "contact/edit";
    }
    

    그래서이 일은 .. 링크처럼 ... edit / 1은 id '1'변환의 Contact에 문자열 '1'에 대한 변환기를 암시 적으로 호출하고이 연락처 객체를 뷰에 가져옵니다. @InitBinder가 필요없고 Converter가 ConversionService에 등록되어 있으므로 암시 적 또는 명시 적으로 원하는 곳 어디에서나 사용할 수 있습니다.

  3. from https://stackoverflow.com/questions/4347284/conversionservice-in-spring by cc-by-sa and MIT license