项目框架:SpringMVC

最近项目中用到视频播放,打算采用html5 的video标签实现网页视频播放,考虑到兼容性与样式又采用了jquery的video.js插件,使用过程中视频播放都没问题,但是在视频播放的时候运行容器(jetty、tomcat)都会报IO异常:

tomcat:

2017-07-04 12:24:57,167 [http-nio-8888-exec-9] ERROR com.icinfo.framework.core.web.handler.GlobalHandlerExceptionResolver - java.io.IOException: Broken pipe
org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
        at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:393)
        at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:426)
        at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:339)
        at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:418)
        at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:406)
        at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:97)
        at org.springframework.util.StreamUtils.copy(StreamUtils.java:127)
        at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.writeContent(ResourceHttpRequestHandler.java:443)
        at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest(ResourceHttpRequestHandler.java:268)

jetty:下报的是IO异常下的EofException;


百度了下知道EofException是内部类BlockDataInputStream.的方法peekByte抛出的异常,意思就是到达了文件的末尾,程序却没有正常结束读取文件内容。

结合前台查看视频文件的加载方式(分段流加载),而错误总是出现在刷新页面或者来回点击进度条的时候,所以猜测是客户端关闭导致流的输出未正常结束而导致的错误,问了下架构师说可能跟服务器有关系,暂时无法解决,但是日志老是打出那么一大堆错误也很蛋疼,于是我就改写了框架的总体异常过滤器将异常过滤掉:

public class NdrcGlobalHandlerExceptionResolver extends
        DefaultHandlerExceptionResolver {

    private static final Logger logger = LoggerFactory.getLogger(NdrcGlobalHandlerExceptionResolver.class);

    @Override
    protected ModelAndView doResolveException(HttpServletRequest request,
                                              HttpServletResponse response, Object handler, Exception ex) {
        if(!(ex instanceof IOException)){
        logger.error(ex.getMessage(), ex);}
        //错误编码
        String errorCode = "";
        //错误信息
        String errorMsg = ex.getMessage();
        //EofException则忽略
        if(ex instanceof IOException){
            Map<String, Object> model = new HashMap<String, Object>();
            model.put("ex", ex);
            return new ModelAndView();
        }
        //判断是否框架异常
        if (ex instanceof GenericException) {
            GenericException be = (GenericException) ex;
            errorCode = be.getErrorCode();
            errorMsg = be.getMessage();
        }
        //Ajax请求处理
        if (WebUtils.isAjax(request)) {
            try {
                response.setContentType("application/json");
                response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
                AjaxResult result = AjaxResult.error(errorCode, errorMsg);
                //转成json格式
                ObjectMapper mapper = new ObjectMapper();
                String json = mapper.writeValueAsString(result);

                PrintWriter pw = response.getWriter();
                pw.write(json);
                pw.close();
            } catch (Exception e) {
                logger.error(errorMsg, e);
            }
            return null;
        } else {
            // 跳转到异常页面
            Map<String, Object> model = new HashMap<String, Object>();
            model.put("ex", ex);
            return new ModelAndView("error", model);
        }
    }
}

并在spring配置文件里面将处理类重新指定:

    <!-- 异常视图处理 -->
    <bean id="exceptionResolver"
class="com.icinfo.ndrc.support.NdrcGlobalHandlerExceptionResolver">
        <!-- 设置日志输出级别,不定义则默认不输出警告等错误日志信息 -->
        <property name="warnLogCategory" value="WARN"></property>
    </bean>
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐