我使用Spring Boot开发了一项服务。这是代码(简化):
@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
是使用mapstruct定义的。这是代码(也简化了):
@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()
);
}
}
调用服务时获得的JSON响应:
{
"id": 9,
"make": { ... },
"model": { ... },
//more fields...
//the urls for the car images
"images": [
"/cars/9/images/1"
]
}
我需要images
字段返回有关部署我的应用的服务器和路径的有效网址。例如,如果我使用localhost通过端口8080部署应用程序,我想得到这个:
{
"id": 9,
"make": { ... },
"model": { ... },
//more fields...
"imagenes": [
"http://localhost:8080/cars/9/images/1"
]
}
我已经审核了Building a Hypermedia-Driven RESTful Web Service,这似乎是我想要的。除了我只需要这些网址,我不想改变我的整个响应对象。
还有其他方法可以实现吗?
答案 0 :(得分:2)
Spring HATEOAS仅为此目的提供了LinkBuilder服务。
尝试以下方法:
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
//...//
linkTo(methodOn(CarController.class).findById(9)).withRel("AddYourRelHere");
这应输出指向您资源的绝对URL。您没有遵循HAL惯例,因此您应该更改或删除“withRel(”“)”
部分您可以将其添加到要更改的特定DTO中:
CarDto dto = carMapper.mapToCarDto(car);
if(dto.matches(criteria)){
dto.setUrl(linkTo...);
}
return dto;
顺便说一句,所有这些都显示在你提到的教程的“创建一个RestController”部分。