I have a spring-boot project that provides a @RestController and a vaadin @SpringUI.
Accessing the vaadin ui is possible through url: http://localhost:8080/
Through ui users create devices. This device creation is done by invoking my @RestController in my vaadin class. Last part is the creation of the device. And now starts the problem. Device objects has a hateos Link member initialized in it's constructor. Link creation is done with Spring ControllerLinkBuilder.
Problem is, that the hateos link is not proper created. The link looks like this:
"href": "http://localhost:8080/vaadinServlet/devices/1"
But the link has to look like this (without vaadinServlet):
"href": "http://localhost:8080/devices/1"
RestController for creating new devices:
@RestController
@RequestMapping("/devices")
public class DevicesRestController {
@RequestMapping(value="/{deviceID}", method=RequestMethod.GET)
@ResponseBody
public HttpEntity<Device> getDevice(@PathVariable("deviceID") int deviceID) {
// return device
}
@RequestMapping(method=RequestMethod.POST)
@ResponseBody
public ResponseEntity<Device> postDevice() {
// return new device
}
}
Vaadin UI creating the device:
public class VaadinController {
@Autowired
private DevicesRestController devicesRestController;
private Device createDevice() {
Device postDevice = devicesRestController.postDevice().getBody();
return postDevice;
}
}
My Device class with hateos Link
public class Device {
private final Link self;
public Device() {
this.self = ControllerLinkBuilder.linkTo(DevicesRestController.class).withSelfRel();
}
}
So long story short: how can I get rid of the /vaadinServlet in my hateos link created by Spring ControllerLinkBuilder?
Edit 1: You can solve this problem quite easy, if I don't autowire the @RestController in my VaadinController by just invoking the RestTemplate class. See the following code snipped:
public class VaadinController {
private Device createDevice() {
RestTemplate rt = new RestTemplate();
ResponseEntity<Device> postForEntity = rt.postForEntity(new URI("http://localhost:8080/devices/"), <REQUEST_DAT>, Device.class);
return postForEntity.getBody();
}
}
But I think that is not best practice and a 'not so clean' way to do that. So my question is still the same: how to remove that /vaadinServlet information in my hateos link?
First of all, don't call your
@RestController
class methods from elsewhere other than testing.Vaadin and Spring Hateoas are two different technologies, do not mix them. In fact, your problem has nothing to do with Vaadin. Hateoas links are created from the current request. If current request is served by another servlet, then it will contain the url of that servlet for sure. You have two options here:
a) Process the received link url: remove
vaadinServlet
from it via string processing. This may seem messy but is acceptable as your intent is not the way hateoas is designed for.b) Don't use Vaadin for this task. Use JavaScript to call the appropriate endpoint and show it to the user. It will have correct links.
c) Modify
ServletRequestAttributes
object directly:RequestContextHolder.setRequestAttributes(requestAttributes)
you may need to do some java magic or use aMockHttpServletRequest
.My recommended solution would be b).
By the way, your 'edit 1' solution is not a real solution because it couples the application to localhost:8080 and ignores the current session variables including (if present) the current user.
Good luck.