简体   繁体   English

如何在不修改整个响应的情况下基于HATEOAS返回URL?

[英]How to return URLs based on HATEOAS without modifying the whole response?

I have developed a service using Spring Boot. 我已经使用Spring Boot开发了一项服务。 This is the code (simplified): 这是代码(简体):

@RestController
@RequestMapping("/cars")
public class CarController {
    @Autowired
    private CarService carService;

    @Autowired
    private CarMapper carMapper;

    @GetMapping("/{id}")
    public CarDto findById(@PathVariable Long id) {
        Car car = carService.findById(id);
        return carMapper.mapToCarDto(car);
    }
}

CarMapper is defined using mapstruct. CarMapper是使用mapstruct定义的。 Here's the code (simplified as well): 这是代码(也已简化):

@Mapper(componentModel="spring",
        uses={ MakeModelMapper.class })
public interface CarMapper {
    @Mappings({
        //fields omitted
        @Mapping(source="listaImagenCarro", target="rutasImagenes")
    })
    CarDto mapToCarDto(Car car);

    String CAR_IMAGE_URL_FORMAT = "/cars/%d/images/%d"
    /*
        MapStruct will invoke this method to map my car image domain object into a String. Here's my issue.
    */
    default String mapToUrl(CarImage carImage) {
        if (carImage == null) return null;
        return String.format(
                   CAR_IMAGE_URL_FORMAT,
                   carImage.getCar().getId(),
                   carImage.getId()
               );
    }
}

The JSON response I get when invoking the service: 调用服务时得到的JSON响应:

{
    "id": 9,
    "make": { ... },
    "model": { ... },
    //more fields...
    //the urls for the car images
    "images": [
        "/cars/9/images/1"
    ]
}

I need that the images field returns valid URLs regarding the server and path where my app is deployed. 我需要images字段返回有关服务器和我的应用程序部署路径的有效URL。 For example, if I deploy the app using localhost through port 8080, I would like to get this: 例如,如果我通过端口8080使用localhost部署应用程序,我想获得以下信息:

{
    "id": 9,
    "make": { ... },
    "model": { ... },
    //more fields...
    "imagenes": [
        "http://localhost:8080/cars/9/images/1"
    ]
}

I've reviewed Building a Hypermedia-Driven RESTful Web Service , which seems what I want. 我已经审查了构建超媒体驱动的RESTful Web服务 ,这似乎是我想要的。 Except that I only need it for these urls, I don't want to change my whole response object. 除了只需要这些URL以外,我不想更改整个响应对象。

Is there another way to achieve it? 还有另一种方法可以实现吗?

Spring HATEOAS provides a LinkBuilder service just for this purpose. Spring HATEOAS为此提供了LinkBuilder服务。

Try the following: 请尝试以下操作:

import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
//...//

linkTo(methodOn(CarController.class).findById(9)).withRel("AddYourRelHere");

This should output an absolute URL that points to your resource. 这应该输出指向您资源的绝对URL。 You are not following the HAL convention, so you should change or remove the part "withRel("")" 您未遵循HAL约定,因此应更改或删除“ withRel(“”)“部分

You can add this to the specific DTOs you want to change: 您可以将其添加到要更改的特定DTO中:

CarDto dto = carMapper.mapToCarDto(car);
if(dto.matches(criteria)){
    dto.setUrl(linkTo...);
}
return dto;

By the way, all of this is shown in the section "Create a RestController" of the tutorial you mention. 顺便说一下,所有这些都显示在您提到的教程的“创建RestController”部分中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM