2

我正在使用新的 spring 3.2 异步 servlet 请求。除了在这种情况下,一切都很好......

@RequestMapping("/test")
@ResponseBody
public DeferredResult<byte[]> test(InputStream is, HttpServletResponse response, WebRequest request) {
    if (someTest()) {
        deferredResult.setResult(DATA);
        return deferredResult;
    }

    deferredResult.onTimeout(new Runnable() {

        @Override
        public void run() {
            deferredResult.setResult(DATA);
        }
    });

    // Use deferredResult in another thread when needed

    return deferredResult;
}

什么时候someTest()是真的 spring/tomcat 返回 404。我不知道我应该怎么做或者为什么会发生这种情况?我认为这可能是因为已经创建了 Servlet 异步上下文。这是一个错误还是我做错了什么?

任何信息将不胜感激!

4

3 回答 3

0

我认为您需要return deferredResult从 if 条件中删除该语句。

并且 setData 也应该在 return 语句之后完成。因此,您需要从某个服务器端事件的单独线程中执行此操作。

希望这对您有所帮助。

于 2013-02-06T17:17:27.277 回答
0

我想通了,请看下面...

@RequestMapping("/test")
@ResponseBody
public DeferredResult<byte[]> test(InputStream is, HttpServletResponse response, WebRequest request) {
    if (someTest()) {
        response.getOutputStream().write(DATA);
        return null;
    }

    deferredResult.onTimeout(new Runnable() {

        @Override
        public void run() {
            deferredResult.setResult(DATA);
        }
    });

    // Use deferredResult in another thread when needed

    return deferredResult;
}

诀窍是返回 null 并将响应手动写入 ServletResponse。

希望这对其他人有用:)

于 2013-02-06T19:37:13.667 回答
0

我最近遇到了一个奇怪的问题,它404使用了一个遗留项目,DeferredResult这是一个添加@ResponseBody. 一个简单的可运行示例:

@SpringBootApplication
public class TestApp {

    public static void main(String[] args) {
        SpringApplication.run(TestApp.class, args);
    }

    @Controller
    static class Rest {

        @Autowired
        private MyService myService;

        @GetMapping("/get")
        @ResponseStatus(HttpStatus.CREATED)
        @ResponseBody // <-- with and without
        public DeferredResult<String> get() {
            return myService.go();
        }
    }

    @Service
    static class MyService {
        public DeferredResult<String> go() {

            DeferredResult<String> result = new DeferredResult<>();

            Executors.newSingleThreadExecutor().submit(() -> {
                System.out.println("starting work");
                LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(5));
                System.out.println("done with work");
                result.setResult("done");
            });

            return result;
        }
    }

}
于 2022-02-11T12:28:25.930 回答