spring - 如何配置 Spring Data REST 以将新创建​​的实体作为 POST 正文的一部分返回

标签 spring rest spring-data-rest

我正在使用 Spring Data REST 将我的 JPA 存储库公开为 Web 服务。

我正在使用 RestTemplate 测试这些 Web 服务中的每一个。我希望这些测试是集成测试……这意味着我在我的应用程序运行时执行每个测试。我不想 mock 任何东西。

现在我想知道的是如何配置 Spring Data REST 以在发送 HTTP POST 时将新创建的实体作为正文的一部分返回。

我尝试在配置类 RepositoryRestMvcConfiguration 中设置适当的标志,但它似乎不起作用。

这是我的配置类:

@Configuration
public class RepositoryRestMvcConfiguration extends org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration {

    @Override
    public RepositoryRestConfiguration config() {
        RepositoryRestConfiguration config = super.config();
        config.setBasePath("/sdr-api");                
        config.setReturnBodyOnCreate(Boolean.TRUE);
        config.setReturnBodyOnUpdate(Boolean.TRUE);        
        config.exposeIdsFor(Project.class);        
        config.setDefaultMediaType(MediaType.APPLICATION_JSON);        
        return config;
    }
}

这是我希望能够执行的测试示例:

@Test
@SqlGroup({ @Sql(scripts = "/clear-data.sql", config = @SqlConfig(transactionMode = TransactionMode.ISOLATED)) })
public void create() {
    final String PROJECT_NAME = "MY_PROJECT";

    Project project = new Project();
    project.setName(PROJECT_NAME);

    ResponseEntity<Project> response = restTemplate().postForEntity(getBaseUrl() + "projects", project, Project.class);
    assertThat(response.getStatusCode(), equalTo(HttpStatus.CREATED));

    Project projectCreated = response.getBody();
    assertThat(projectCreated.getId(), notNullValue());
    assertThat(projectCreated.getCreatedBy(), notNullValue());
    assertThat(projectCreated.getCreatedDate(), notNullValue());
    assertThat(projectCreated.getLastModifiedBy(), notNullValue());
    assertThat(projectCreated.getLastModifiedDate(), notNullValue());
    assertThat(projectCreated.getName(), equalTo(PROJECT_NAME));
}

此测试在以下语句上失败,因为 ID 以及所有其他属性为 null...

assertThat(projectCreated.getId(), notNullValue());

即使我尝试使用 curl 调用 WS,它也没有给出我期望的结果...

curl -i -X POST -H "Content-Type:application/json" -d '{ "name" : "MY_PROJECT" }' http://localhost:8081/myproject/sdr-api/projects

它应该返回新创建的实体,它应该返回结果作为 application/json 而不是我的配置类中指定的 application/hal+json...

HTTP/1.1 201 Created
Server: Apache-Coyote/1.1
Access-Control-Allow-Methods: GET, POST, HEAD, PUT, DELETE, OPTIONS
Access-Control-Max-Age: 3600
Access-Control-Allow-Headers: Accept, Origin, X-Requested-With, Content-Type, Last-Modified, Authorization
Access-Control-Allow-Credentials: true
ETag: "0"
Last-Modified: Tue, 10 Nov 2015 19:59:12 GMT
Location: http://localhost:8081/myproject/sdr-api/projects/4
Content-Type: application/hal+json
Transfer-Encoding: chunked
Date: Tue, 10 Nov 2015 19:59:12 GMT

{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8081/myproject/sdr-api/projects/4"
    },
    "project" : {
      "href" : "http://localhost:8081/myproject/sdr-api/projects/4{?projection}",
      "templated" : true
    }
  }
}

知道问题出在哪里吗?

在过去的几个小时里,我尝试了很多事情......在 Spring 2.4.0.RELEASE 中,我尝试按照

的建议使用 RepositoryRestConfigurerAdapter
@Configuration
@Import(RepositoryRestMvcConfiguration.class)
public class SpringDataRestConfiguration extends RepositoryRestConfigurerAdapter {

    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.setBasePath("/sdr-api");
        config.setReturnBodyOnCreate(Boolean.TRUE);
        config.setReturnBodyOnUpdate(Boolean.TRUE);
        config.exposeIdsFor(Project.class);
        config.useHalAsDefaultJsonMediaType(false);
        config.setDefaultMediaType(MediaType.APPLICATION_JSON);
    }
}

但我仍然得到相同的结果...虽然我的 SDR API 在/sdr-api 下可用,但代码似乎已执行。

所以我决定将 Spring Data Rest 的版本降级到 2.3.2.RELEASE。我以这种方式修改了我的配置类:

@Configuration
public class MySDRConfiguration extends RepositoryRestMvcConfiguration {

    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.setBasePath("/sdr-api");
        config.setReturnBodyOnCreate(Boolean.TRUE);
        config.setReturnBodyOnUpdate(Boolean.TRUE);
        config.exposeIdsFor(Project.class);
        config.useHalAsDefaultJsonMediaType(false);
        config.setDefaultMediaType(MediaType.APPLICATION_JSON);
    }
}

这次,它成功了!我得到的结果是我所期待的:

HTTP/1.1 201 Created
Server: Apache-Coyote/1.1
Access-Control-Allow-Methods: GET, POST, HEAD, PUT, DELETE, OPTIONS
Access-Control-Max-Age: 3600
Access-Control-Allow-Headers: Accept, Origin, X-Requested-With, Content-Type, Last-Modified, Authorization
Access-Control-Allow-Credentials: true
ETag: "0"
Last-Modified: Thu, 12 Nov 2015 20:55:32 GMT
Location: http://localhost:8081/myproject/sdr-api/projects/3
Content-Type: application/json
Transfer-Encoding: chunked
Date: Thu, 12 Nov 2015 20:55:32 GMT

{
  "id" : 3,
  "createdBy" : "anonymousUser",
  "createdDate" : "2015-11-12T20:55:32.368Z",
  "lastModifiedBy" : "anonymousUser",
  "lastModifiedDate" : "2015-11-12T20:55:32.368Z",
  "name" : "TEST",
  "links" : [ ],
  "content" : [ ],
  "links" : [ {
    "rel" : "self",
    "href" : "http://localhost:8081/myproject/sdr-api/projects/3"
  }, {
    "rel" : "testPlans",
    "href" : "http://localhost:8081/myproject/sdr-api/projects/3/testPlans"
  } ]
}

我是否遗漏了最新版本的 Spring Data REST?

最佳答案

Spring :

<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
@SpringBootApplication
public class QuizApplication implements ViewProvider {
    public static void main(String[] args) {
        SpringApplication.run(QuizApplication.class, args);
    }

    @Bean
    public RepositoryRestConfigurer repositoryRestConfigurer(EntityManager entityManager) {
        return RepositoryRestConfigurer.withConfig(config -> config.exposeIdsFor(Question.class));
    }
}

关于spring - 如何配置 Spring Data REST 以将新创建​​的实体作为 POST 正文的一部分返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33638580/

相关文章:

Azure ServiceBus REST API 队列中的消息总数

java - 使用 Spring Data Rest 为 Controller 和存储库提供相同的 url 映射

jpa - 如何使用 Spring Data REST 和 HATEOAS 公开完整的树结构?

spring - 我可以将 Spring MVC servlet 的 WebApplicationContext 注入(inject) DelegatingFilterProxy 吗?

java - 我如何将一个 bean 合并到另一个 bean 中以进行部分更新

java - 与正常的异常处理相比,Hystrix 有哪些优势?

javascript - 我应该如何构建 .net 网站以使用 Web API?

java - Jersey @PathParam : how to pass a variable which contains more than one slashes

java - Spring Cloud Stream 与 RabbitMQ 的连接

java - 在 spring boot JPA 中,如何正确地将实体表示具有外键关联的对象发布到不同的实体?