Adr*_*yes 5 java spring websocket spring-boot
ControllerLinkBuilder.linkTo从websocket 调用时出现以下错误.
java.lang.IllegalStateException: Could not find current request via RequestContextHolder
at org.springframework.util.Assert.state(Assert.java:385)
at org.springframework.hateoas.mvc.ControllerLinkBuilder.getCurrentRequest(ControllerLinkBuilder.java:234)
at org.springframework.hateoas.mvc.ControllerLinkBuilder.getBuilder(ControllerLinkBuilder.java:186)
at org.springframework.hateoas.mvc.ControllerLinkBuilderFactory.linkTo(ControllerLinkBuilderFactory.java:117)
at org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo(ControllerLinkBuilder.java:135)
at urlshortener2014.common.web.UrlShortenerController.createAndSaveIfValid(UrlShortenerController.java:94)
at urlshortener2014.richcarmine.web.UrlShortenerControllerWithLogs.access$200(UrlShortenerControllerWithLogs.java:45)
at urlshortener2014.richcarmine.web.UrlShortenerControllerWithLogs$CreateCallable.call(UrlShortenerControllerWithLogs.java:226)
at urlshortener2014.richcarmine.massiveShortenerNaiveWS.ShortURLWSGenerator.onCall(ShortURLWSGenerator.java:41)
at urlshortener2014.richcarmine.massiveShortenerNaiveWS.ShortURLWSGenerator.onCall(ShortURLWSGenerator.java:15)
at urlshortener2014.richcarmine.massiveShortenerREST.RequestContextAwareCallable.call(RequestContextAwareCallable.java:26)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Run Code Online (Sandbox Code Playgroud)
整个项目是关于缩短网址,因为我的第一个方法是弹簧websockets我试图通过从任何网址回复缩短的网址来使其工作.
我的 TextWebSocketHandler
public class MyHandler extends TextWebSocketHandler {
AtomicLong messageOrder = new AtomicLong(0);
ExecutorService threadPool = Executors.newCachedThreadPool();
CompletionService<CSVContent> pool = new ExecutorCompletionService<>(threadPool);
/* controller reference */
@Autowired
UrlShortenerControllerWithLogs controller;
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
logger.info("WS: " + message.getPayload());
long order = messageOrder.getAndIncrement();
pool.submit(new ShortURLWSGenerator(order,message.getPayload(),"","","",session.getRemoteAddress(),controller));
CSVContent content = pool.take().get();
session.sendMessage(new TextMessage("Echo Test: " + content.getShortURL().getUri()));
}
}
Run Code Online (Sandbox Code Playgroud)
这是 ShortURLWSGenerator
public class ShortURLWSGenerator extends RequestContextAwareCallable<CSVContent>{
...
@Override
public CSVContent onCall() {
ShortURL shortURL = null;
try {
shortURL = controller. new CreateCallable(url,sponsor,brand,owner,address.toString()).call();
} catch (Exception e) {
e.printStackTrace();
}
CSVContent content = new CSVContent();
content.setOrder(order);
content.setShortURL(shortURL);
return content;
}
}
Run Code Online (Sandbox Code Playgroud)
使用RequestContextAwareCallable,它在实现与REST服务相同的功能时解决了同样的问题,在任何情况下,即使使用简单的Callable,我仍然会得到相同的错误.
这是CreateCallable,它只包含main函数
public class CreateCallable implements Callable<ShortURL>{
...
@Override
public ShortURL call() throws Exception {
/* explodes while creating the new short url */
return createAndSaveIfValid(url,sponsor,brand,owner,ip);
}
}
Run Code Online (Sandbox Code Playgroud)
最后这是createAndSaveIfValid哪个电话ControllerLinkBuilder.linkTo
protected ShortURL createAndSaveIfValid(String url, String sponsor,
String brand, String owner, String ip) {
UrlValidator urlValidator = new UrlValidator(new String[] { "http",
"https" });
if (urlValidator.isValid(url)) {
String id = Hashing.murmur3_32()
.hashString(url, StandardCharsets.UTF_8).toString();
ShortURL su = new ShortURL(id, url,
linkTo(
methodOn(UrlShortenerController.class).redirectTo(
id, null)).toUri(), sponsor, new Date(
System.currentTimeMillis()), owner,
HttpStatus.TEMPORARY_REDIRECT.value(), true, ip, null);
return shortURLRepository.save(su);
} else {
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
完整的项目可以在github上找到
Rob*_*ain 30
在一个密切相关的说明中,对于那些单元测试它们的具体ResourceAssemblerSupport实现,并体验相同的堆栈跟踪,这里是如何模拟它:
@Before
public void setup() {
HttpServletRequest mockRequest = new MockHttpServletRequest();
ServletRequestAttributes servletRequestAttributes = new ServletRequestAttributes(mockRequest);
RequestContextHolder.setRequestAttributes(servletRequestAttributes);
}
@After
public void teardown() {
RequestContextHolder.resetRequestAttributes();
}
Run Code Online (Sandbox Code Playgroud)
小智 7
linkTo取决于当前的HTTP请求,但HTTP当前请求不存在,因为该调用是由WebSocket事件发起的.因此,您需要一种不同的方法.
创建一个名为方法例如createAndSaveIfValidExtended根据createAndSaveIfValid.代码相同但linkTo(methodOn(UrlShortenerController.class).redirectTo(id, null)).toUri()由方法替换createLink(id)
创建一个方法String createLink(String id).此方法将使用在application.properties(请参阅此处如何)中定义的属性来构建URL,该属性的值将在一个字段中注入,该字段表示将部署应用程序的位置/l和值ìd.
在CreateCallable,打电话createAndSaveIfValidExtended而不是createAndSaveIfValid
| 归档时间: |
|
| 查看次数: |
5240 次 |
| 最近记录: |