0

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 として返すことはまだ可能でしょうか?

4

3 に答える 3

0

リソース アセンブラーは、1 つの pojo/entity/whatever を 1 つの hatoas リソースに変換するためのものです。リストをリストに変換しようとしています。

あなたのアセンブラが

public class RoleResourceAssembler extends ResourceAssemblerSupport<List<RoleModel>, RolesResource> {

そして RolesResource はあなたが望んでいたものでした...うまくいくはずです。

ただし、「もの」のページを取得し、アセンブラーを使用してリソースのページを作成する PagedResourceAssembler の使用を検討することをお勧めします。ページは、コレクション全体またはコレクション内のページのみの場合があります。カテゴリの簡単な例を次に示します。

public HttpEntity<PagedResources<CategoryResource>> categories(
    PagedResourcesAssembler<Category> pageAssembler,
    @PageableDefault(size = 50, page = 0) Pageable pageable
){

    Page<Category> shopByCategories = categoryService.findCategories(pageable);        

    PagedResources<CategoryResource> r = pageAssembler.toResource(shopByCategories,
            this.categoryAssembler);

    return new ResponseEntity<PagedResources<CategoryResource>>(r, HttpStatus.OK);
}

しかし..JacksonがPagedResourcesをXMLとしてマーシャリングする際にいくつか問題がありました.JSONでは問題なく動作します。

于 2014-08-18T17:09:33.570 に答える
0

ResourceAssemblerSupport では、HATEOAS リソースのリストを XML にマーシャリングすることはできないようです。その理由は、ResourceAssemblerSupport を拡張するクラスの toResources() メソッドによって返されるリソースのリストに @XmlRootElement がなく、JAXB がマーシャリングに失敗するためです。次のようなクラスを作成する必要がありました

 @XmlRootElement
    public class Roles {    
    private List<RoleResource> roleResource;
    ....
}

@XmlRootElement
public class RoleResource  extends ResourceSupport {
    private RoleModel role;
    ...
}

リソースリストを手動で作成します。のようなSpring HATEOASリソースラッパーを使用しようとしたときに同じ問題が発生しました

Resource<RoleModel> resource = new Resource<>();

Spring の Resource クラスには @XmlRootElement のアノテーションが付けられていないため、REST コントローラーはそれを XML にマーシャリングできません

于 2014-08-29T13:13:41.133 に答える