Spring HATEOAS ベースのアプリケーションで XML 応答をサポートしようとしています。JSON 応答は、単一のリソースの XML と同様に正常に機能します。問題はリソースのリストから始まります。Spring MVC コントローラーは、ResourceAssemblerSupport 派生クラスを使用して構築されたリストをシリアル化できません。コントローラーは、curl コマンドに対して「org.springframework.web.HttpMediaTypeNotAcceptableException: 受け入れ可能な表現が見つかりませんでした」をスローします。
curl -k -i -H "Accept:application/xml" -H "Media-Type:application/xml" -X GET http://127.0.0.1:8080/admin/roles*
私の HATEOAS リソースはエンティティ クラスのラッパーです。
@XmlRootElement
@XmlSeeAlso(RoleModel.class)
public class RoleResource extends ResourceSupport {
public RoleModel role;
}
コントローラーは単純です。
@RequestMapping(method = RequestMethod.GET)
public @ResponseBody HttpEntity<List<RoleResource>> getAllRoles()
throws ObjectAccessException, ObjectNotFoundException {
List<RoleModel> resp = rolesManagement.getRoles();
return new ResponseEntity<List<RoleResource>>(roleResourceAssembler.toResources(resp),
HttpStatus.OK);
}
リソース アセンブラ クラス:
@Configuration
public class RoleResourceAssembler extends ResourceAssemblerSupport<RoleModel, RoleResource> {
public RoleResourceAssembler() {
super(RolesRestController.class, RoleResource.class);
}
@Bean
public RoleResourceAssembler roleResourceAssembler(){
return new RoleResourceAssembler();
}
@Override
public RoleResource toResource(RoleModel role) {
RoleResource res = instantiateResource(role);
res.role = role;
try {
res.add(linkTo(methodOn(RolesRestController.class).getRole(role.getRoleId())).withSelfRel());
} catch (ObjectAccessException | ObjectNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return res;
}
}
ResourceAssemblerSupport を回避し、次のようにリソースを手動でビルドすると:
@XmlRootElement
@XmlSeeAlso(RoleModel.class)
public class RolesList {
private List<Resource<RoleModel>> roles;
...
}
@RequestMapping(method = RequestMethod.GET)
public @ResponseBody HttpEntity<RolesList> getAllRoles()
throws ObjectAccessException, ObjectNotFoundException {
List<RoleModel> resp = rolesManagement.getRoles();
List<Resource<RoleModel>> roles =new ArrayList<>();
for (RoleModel model: resp) {
Resource<RoleModel> res = new Resource<RoleModel>(model);
res.add(linkTo(methodOn(RolesRestController.class).getRole(model.getRoleId())).withSelfRel());
roles.add(res);
}
RolesList list = new RolesList();
list.setRoles(roles);
return new ResponseEntity<RolesList>(list,
HttpStatus.OK);
}
XML シリアライゼーションが機能します。リソース アセンブラーを使用せずに手動でリソースをビルドすることもできると思いますが、それではコードがクリーンでモジュール化されなくなります。ResourceAssemblerSupport をリソース ビルダーとして使用し、リソースのリストを XML として返すことはまだ可能でしょうか?