1. 程式人生 > >Cannot forward to error page for request [/wechat/portal] as the response has already been commit

Cannot forward to error page for request [/wechat/portal] as the response has already been commit

1、問題描述

最近使用Spring Boot搭建 web 框架過程中遇到這樣一個問題:該介面接收微信伺服器的簽名校驗,但是請求的時候報了ERROR。

2018-05-30 13:56:14.265 ERROR - Cannot forward to error page for request 
[/wechat/portal/hdd] as the response has already been committed. As a 
result, the response may have the wrong status code. If your application 
is running on WebSphere Application Server you may be able to resolve this
problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false (o.s.boot.web.support.ErrorPageFilter:210) [http-nio-8080-exec-6]

2、解決方案

看日誌提示是需要設定com.ibm.ws.webcontainer.invokeFlushAfterService為false。

    @Bean
    public ErrorPageFilter errorPageFilter() {
        return new
ErrorPageFilter(); } @Bean public FilterRegistrationBean disableSpringBootErrorFilter(ErrorPageFilter filter) { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter(filter); filterRegistrationBean.setEnabled(false
); return filterRegistrationBean; }
  1. 改完後重新部署,的確不報ERROR了,但是介面報404。
  2. 此時各位可以檢查自己的Url是否正確,我的情況是:
  3. 介面url沒錯,並且remote debug可以進去,也能正常return,但是檢視localhost_access_log也確實404,可以說是千奇百怪了。

3、深入挖掘

貼上介面程式碼:

@GetMapping(produces = "text/plain;charset=utf-8")
    public String authGet(@RequestParam(name = "signature", required = false) String signature,
                          @RequestParam(name = "timestamp", required = false) String timestamp,
                          @RequestParam(name = "nonce", required = false) String nonce,
                          @RequestParam(name = "echostr", required = false) String echostr) {
        return authGet(signature, timestamp, nonce, echostr, null);
    }

    @ResponseBody
    @GetMapping(value = "/{channel}", produces = "text/plain;charset=utf-8")
    public String authGet(@RequestParam(name = "signature", required = false) String signature,
                          @RequestParam(name = "timestamp", required = false) String timestamp,
                          @RequestParam(name = "nonce", required = false) String nonce,
                          @RequestParam(name = "echostr", required = false) String echostr,
                          @PathVariable(name = "channel") String channel) {
        log.info("\n接收到來自微信伺服器的認證訊息 [{}, {}, {}, {},{}]", signature, timestamp, nonce, echostr, channel);

        if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
            throw new IllegalArgumentException("請求引數非法,請核實!");
        }

        WxMpService wxMpService = oldHxWeChatService;
        if (channel != null) {
            wxMpService = hxWeChatService;
        }
        if (wxMpService.checkSignature(timestamp, nonce, signature)) {
            return echostr;
        }

        return "非法請求";
    }

解決方案:使用response輸出流或@ResponseBody

  1. response.getWriter().print(echostr);
  2. @responseBody註解的作用是將controller的方法返回的物件通過適當的轉換器轉換為指定的格式之後,寫入到response物件的body區,通常用來返回JSON資料或者是XML資料,需要注意的呢,在使用此註解之後不會再走試圖處理器,而是直接將資料寫入到流中,他的效果等同於通過response物件輸出指定格式的資料。
  3. 因此可知之前直接使用return echostr spring會找不到對應的檢視,但是檢視找不到,spring又轉到errorPage,但是專案中沒有配置errorPage,從而404.