Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring mvc 将@RequestBody中的HAL URI映射到Spring数据Rest管理实体_Spring Mvc_Spring Data_Spring Data Rest_Spring Hateoas - Fatal编程技术网

Spring mvc 将@RequestBody中的HAL URI映射到Spring数据Rest管理实体

Spring mvc 将@RequestBody中的HAL URI映射到Spring数据Rest管理实体,spring-mvc,spring-data,spring-data-rest,spring-hateoas,Spring Mvc,Spring Data,Spring Data Rest,Spring Hateoas,我使用SpringDataJPA来管理JPA实体,SpringDataREST将存储库导出到RESTAPI中 我还构建了一个自定义控制器,希望在其中获取实体的URI(HAL链接),并通过crudepository自动将其映射到实体对象 客户控制器 @RequestMapping(path=MeLinks.ELEVATE,method=RequestMethod.PUT,consumes=RestMediaTypes.TEXT\u URI\u LIST\u VALUE) HttpEntity提升(

我使用SpringDataJPA来管理JPA实体,SpringDataREST将存储库导出到RESTAPI中

我还构建了一个自定义控制器,希望在其中获取实体的URI(HAL链接),并通过
crudepository
自动将其映射到实体对象

客户控制器

@RequestMapping(path=MeLinks.ELEVATE,method=RequestMethod.PUT,consumes=RestMediaTypes.TEXT\u URI\u LIST\u VALUE)
HttpEntity提升(@RequestBody@Valid CollectionModel联系人){
...
}
尝试
放置
联系人链接时,如
http://localhost:8080/contacts/1
使用内容类型
text/uri list
,我可以使用
contact.getLinks()
访问链接,但不能使用contact对象本身

SpringDataREST是否可以从URI自动推断实体?我知道有一个内置的
UriToEntityConverter
,但如何使用它呢

编辑

这是一个有效的尝试,但并不能很好地解决问题

下面的代码初始化一个
UriToEntityConverter
,并将传入的URI转换为域对象

@Autowired
私有应用程序上下文应用程序上下文;
@自动连线
私有映射上下文映射上下文;
@RequestMapping(path=MeLinks.ELEVATE,method=RequestMethod.PUT,consumes=RestMediaTypes.TEXT\u URI\u LIST\u VALUE)
HttpEntity提升(@RequestBody@Valid CollectionModel URI){
URI=URI.create(uris.getLinks().get(0.getHref());
存储库存储库=新存储库(applicationContext);
PersistentEntity contactPersistentEntity=repositories.getPersistentEntity(Contact.class);
UriToEntityConverter UriToEntityConverter=新UriToEntityConverter(
新的PersistentEntity(Collections.singleton(mappingContext)),
新的DefaultRepositoryInvokerFactory(存储库),
储存库);
Contact t=(Contact)uriToEntityConverter.convert(uri,TypeDescriptor.valueOf(uri.class),TypeDescriptor.valueOf(Contact.class));
}
可以想象,从
存储库
中获取域对象要比上述操作简单得多。假设URI使用
ID
作为链接的唯一部分,这也是可行的。在我的例子中,我对它进行了定制,以使用UUID。因此,
UriToEntityConverter
的默认行为将不起作用


注意:
Resources
class to
CollectionModel
,HATEOAS首次发布。

如果您想继续使用
UriToEntityConverter
我建议签出,使用
EntityLookupSupport
类将资源URI自定义为不同的属性。然后,
UriToEntityConverter
应正确返回实体

如果您希望直接使用存储库,请考虑以下内容:

查看的源代码,它使用URI的最后一部分作为对象的标识符。你也可以这样做。(在这个代码片段中,我刚刚从上面修改了您的代码,假设您正确地检索了
URI
对象)

private ContactRepository ContactRepository;
//您应该使用构造函数注入,因为它优于字段注入。
@自动连线
公共CustomController(ContactRepository ContactRepository){
this.contactRepository=contactRepository;
}
@RequestMapping(path=MeLinks.ELEVATE,method=RequestMethod.PUT,consumes=RestMediaTypes.TEXT\u URI\u LIST\u VALUE)
HttpEntity提升(@RequestBody@Valid CollectionModel URI){
URI=URI.create(uris.getLinks().get(0.getHref());
可选选项contact=contactRepository.findByName(getLastUriPart(uri));
if(可选的contact.isPresent()){
返回optionalContact.get();
}否则{
//错误处理
}
}
私有字符串getLastUriPart(URI){
字符串[]uriParts=uri.getPath().split(“/”);
如果(长度小于2){
//错误处理
}
返回uriParts[uriParts.length-1];
}

适用于我,但太糟糕了,它不适用于子实体(例如
http://localhost:8080/contacts/1/childEntity
)我四处搜索,到目前为止没有找到任何东西。@GuiRitter什么东西不适合子实体?子实体也有存储库还是自定义链接?在自定义链接的情况下,您是否使用
RepositoryRestController
?在上面的示例链接中,它尝试将
childEntity
解析为
Long
,就好像它是
联系人
id一样
childEntity
确实有一个存储库,但没有自定义链接。啊,我明白了。这可能是因为
UriToEntityConverter
仅用于解析根URI。因此,在您的例子中,要解析的URI应该是
http://localhost:8080/child_entities/1
或类似内容。我正在尝试使用您的代码,但如何获取@Autowired private MappingContext MappingContext;?
private ContactRepository contactRepository;

// You should use constructor injection, as it is preferred over field injection.
@Autowired
public CustomController(ContactRepository contactRepository){
    this.contactRepository = contactRepository;
}


@RequestMapping(path = MeLinks.ELEVATE, method = RequestMethod.PUT, consumes = RestMediaTypes.TEXT_URI_LIST_VALUE)
HttpEntity<?> elevate(@RequestBody @Valid CollectionModel<Contact> uris) {
    URI uri = URI.create(uris.getLinks().get(0).getHref());

    Optional<Contact> optionalContact = contactRepository.findByName(getLastUriPart(uri));

    if (optionalContact.isPresent()){
        return optionalContact.get();
    } else {
        // Error handling
    }
}

private String getLastUriPart(URI uri) {
    String[] uriParts = uri.getPath().split("/");

    if (uriParts.length < 2) {
        // Error handling
    }

    return uriParts[uriParts.length - 1];
}