2

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

可以通过 url 访问 vaadin ui:http://localhost:8080/

通过 ui 用户创建设备。这个设备创建是通过在我的 vaadin 类中调用我的 @RestController 来完成的。最后一部分是设备的创建。现在开始问题了。设备对象在其构造函数中初始化了一个 hatos 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;
    }

}

我的设备类与 hatos 链接

public class Device {
    private final Link self;

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

}

长话短说:如何摆脱 Spring ControllerLinkBuilder 创建的 hatos 链接中的 /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();
    }

}

但我认为这不是最佳做法,也是一种“不那么干净”的方式。所以我的问题还是一样:如何在我的 hatos 链接中删除 /vaadinServlet 信息?

4

1 回答 1

0

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

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

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

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

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

我推荐的解决方案是b)

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

祝你好运。

于 2016-05-04T11:30:28.953 回答