【问题标题】:Spring HATEOAS Resource Assembler and Resource Links with many variablesSpring HATEOAS 资源汇编器和具有许多变量的资源链接
【发布时间】:2014-11-25 11:05:12
【问题描述】:

我正在使用 Spring HATEOAS 和 Spring 堆栈开发 REST API,但我在资源链接方面遇到了一些问题。

这是我的代码:

控制者:

@RestController
@RequestMapping("/apporteurs/{idInt}/ribs")
public class RibController {

    @Autowired
    private RibResourceAssembler ribResourceAssembler;

    @Autowired
    private RibRepository ribRepository;

    /**
     * Methode GET permettant d'obtenir un Rib par son ID
     *
     * @param idRib ID du Rib
     * @return RibResource
     */
    @RequestMapping(value = "/{idRib}", method = RequestMethod.GET)
    @ResponseBody
    public RibResource getRibById(@PathVariable Long idInt, @PathVariable Long idRib) {

        CurrentUserUtils.checkAuthorizationByApporteur(idInt);
        return ribResourceAssembler.toResource(ribRepository.getRibById(idRib));
    }

}

汇编器:

@Component
public class RibResourceAssembler extends ResourceAssemblerSupport<Rib, RibResource> {

    public static final long TMP_IDS = 1234L;
    @Autowired
    private RibResourceMapper ribResourceMapper;

    public RibResourceAssembler() {
        super(RibController.class, RibResource.class);
    }

    @Override
    public RibResource toResource(Rib rib) {
        return createResourceWithId(rib.getId(), rib);
    }

    /**
     * TODO : mettre le lien vers l'editique Mandat
     *
     * @param rib Rib à instancier en Resource.
     * @return RibResource
     */
    @Override
    protected RibResource instantiateResource(Rib rib) {
        RibResource ribResource = ribResourceMapper.fromRib(rib, rib.getLastMandat());
        ribResource.removeLinks();

        CustomUserDetails user = CurrentUserUtils.getCurrentUser();

        UriComponentsBuilder uriBuilderMandat = linkTo(RibController.class).toUriComponentsBuilder();
        String uri = uriBuilderMandat.path("/{idRib}/mandats/{idMandat}").buildAndExpand(user.getIdInt(), rib.getId(), TMP_IDS).toUriString();
        Link linkEditiqueMandat = new Link(uri).withRel("editiqueMandat");

        UriComponentsBuilder uriBuilderRib = linkTo(RibController.class).toUriComponentsBuilder();
        String uriSelf = uriBuilderRib.path("/{idRib}").buildAndExpand(user.getIdInt(), rib.getId()).toUriString();
        Link linkUriSelf = new Link(uriSelf).withSelfRel();

        ribResource.add(linkEditiqueMandat);
        ribResource.add(linkUriSelf);

        return ribResource;
    }
}

资源:

public class RibResource extends ResourceSupport {

    private Long idRib;
    private String rum;
    private String iban;
    private String libelle;
    private String dateFin;
    private String dateCreation;
    private String dateModification;
    private String codeOperateurCreation;
    private String dateRegulationMandat;
    private boolean actif;
    private boolean reactivable;
    private CodeValueResource modeReglement;

/*Gzetter & setters, etc*/

}

如您所见,我的控制器在 URI 中有一些参数:idInt 和 idRib。

所以要制作一个 SelfLink,我必须知道这个参数才能制作类似“/apporteurs/1234/ribs/1234”的东西,但我认为汇编程序只需要一个参数和一个“简单”URI。

我有这个堆栈跟踪:

2014-11-25 12:02:09.365 ERROR 20860 --- [nio-9080-exec-1] w.s.m.m.a.ResponseEntityExceptionHandler : Not enough variable values available to expand 'idInt'

所以我正在寻找一个优雅的解决方案来做到这一点,因为我没有找到任何东西^^

我在 ResourceProcessor 中看到了一些东西,但我没有使用 Spring Data Rest。

你能帮帮我吗?提前谢谢你;)

编辑:

结果应该是:

_links": {
        "editiqueMandat": {
            "href": "http://localhost:9080/apporteurs/6797/mandats/5822"
        },
        "self": {
                "href": "http://localhost:9080/apporteurs/6797/ribs/1234"
            }
    }

【问题讨论】:

    标签: java spring rest hateoas spring-hateoas


    【解决方案1】:
    @Override
    public RibResource toResource(Rib rib) {
        return createResourceWithId(rib.getId(), rib);
    }
    

    createResourceWithId() 在内部根据控制器的 URL 创建一个自链接。在您包含占位符 {idInt} 的情况下,您必须为此提供一个参数:

    CustomUserDetails user = CurrentUserUtils.getCurrentUser();
    return createResourceWithId(rib.getId(), rib, user.getIdInt());
    

    更好的选择是根本不打电话给createResourceWithId()。只需将您现在在 instantiateResource() 中的所有内容移动到 toResource()

    【讨论】:

    • 好的!!!非常感谢,我研究了这样的解决方案,但不知道从哪里开始:我看到“createResourceWithId”在 Spring 代码中创建了 Self Link,但之后创建“removeLinks”不是“干净”的我的意见^^非常感谢,标记已解决;)
    猜你喜欢
    • 2016-11-05
    • 1970-01-01
    • 2021-07-17
    • 2019-01-03
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2014-11-09
    • 1970-01-01
    相关资源
    最近更新 更多