Spring Resource Assembler and HATEOAS Resources Multiple Variable References

I am working on REST API using Spring HATEOAS and Spring and I have issues with resource referencing.

Here is my code:

Controller:

@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));
    }

}

      

Assembler:

@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;
    }
}

      

Resource:

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*/

}

      

As you can see, my controller has some parameters in the URI: idInt and idRib.

So, to create a SelfLink, I have to know these parameters to do something like "/ apporteurs / 1234 / ribs / 1234", but I think the Assembler only wants one parameter and a "simple" URI.

I have a stack trace:

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'

      

So, I'm looking for an elegant solution for this because I didn't find anything ^^

I saw something with ResourceProcessor, but I am not using Spring Data Rest.

Could you help me? Thank you in advance;)

EDIT:

The result should be:

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

      

+3


source to share


1 answer


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

      

createResourceWithId()

internally creates its own link based on the controller url. In your case containing a placeholder {idInt}

, so you need to provide a parameter for that:



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

      

The best choice would be not to name it at all createResourceWithId()

. Just move everything you now have from instantiateResource()

to toResource()

.

+3


source







All Articles