ConversionService in Spring

后端 未结 2 988
盖世英雄少女心
盖世英雄少女心 2020-12-08 02:57

I\'m following this scheme in a Spring application.

  1. Request is sent to the server with the id of the object and some other params to be populated in this objec
相关标签:
2条回答
  • 2020-12-08 03:44

    You're trying to implement a ConversionService to do the conversion between Strings and User objects. However, it's Converter implementations that do this part. What you want to do is:

    1. Write a Converter
    2. Register that converter with a ConversionService
    3. Make use of the ConversionService.

    Your converter would be something like:

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

    You then need to register that converter. You can either write your own ConversionServiceFactoryBean or override the default:

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

    If you want to use the ConversionService explicitly, as you have, just leave it as something that can be autowired. Spring and that factorybean definition will take care of the rest.

    If, however, you're already using the <mvc:annotation-driven> tag in your context, you can use its conversion-service attribute to reference your ConversionServiceFactoryBean. You then don't need to have InitBinder or ConversionService in your class at all: by simply having a parameter of a @RequestMapping have your target type, User, the conversion will take place without you having to intervene.

    0 讨论(0)
  • 2020-12-08 03:47

    I did exactly what Gary is saying above and it worked:

    I want to add some more information to the solution. As per the Spring documentation here a URI template variable gets translated to the target object using the Converter/ConversionService. I tried to use a @RequestParam("id") @ModelAttribute("contact") Contact contact, but I was getting an IllegalStateException: Neither BindingResult nor plain target object for bean name 'contact' available as request attribute for not having the model object contact in my view edit.jsp. This can be easily resolved by declaring a Model model and model.addAttribute(contact);. However, there is an even better way; using the URI template variable. It's strange why @RequestParam did not work.

    DID NOT WORK

    @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";
    }
    

    WHAT WORKED

    @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";
    }
    

    So what does this thing do .. a link like ...edit/1 implicitly invokes the converter for String '1' to Contact of id '1' conversion, and brings this contact object to the view. No need for @InitBinder and since its a Converter registered with the ConversionService I can use this anywhere I want - implicitly or explicitly.

    0 讨论(0)
提交回复
热议问题