完整的错误信息:
十一月 30, 2017 10:54:52 上午 org.apache.catalina.core.StandardWrapperValve invoke 严重: Servlet.service() for servlet [SpringMVC] in context with path [/smarthome] threw exception [Request processing failed; nested exception is java.nio.BufferOverflowException] with root cause java.nio.BufferOverflowException at java.nio.Buffer.nextPutIndex(Buffer.java:521) at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:169) at com.wanyu.smarthome.gateway.GatewayInstance.sendCommand(GatewayInstance.java:141) at com.wanyu.smarthome.mobile.EquipmentMobile.DeferredAdd(EquipmentMobile.java:520) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:690) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852) at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at com.wanyu.frame.base.AuthFilter.doFilter(AuthFilter.java:97) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:94) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:509) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1104) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1524) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1480) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745)这是在操作 java.nio.ByteBuffer 时出现的错误。 错误原因: 写入的长度超出了允许的长度:
例如下面的代码:
ByteBuffer params = ByteBuffer.allocate(2);// 这里只分配了2个字节,下面的params.put(tmp);却put了3个字节的数据。所以导致 java.nio.BufferOverflowException 异常 params.order(ByteOrder.LITTLE_ENDIAN); byte[] tmp = new byte[3]; tmp[0] = (byte) data1; tmp[1] = (byte) data2; tmp[2] = (byte) data3; params.put(tmp);
但实际使用中 ByteBuffer 的使用没有这么简单。
如何解决这个问题呢?
添加写入长度与 ByteBuffer 中可写入的长度的判断,例如:while (writeBuffer.remaining() > 0) { writeBuffer.put((byte)0); }
注意:你每次只写入一个字节,那就判断大于0就好了,如果不是一个记得修改条件哦!
总结
当 ByteBuffer.remaining() 小于要读取或写入的长度时,再执行读取或写入操作都会产生异常;
读取则产生 java.nio.BufferUnderflowException 异常,
写入则产生 java.nio.BufferOverflowException 异常。
当 ByteBuffer.remaining() 等于 0 时,不能再执行读取或写入操作,需要执行:clear() 操作,否则将产生异常。
你可能也会遇到这个异常:
java.nio.BufferUnderflowException