我正在尝试将HATEOAS链接添加到由Spring REST控制器提供的JSON资源。
我看到我应该使用https://github.com/spring-projects/spring-hateoas
中描述的资源汇编程序该示例显示Person类和PersonResource类。
我理解PersonResource类定义为:
public class PersonResource extends ResourceSupport {
}
那么Person类是什么?它是数据域类吗?
就我而言,我已经定义了一个Admin类,它是一个REST域类,我将其指定为具有资源支持:
public class Admin extends ResourceSupport {
private String firstname;
private String lastname;
private String email;
private String login;
private String password;
private String passwordSalt;
public Admin() {
}
public String getFirstname() {
return this.firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return this.lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getLogin() {
return this.login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPasswordSalt() {
return passwordSalt;
}
public void setPasswordSalt(String passwordSalt) {
this.passwordSalt = passwordSalt;
}
public EventAdmin toEventAdmin() {
EventAdmin eventAdmin = new EventAdmin();
BeanUtils.copyProperties(this, eventAdmin);
return eventAdmin;
}
public static Admin fromEventAdmin(EventAdmin eventAdmin) {
Admin admin = new Admin();
BeanUtils.copyProperties(eventAdmin, admin);
return admin;
}
}
我的REST控制器只看到这个Admin类,因为它是一个REST域类。它不知道,也不应该知道任何数据域类。
所以我想知道如何在这里使用资源汇编程序支持。
我不明白为什么我应该在这里有一个额外的数据域Admin类。
亲切的问候,
以下迈克的回答是我的控制器现在的样子:
@RequestMapping(method = RequestMethod.POST, produces = "application/json; charset=utf-8")
@ResponseBody
public ResponseEntity<Admin> add(@RequestBody Admin admin, UriComponentsBuilder builder) {
AdminCreatedEvent adminCreatedEvent = adminService.add(new CreateAdminEvent(admin.toEventAdmin()));
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.add("Content-Type", "application/json; charset=utf-8");
responseHeaders.setLocation(builder.path("/admin/{id}").buildAndExpand(adminCreatedEvent.getAdminId()).toUri());
Admin createdAdmin = adminResourceAssembler.toResource(adminCreatedEvent.getEventAdmin());
ResponseEntity<Admin> responseEntity = new ResponseEntity<Admin>(createdAdmin, responseHeaders, HttpStatus.CREATED);
return responseEntity;
}
之前,我没有使用资源汇编程序,而是使用:
Admin createdAdmin = Admin.fromEventAdmin(adminCreatedEvent.getEventAdmin());
createdAdmin.add(linkTo(methodOn(AdminController.class).add(createdAdmin, builder)).withSelfRel());
但是它没有在网址中给我资源ID。
答案 0 :(得分:7)
您的ResourceAssembler
实现需要了解数据域类和REST域类,因为它的工作是将前者转换为后者。
如果您希望从控制器中了解数据类,可以创建一个资源转换服务,该服务将从repo检索数据并使用ResourceAssembler
将其转换为控制器可以使用的资源知道。
@Component
public class AdminResourceAssembler extends ResourceAssemblerSupport<Admin, AdminResource> {
public AdminResourceAssembler() {
super(AdminController.class, AdminResource.class);
}
public AdminResource toResource(Admin admin) {
AdminResource adminResource = createResourceWithId(admin.getId(), admin); // adds a "self" link
// TODO: copy properties from admin to adminResource
return adminResource;
}
}
@Service
public class AdminResourceService {
@Inject private AdminRepository adminRepository;
@Inject private AdminResourceAssembler adminResourceAssembler;
@Transactional
public AdminResource findOne(Long adminId) {
Admin admin = adminRepository.findOne(adminId);
AdminResource adminResource = adminResourceAssembler.toResource(admin);
return adminResource;
}
}
@Controller
@RequestMapping("/admins")
public class AdminController {
@Inject private AdminResourceService adminResourceService;
@RequestMapping(value="/{adminId}", method=RequestMethod.GET)
public HttpEntity<AdminResource> findOne(@PathVariable("adminId") Long adminId) {
AdminResource adminResource = adminResourceService.findOne(adminId);
return new ReponseEntity<>(adminResource, HttpStatus.OK);
}
}