在Spring hateos链接

时间:2016-04-25 14:08:16

标签: java spring spring-boot vaadin vaadin-spring-boot

我有一个spring-boot项目,提供@RestController和vaadin @SpringUI。

可以通过网址http://localhost:8080/

访问vaadin ui

通过ui用户创建设备。通过在我的vaadin类中调用我的@RestController来完成此设备创建。最后一部分是设备的创建。现在开始问题了。设备对象在其构造函数中初始化了一个hateos Link成员。使用Spring ControllerLinkBuilder完成链接创建。

问题是,hateos链接没有正确创建。链接如下所示:

"href": "http://localhost:8080/vaadinServlet/devices/1"

但是链接必须看起来像这样(没有vaadinServlet):

"href": "http://localhost:8080/devices/1"

用于创建新设备的RestController:

@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创建设备:

public class VaadinController {

    @Autowired
    private DevicesRestController devicesRestController;

    private Device createDevice() {
        Device postDevice = devicesRestController.postDevice().getBody();
        return postDevice;
    }

}

我的设备类与hateos链接

public class Device {
    private final Link self;

    public Device() {
        this.self = ControllerLinkBuilder.linkTo(DevicesRestController.class).withSelfRel();
    }

}

这么长的故事:如何摆脱Spring ControllerLinkBuilder创建的hateos链接中的/ vaadinServlet?

编辑1: 如果我不通过调用RestTemplate类来自动化我的VaadinController中的@RestController,你可以很容易地解决这个问题。请参阅以下代码剪辑:

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

}

但我认为这不是最佳做法,并且不是那么干净&#39;这样做的方法。所以我的问题仍然是一样的:如何在我的hateos链接中删除/ vaadinServlet信息?

1 个答案:

答案 0 :(得分:0)

首先,除了测试之外,不要从其他地方调用@RestController类方法。

Vaadin和Spring Hateoas是两种不同的技术,不要混用它们。事实上,你的问题与Vaadin无关。 Hateoas链接是根据当前请求创建的。如果当前请求由另一个servlet提供,那么它肯定会包含该servlet的url。你有两个选择:

a)处理收到的链接url:通过字符串处理从中删除vaadinServlet。这可能看起来很乱,但是可以接受,因为你的意图不是hateoas的设计方式。

b)不要将Vaadin用于此任务。使用JavaScript调用适当的端点并将其显示给用户。它将有正确的链接。

c)直接修改ServletRequestAttributes对象:RequestContextHolder.setRequestAttributes(requestAttributes)您可能需要做一些java魔术或使用MockHttpServletRequest

我推荐的解决方案是 b)

顺便说一下,你的'edit 1'解决方案不是一个真正的解决方案,因为它将应用程序耦合到localhost:8080并忽略当前会话变量,包括(如果存在)当前用户。

祝你好运。