从@PathVariable DomainObject转换为String?(使用ControllerLinkBuilder.methodOn)


问题内容

我试图ControllerLinkBuilder.methodOn()用非字符串类型来调用Spring
,它总是失败。而且我不知道使用哪种类型Converter以及在哪里注册。

这是我的控制器:

@RestController
@RequestMapping("/companies")
class CompanyController {

    @RequestMapping(value="/{c}", method=RequestMethod.GET)
    void getIt(@PathVariable Company c) {
        System.out.println(c);
        Link link = linkTo(methodOn(getClass()).getIt(c));
    }

}

System.out.println(c)效果很好。Company从数据库中获取了我的Domain对象。(我正在使用DomainClassConverter

但是另一种方法不起作用: ConverterNotFoundException: No converter found capable of converting from type @PathVariable Company to type String

我只需要一个Converter<Company, String>吗?我应该在哪里注册?我尝试使用的addFormatters(FormatterRegistry registry)方法进行操作WebMvcConfigurationSupport,但确实显示了相同的错误。但是毕竟我不确定我到底尝试了什么…


问题答案:

找到了一个“解决方案”。它需要从Spring的类中进行大量复制和粘贴,但是至少它能起作用!

基本上我必须复制org.springframework.hateoas.mvc.AnnotatedParametersParameterAccessor和更改两行:

class AnnotatedParametersParameterAccessor {
    ...
    static class BoundMethodParameter {
        // OLD: (with this one you can't call addConverter())
        // private static final ConversionService CONVERSION_SERVICE = new DefaultFormattingConversionService();
        // NEW:
        private static final FormattingConversionService CONVERSION_SERVICE = new DefaultFormattingConversionService();

        ...

        public BoundMethodParameter(MethodParameter parameter, Object value, AnnotationAttribute attribute) {
            ...
            // ADD:
            CONVERSION_SERVICE.addConverter(new MyNewConverter());
    }

    ...
}

此类使用了ControllerLinkBuilderFactory。所以我也必须复制并粘贴。

并已使用ControllerLinkBuilder。也复制并粘贴。

Converter就是这样myDomainObject.getId().toString()

public class MyNewConverter implements Converter<Company, String> {
    @Override
    public String convert(Company source) {
        return source.getId().toString();
    }   
}

现在,您可以ControllerLinkBuilder在控制器内使用复制粘贴的文件,它可以按预期工作!