Определение ассемблера ресурсов для контроллера HATEOAS Rest Spring
Я пытаюсь добавить ссылки HATEOAS на ресурс JSON, обслуживаемый контроллером Spring REST.
Я вижу, что должен использовать ассемблер ресурсов, как описано в https://github.com/spring-projects/spring-hateoas
в Примере отображаются класс Person и класс PersonResource.
Я понимаю, что класс PersonResource определяется как:
public class PersonResource extends ResourceSupport {
}
что такое класс Person ? Это класс домена данных ?
в моем случай, я определил класс администратора, который является классом домена 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 видит только этот класс администратора, поскольку это класс домена REST. Он не знает и не должен знать ничего о классе домена данных.
поэтому мне интересно, как использовать поддержку ассемблера ресурсов здесь.
Я не понимаю, почему у меня должен быть дополнительный класс администратора домена данных здесь.
вид С уважением,
после ответа Майка вот как теперь выглядит мой контроллер:
@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());
но он не давал мне идентификатор ресурса в url-адресе.
1 ответов
код ResourceAssembler
реализация должна знать как о классе домена данных, так и о классе домена REST, потому что его задача-преобразовать первый в последний.
Если вы хотите сохранить знания о своих классах данных из своего контроллера, вы можете создать службу преобразования ресурсов, которая будет извлекать данные из РЕПО и использовать 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);
}
}