How to create link pointing to Spring controller action that returns void
Asked Answered
H

1

6

I am using spring mvc, hateoas. I have a controller action that looks like

@RequestMapping(value = "/images/{userId}/{publicUrl}/{fileName:.+}", method = RequestMethod.GET)
public void image(@PathVariable Integer userId, @PathVariable String publicUrl, @PathVariable String fileName, HttpServletRequest request, HttpServletResponse response) throws Exception {
    try(HellodoxAws aws = haws;){
        .....
        .....
        response.setContentType(image.getObjectMetadata().getContentType());
        response.setHeader("ETag",image.getObjectMetadata().getETag());
        response.setHeader("Cache-Control",image.getObjectMetadata().getCacheControl());
        response.setHeader("Last-Modified",image.getObjectMetadata().getLastModified().toString());
        IOUtils.copy(image.getObjectContent(), response.getOutputStream());
    }catch (Exception e) {
        if(e instanceof AmazonS3Exception){
            int statusCode = ((AmazonS3Exception) e).getStatusCode();
            //System.out.println("Status Code : "+statusCode);
            response.setContentType("image/jpeg");
            if(statusCode==HttpStatus.NOT_MODIFIED.value()){
                response.setHeader("ETag",((AmazonS3Exception) e).getAdditionalDetails().get("ETag"));
                response.setHeader("Cache-Control",((AmazonS3Exception) e).getAdditionalDetails().get("Cache-Control"));
                response.setHeader("Last-Modified",((AmazonS3Exception) e).getAdditionalDetails().get("Last-Modified"));
            }
            response.setStatus(statusCode);
        }
    }
}

This action works perfectly well.

Now what I want is to publish url to access each profiles' image. JSON format is some thing like this

{
    "profileId" : 342308,
    "userId" : 342308,
    "firstname" : "Henry",
    "lastname" : "Seol",
    "title" : "Mr.",
    "largeImageUrl" : "https://<host>/image/<id>/<publicUrl>/<filename1.jpg>",
    "thumbImageUrl" : "https://<host>/image/<id>/<publicUrl>/<filename2.jpg>"
}

I want to add that link in place of the value for "largeImageUrl" and "thumbImageUrl".

If I use linkTo function of hateoas it says controller's corresponding method should not return void.

How to create these kind of dynamic link and add it to the resource?

Hanafee answered 1/6, 2015 at 13:10 Comment(4)
You can always use linkTo(...).slash(...)... as last resort. I wonder why the method's return type is void when you actually return an image. Having HttpServletRequest or HttpServletResponse as parameters is a no-go.Diamagnet
Can you suggest me how to return image in this controller by not using HttpServletRequest or HttpServletResponse as parameters, or any other solution for this controller?Hanafee
One alternative is to return ResponseEntity<InputStreamResource>. The InputStreamResource can be created with new InputStreamResource(image.getObjectContent()), I assume.Diamagnet
While in this specific example may perhaps be changed, there are others where void is ok and by design, e.g. action applies side effect and returns no content.Unmeant
V
4

You can use the

public static ControllerLinkBuilder linkTo(Class<?> controller, Method method, Object... parameters) {

So it should be something like

Link link = linkTo(
  ImageController.class,
  ImageController.class
    .getMethod("image", Integer.class, String.class, String.class, HttpServletRequest.class, HttpServletResponse.class),
  1,
  "url",
  "file"
).withRel("image");

Note : There is a shorter method

public static ControllerLinkBuilder linkTo(Method method, Object... parameters) {

but it has a bug therefore it does not work

Violate answered 23/10, 2015 at 13:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.