将自定义 REST 控制器中的链接资源与 Spring REST JPA 结合使用 [英] Using linked Resources in Custom REST Controller with Spring REST JPA

查看:44
本文介绍了将自定义 REST 控制器中的链接资源与 Spring REST JPA 结合使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过数据库开发一组 rest 资源,并使用 Spring Data Rest 公开核心 CRUD 功能以直接与存储库交互.

I am developing a set of rest resources over a database and exposing the core CRUD functionality using Spring Data Rest to directly interact with the Repositories.

在我的简化示例中,我有用户:

In my simplified sample I have Users:

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long id;

    public String name;

    @OneToMany(mappedBy = "user")
    public Collection<Project> projects;
}

和用户拥有的项目:

@Entity
public class Project {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long id;

    public String name;

    public String oneOfManyComplexDerivedProperties;

    @ManyToOne
    public User user;
}

直接与存储库交互很好,因此对于创建用户(其他其他简单实体),问题在于创建项目.项目有大量基于用户表单输入的服务器派生字段,因此我编写了一个自定义控制器来生成它们并保留结果.为了保持结果,我需要将项目与其拥有的用户相关联.我希望我的客户能够为此使用用户链接,就像通过直接进入存储库来创建新实体一样(直接进入存储库才有效):

Directly interacting with the repositories is fine, so for creating Users (other other simple entities), the problem comes with creating Projects. Projects have a large number of server derived fields based on the users form input, so I wrote a custom controller to generate them and persist the result. In order to persist the result, I need to associate the Project with it's owning User. I want my client to be able to use the user Link for this, just as when creating a new entity by going direct to the repository (going direct to the repository just works):

@RepositoryRestController
public class CustomProjectController {

    @Autowired
    ProjectRepo projectRepo;

    @RequestMapping(value = "/createProject", method = RequestMethod.POST)
    public HttpEntity<Project> createProject(@RequestParam User userResource,
                                         @RequestParam String formField1, // actually an uploaded file that gets processed, but i want simple for example purposes
                                         @RequestParam String formfield2)
{
    Project project = new Project();

    /*
    Actually a large amount of complex business logic to derive properties from users form fields, some of these results are binary.
     */
    String result = "result";
    project.oneOfManyComplexDerivedProperties = result;
    project.user = userResource;
    projectRepo.save(project);

    // aware that this is more complex than I've written.
    return ResponseEntity.ok(project);
}
}

当我打电话时:
http://localhost:9999/api/createProject?userResource=http://localhost:9999/api/users/1&formField1=data1&formField2=Otherdata

When I call:
http://localhost:9999/api/createProject?userResource=http://localhost:9999/api/users/1&formField1=data1&formField2=Otherdata

我明白了:

{
    "timestamp": 1510588643801,
    "status": 400,
    "error": "Bad Request",
    "exception": "org.springframework.web.method.annotation.MethodArgumentTypeMismatchException",
    "message": "Failed to convert value of type 'java.lang.String' to required type 'com.badger.User'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Long] for value 'http://localhost:9999/api/users/1'; nested exception is java.lang.NumberFormatException: For input string: \"http://localhost:9999/api/users/1\"",
    "path": "/api/createProject"
}

如果我将 userResource 更改为输入 Resource,则会出现不同的错误:
无法将'java.lang.String'类型的值转换为所需类型'org.springframework.hateoas.Resource';嵌套异常是java.lang.IllegalStateException:无法转换'java.lang.String类型的值' 到所需类型 'org.springframework.hateoas.Resource':找不到匹配的编辑器或转换策略"

If I change userResource to type Resource then I get a different error:
"Failed to convert value of type 'java.lang.String' to required type 'org.springframework.hateoas.Resource'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.hateoas.Resource': no matching editors or conversion strategy found"

我在文档中找不到任何关于在自定义控制器中使用存储库 URI 的参考,我找到的最接近的是 在自定义控制器 (Spring HATEOAS) 中解析实体 URI,但自编写以来 API 发生了变化,我无法让它工作.

I can't find any reference to using repository URI's in custom controllers in the docs, the closest I found was Resolving entity URI in custom controller (Spring HATEOAS) but the API's have changed since that was written and I have not been able to get it to work.

推荐答案

我建议你真正应该做的是:

I would suggest that what you should really be doing is:

http://localhost:9999/api/users/1/projects?formField1=data1&formField2=Otherdata

通过启用 Spring Data 的 Web 支持,您可以将路径变量自动绑定到实体实例.

By enable Spring Data's web support you can have the path variable automatically bound to the entity instance.

@RequestMapping(value = "users/{id}/projects", method = RequestMethod.POST)
        public HttpEntity<Project> createProject(
                            @PathVariable("id") User user,
                            @RequestParam String formField1,
                            @RequestParam String formfield2)
{

}

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#core.web

这篇关于将自定义 REST 控制器中的链接资源与 Spring REST JPA 结合使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆