没有Spring数据中的自定义编辑器和转换器

时间:2015-07-02 16:10:02

标签: spring-mvc spring-data spring-data-rest

请原谅我冗长而描述性的问题。感谢您花时间阅读本文。

我在持久层之上有一个自定义的spring数据休息实现。 我使用UUID作为对象的id类型,而不是使用原始类型 持续存在。

我有一个像这样的存储库:

public interface DummyRepository extends PagingAndSortingRepository<Dummy, UUID> { }

我有我的自定义DummyController来执行GET和POST到存储库,如下所示:

@RestController
public class DummyController {

@Autowired
DummyRepository dummyRepository;

@Autowired
DummyResourceProcessor processor;

@RequestMapping(value="/dummies", method = POST,     
consumes=MediaType.APPLICATION_JSON_VALUE,
produces=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Resource<Dummy>> createDummy(@RequestBody Dummy   
dummy){

    Dummy save = dummyRepository.save(dummy);
    Resource<Dummy> dummyResource = new Resource<Dummy>(save);
    return new  
    ResponseEntity<Resource<Dummy>>processor.process(dummyResource), 
    HttpStatus.CREATED);
  }

@RequestMapping(value="/dummies/{id}", method = GET,   
 produces=MediaType.APPLICATION_JSON_VALUE)
 public ResponseEntity<Resource<Dummy>> getDummy(@PathVariable("id") 
 Dummy dummy){

    Resource<Dummy> dummyResource = new Resource<Dummy>(save);
    return new ResponseEntity<Resource<Dummy>>
    (processor.process(dummyResource), HttpStatus.OK);
 }
}

保存虚拟对象时,会生成并分配UUID 持久化之前的id字段。 在我的资源处理器中,链接的设置如下:

@Component
public class DummyResourceProcessor implements  
ResourceProcessor<Resource<Dummy>> {

  @Override
  public Resource<Dummy> process(Resource<Dummy> resource) {
    Dummy dummy = resource.getContent();     
    resource.add(linkTo(methodOn(DummyController.class).
      getDummy(dummy)).withSelfRel());
    return resource;
  }
}

从我的测试代码中我使用这样的方式进行POST:

    result =
    mockMvc.perform(
            post("/dummies").content("{\"name\":\"TestDummy\"}")  
             .contentType(MediaType.APPLICATION_JSON_VALUE))
             .andDo(print())
             .andExpect(status().isCreated()).andReturn();

我得到这样的东西:

Caused by: java.lang.IllegalStateException: Cannot convert value of type [java.util.UUID] to required type [java.lang.String] for property 'id': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:287)
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:461)
... 72 more
{"cause":null,"message":"No converter found capable of converting from   
type @org.springframework.web.bind.annotation.PathVariable 
com.sudo.Dummy to type java.lang.String"}

这是使用DummyToStringConvertor修复的,基本上如下所示:

public class DummyToStringConverter implements Converter<Dummy, String> {

 @Override
 public String convert(Dummy dummy) {
  return dummy.getId().toString();
 }
}

然后我这样做GET:

String dummyLocation = result.getResponse().getHeader("Location");
result =
    mockMvc.perform(get(dummyLocation)).andExpect(status().
    isOk())..andExpect(jsonPath("$.name").value("TestDummy"))
   .andDo(print()).andReturn();

我回来了:

Failed to convert value of type 'java.lang.String' to required type   
'com.sudo.Dummy'; nested exception is java.lang.IllegalStateException
:Cannot convert value of type [java.lang.String] to required type  
[com.sudo.Dummy]: no matching editors or conversion strategy found

这是使用自定义编辑器类修复的,以便将String转换回Dummy对象:

public class DummyEditor extends PropertyEditorSupport {

  private final DummyRepository dummyRepository;

  public DummyEditor(DummyRepository dummyRepository) {
     this.dummyRepository = dummyRepository;
  }

  @Override
  public void setAsText(String text) throws IllegalArgumentException {
     Dummy dummy = dummyRepository.findOne(UUID.fromString(text));
     setValue(dummy);
  }
 }

在控制器中我使用@Initbinder添加了它。它停了下来 侵犯。

我的工作理论是在虚拟内部生成链接 资源处理器,在调用方法期间(虽然没有执行, 我相信,@ PathVariable注释需要一个&#34; id&#34;但它得到了一个假人 对象和它因为无法将其转换为String而中断 (URI模板)。这是正确的吗 ?如果没有,为什么Dummy对象不存在 在链接生成期间自动解决?是因为UUID 场?当我将Dummy对象的id保存为String并更改时 从UUID到String的存储库签名,然后一切都按预期工作。是 有没有办法绕过这个问题,而无需使用自定义 转换器和编辑?

1 个答案:

答案 0 :(得分:0)

这两个例外与链接生成代码无关。试图分别解析请求主体和参数时引发了两个异常。

您遇到了第一个异常,因为请求正文无法将您的输入Json转换为Dummy对象。因为id的UUID类型。实现转换器时问题得到解决。

在GET调用期间引发了第二个异常,因为Spring试图将{id}占位符String值转换为Dummy对象,并且它不知道如何执行此操作。如果您更改GET方法的方法签名,如下所示,那么您应该很好。您不需要PropertyEditorSupport

public ResponseEntity<Resource<Dummy>> getDummy(@PathVariable("id") 
 String dummyId){
}

希望这有帮助。