使用spring数据REST我公开了一个ProjectRepository支持列出项目并对它们执行CRUD操作的方法.当我去的时候,http://localhost:8080/projects/我得到了我期望的项目清单.
我要做的是将自定义操作添加到_linksProject Collection的JSON响应部分.
例如,我希望调用http://localhost:8080/projects/返回这样的内容:
{
"_links" : {
"self" : {
"href" : "http://localhost:8080/projects/{?page,size,sort}",
"templated" : true
},
"search" : {
"href" : "http://localhost:8080/projects/search"
},
"customAction" : {
"href" : "http://localhost:8080/projects/customAction"
}
},
"page" : {
"size" : 20,
"totalElements" : 0,
"totalPages" : 0,
"number" : 0
}
}
Run Code Online (Sandbox Code Playgroud)
凡customAction在某些控制器进行定义.
我试过创建以下类:
public class ProjectCollectionResourceProcessor implements ResourceProcessor<Resource<Collection<Project>>> {
@Override
public Resource<Collection<Project>> process(Resource<Collection<Project>> listResource) {
// code to add the links …Run Code Online (Sandbox Code Playgroud) 它在标题中说的是什么.
我想提供只包含"较低"资源链接的根资源.似乎Resource除了HttpEntity想要一个带有某些内容的对象作为他们的类型,那么我怎么才能只提供链接呢?
谢谢.
我有一个带方法的控制器,它返回PagedResource,如下所示:
@RequestMapping(value = "search/within", method = RequestMethod.POST)
public @ResponseBody PagedResources within(@RequestBody GeoJsonBody body,
Pageable pageable, PersistentEntityResourceAssembler asm) {
// GET PAGE
return pagedResourcesAssembler.toResource(page, asm);
}
Run Code Online (Sandbox Code Playgroud)
现在,我想将该方法添加为根资源的链接,因此我执行以下操作:
public RepositoryLinksResource process(RepositoryLinksResource repositoryLinksResource) {
repositoryLinksResource.add(linkTo(methodOn(ShipController.class).within(null, null, null)).withRel("within"));
return repositoryLinksResource;
}
Run Code Online (Sandbox Code Playgroud)
哪个有效,我得到了我的链接,但它添加了没有分页参数的链接.所以它看起来像这样:
"within": {
"href": "http://127.0.0.1:5000/search/within"
},
Run Code Online (Sandbox Code Playgroud)
我想把它变成:
"within": {
"href": "http://127.0.0.1:5000/search/within{?page, size}"
},
Run Code Online (Sandbox Code Playgroud)
这在以前的计算器问题表明,固定后GitHub上相应的问题应该是默认的工作,然而,事实并非如此.
我究竟做错了什么 ?
我有一个使用Spring HATEOAS的Spring Boot应用程序,它已@EnableEntityLinks启用.该应用程序有一个包含字段的mvc控制器@Autowired EntityLinks entityLinks.
我预计@EnableEntityLinks会提供EntityLinksbean(根据:暴露和管理与Spring HATEOAS的链接),但我得到了一个NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.hateoas.EntityLinks] found
该应用程序是一个测试应用程序,因此它非常小:
Application.java:
@ComponentScan
@EnableAutoConfiguration
@EnableEntityLinks
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Run Code Online (Sandbox Code Playgroud)
CustomerController:
@Controller
@ExposesResourceFor(Customer.class)
@RequestMapping(value = "/customers", produces = "application/json")
public class CustomerController {
@Autowired
private EntityLinks entityLinks;
@RequestMapping(method=RequestMethod.GET)
@ResponseBody
public ResponseEntity<List<Customer>> customers() {
return new ResponseEntity<List<Customer>>(HttpStatus.OK);
}
@RequestMapping(value="/{id}", method=RequestMethod.GET)
@ResponseBody
public ResponseEntity<Customer> customer(@PathVariable long id) { …Run Code Online (Sandbox Code Playgroud) 我想知道是否可以将 HTTP 方法添加到使用 Spring HATEOAS 创建的链接中。我希望链接看起来像:
{
"href":http://localhost:8080/admin/users",
"rel": "add",
"method": "POST"
}
{
"href":http://localhost:8080/admin/users/john",
"rel": "remove",
"method": "DELETE"
}
Run Code Online (Sandbox Code Playgroud)
我找不到任何可以让我向链接添加“方法”的内容。
我正在尝试将 Spring Data REST 与给定的 SQL 模式一起使用,该模式将 JPA @IdClass 注释用于关联表(交集表或多对多解析表)。这些映射实体未正确序列化。
我创建了一个小项目,它说明了这个问题。它是 spring-data-examples 的一个分支,非常简单。它正在使用 eclipselink,但我已经用 Hibernate 对其进行了测试,问题是一样的。
https://github.com/otrosien/spring-data-examples/tree/idClassFailureWithSerializable
设置:2个实体:Customer和Relationship,2个存储库:CustomerRepository、RelationshipRepository,都扩展了CrudRepository
客户有一个生成的 Id 和名字,姓氏作为字符串。关系具有 IdClass "RelationshipID" 和 customer1、customer2 作为复合主键,两者在 Customer 上都有外键。加上一个关系字符串。
基本集成测试显示实体按预期工作。
Customer dave = customers.save(new Customer("Dave", "Matthews"));
Customer jack = customers.save(new Customer("Jack", "Johnson"));
assertThat(customers.findOne(dave.getId()), is(dave));
assertThat(customers.findOne(jack.getId()), is(jack));
Relationship rel = relationships.save(new Relationship(dave, jack, "likes"));
assertThat(relationships.findOne(rel.pk()), is(rel));
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好。现在让我们通过 REST API 试试这个。
POST http://localhost:8080/customers
Content-Type: application/json
{
"lastname" :"Dave",
"firstname":"Matthews"
}
POST http://localhost:8080/customers
Content-Type: application/json
{
"lastname" :"Jack",
"firstname":"Johnson"
}
POST http://localhost:8080/relationships
Content-Type: application/json …Run Code Online (Sandbox Code Playgroud) 我为 Spring Data Rest 项目实现了以下域类。
@Entity
@Data
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long addressID;
private String houseName;
private String apartmentNumber;
@ManyToOne
private City city;
@ManyToOne
private Country country;
}
Run Code Online (Sandbox Code Playgroud)
现在,我通过发送带有以下 JSON 的 POST 来创建地址资源。
{
"houseName":"Some House",
"apartmentNumber":"13 B",
"city": "http://localhost:8080/city/1"
"country":"http://localhost:8080/countries/1"
}
Run Code Online (Sandbox Code Playgroud)
http://localhost:8080/addresses/1当我使用以下 JSON向端点发送 PUT 请求时,houseName 的值会更新。然而,即使我为该城市发送了不同的 URI,该城市仍然保持不变。
{
"houseName":"Another House",
"apartmentNumber":"13 B",
"city": "http://localhost:8080/city/2"
"country":"http://localhost:8080/countries/1"
}
Run Code Online (Sandbox Code Playgroud)
如果我发送 PATCH 而不是 PUT,城市值也会更新。那么我该如何解决这个问题呢?
更新1
乡村班
@Data
@Entity
public class Country {
@Id
@GeneratedValue(strategy …Run Code Online (Sandbox Code Playgroud) 默认情况下,当我们有一个暴露了save方法的存储库时,我们可以执行PATCH请求.然后,Spring Data REST从数据库中检索原始对象并将更改应用于实体,然后将其保存给我们(在JsonPatchHandler类中).这允许我们为类做以下请求
class Address {
Long id;
String street;
Long houseNumber;
}
Run Code Online (Sandbox Code Playgroud)
PATCH/api /地址/ 1与身体
{ houseNumber: 123 }
Run Code Online (Sandbox Code Playgroud)
只有这一个领域才会改变.
现在有了自定义控制器,我们希望在update方法中接收整个对象(在HATEOAS将其与来自DB的原始对象合并之后)
@RepositoryRestController
@ExposesResourceFor(Address.class)
@ResponseBody
@RequestMapping("/addresses")
public class AdddressController {
@PatchMapping("/{addressId}")
public Resource<Address> update(@RequestBody Resource<Address> addressResource, @PathVariable Long addressId) {
Address address= addressResource.getContent();
// .... some logic
address = addressRepository.save(address);
return new Resource<>(address);
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,在我会做一些逻辑的地方,我得到的地址是空字段而不是合并对象.
是否可以在Spring Data REST堆栈中插入自定义控制器,以便在修补请求时将它合并为我(就像它对普通存储库一样)?
编辑:我想找到一个透明地与PATCH(内容类型:application/json-patch + json)和PATCH(内容类型:application/hal + json)一起工作的解决方案
我按照 spring.io Pivotal 教程获得了带有 MySQL 数据库的 REST API,并且事情进展顺利。但是,我发现了一种我无法配置或解决的行为。
当我使用内置功能从 PagingAndSortingRepository 检索我的资源时,生成的 REST 会自动分页并使用有用的 HAL 链接(_links、self、search、链接的资源等)进行封装。我想用那个。
当我实现我的控制器来自定义 PostMapping 行为并引入健全性检查、验证等时,GetMapping 停止工作。所以我重新实现了一个利用我的服务层的 GetMapping。
不幸的是,这样做破坏了之前提供的 HATEOAS。
我想要的是能够自定义 PostMapping,但完全像默认值一样保留 GetMapping。如果可能的话,我很想避免自己编写它,因为我知道框架可以提供它。
有没有办法做到这一点?
控制器:
@RestController
public class PartyMemberController {
@Autowired
PartyMemberService partyMemberService;
@RequestMapping(method = RequestMethod.GET, value = "/partyMembers")
public ResponseEntity<Iterable<PartyMember>> getAllPartyMembers() {
Iterable<PartyMember> partyMemberList = partyMemberService.getAll();
return new ResponseEntity<>(partyMemberList, HttpStatus.OK);
}
@RequestMapping(method = RequestMethod.POST, value = "/partyMembers")
public ResponseEntity<PartyMember> addEmployee(@Valid @RequestBody PartyMember partyMember) {
if (partyMemberService.exists(partyMember)) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
partyMember = …Run Code Online (Sandbox Code Playgroud) 我有一个关于 Spring HATEOAS 的表示模型处理器的问题。我们正在尝试在将模型序列化给客户端之前对其进行处理。我们的用例是在运行时丰富对象imageUrl字段UserModel,因为我们必须根据来自配置 bean 的值构建 URL(AWS S3 存储桶 URL 因 DEV/PROD 设置而异)。
@Data
public class UserModel {
// ...
private String imageUrl;
}
Run Code Online (Sandbox Code Playgroud)
因此,我们创建了一个UserProcessor来实现这个:
public class UserProcessor implements RepresentationModelProcessor<EntityModel<UserModel>> {
private final ConfigAccessor configAccessor;
public UserProcessor(ConfigAccessor configAccessor) {
this.configAccessor = configAccessor;
}
@Override
public EntityModel<UserModel> process(EntityModel<UserModel> model) {
if (model.getContent() != null)
// do the enrichment and set "imageUrl" field
}
return model;
}
}
Run Code Online (Sandbox Code Playgroud)
如果我们有这样的控制器方法,这非常有效:
@ResponseBody
@GetMapping("/me")
public EntityModel<UserModel> getCurrentUser(@AuthenticationPrincipal Principal principal) …Run Code Online (Sandbox Code Playgroud) spring-hateoas ×10
spring ×8
java ×6
spring-boot ×4
hateoas ×3
rest ×2
spring-mvc ×2
jpa ×1
spring-data ×1