protobuf接口调用报错:java.nio.charset.MalformedInputException: Input length = 1
使用protobuf定义的接口api发起http请求报错,日志如下:
- [-- ::] DEBUG AbstractPool: - server updated, node=10.211.95.79:, server={ node: 10.211.95.79:, hostname: 10.211.95.79, port: , status: , weight: , capacity: , breaker: { state :CLOSED, working: , delay: , failureThreshold: [/, 0.8], successThreshold: [/, 0.75]}, version: }
- [-- ::] DEBUG EnvironmentInterceptor: - EnvironmentInterceptor.preHandle requesturl:http://127.0.0.1:8080/ms-search-war/ms.search.searchService/getSearchRank
- [-- ::] DEBUG EnvironmentInterceptor: - RequestHeads,User-Agent=Apache-HttpClient/4.1. (java 1.5),X-Identity-ID=,X-Auth-Token=,X-Login-Type=
- [-- ::] ERROR ServletRequestParser: - IOException: request=/ms-search-war/ms.search.searchService/getSearchRank, ex=java.nio.charset.MalformedInputException: Input length =
- [-- ::] DEBUG EnvironmentInterceptor: - EnvironmentInterceptor completed, requesturl= http://127.0.0.1:8080/ms-search-war/ms.search.searchService/getSearchRank and server delayTime = 141
我们来看ServletRequestParser的报错代码行:
- import java.io.IOException;
- import java.math.BigDecimal;
- import javax.servlet.http.HttpServletRequest;
- import javax.xml.bind.DatatypeConverter;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.http.HttpMethod;
- import org.springframework.http.MediaType;
- import com.google.protobuf.ByteString;
- import com.google.protobuf.Descriptors;
- import com.google.protobuf.InvalidProtocolBufferException;
- import com.google.protobuf.Message;
- import com.google.protobuf.util.JsonFormat;
- public class ServletRequestParser {
- private static final Logger logger = LoggerFactory.getLogger(ServletRequestParser.class);
- public static Message parse(HttpServletRequest request, Message prototype) {
- String requestMethod = request.getMethod();
- Descriptors.Descriptor inputType = prototype.getDescriptorForType();
- Message.Builder builder = prototype.newBuilderForType();
- if (HttpMethod.POST.matches(requestMethod)) {
- MediaType contentType = ContentType.BINARY;
- try {
- contentType = MediaType.valueOf(request.getContentType());
- } catch (Exception ex) {
- }
- try {
- if (ContentType.isProtobuf(contentType) || ContentType.isBinary(contentType)) {
- return builder.mergeFrom(request.getInputStream()).build();
- } else if (ContentType.isJson(contentType)) {
- request.setCharacterEncoding("utf-8");
- JsonFormat.parser().merge(request.getReader(), builder);
- return builder.build();
- } else {
- logger.error("invalid content-type: {}", contentType);
- }
- } catch (InvalidProtocolBufferException ex) {
- logger.error("InvalidProtocolBuffer: request={}, ex={}", request.getRequestURI(), ex);
- } catch (IOException ex) {
- logger.error("IOException: request={}, ex={}", request.getRequestURI(), ex);
- }
- } else if (HttpMethod.GET.matches(requestMethod)) {
- for (Descriptors.FieldDescriptor field : inputType.getFields()) {
- String[] values = request.getParameterValues(field.getName());
- if (null != values && values.length > 0) {
- if (!field.isRepeated()) {
- Object o = parseFieldValue(field, values[0], builder);
- if (null != o) builder.setField(field, o);
- } else {
- for (String value : values) {
- Object o = parseFieldValue(field, value, builder);
- if (null != o) builder.addRepeatedField(field, o);
- }
- }
- }
- }
- return builder.build();
- }
- return null;
- }
这里调用了com.google.protobuf.util.JsonFormat的内部类Parser的merge方法进行转换时报错,因为异常只在这里抛出,所以只能怀疑获取Reader对象的这个request.getReader()方法,跟进代码:
- /**
- * Wrapper object for the Coyote request.
- *
- * @author Remy Maucherat
- * @author Craig R. McClanahan
- */
- public class Request implements org.apache.catalina.servlet4preview.http.HttpServletRequest {
- /**
- * Read the Reader wrapping the input stream for this Request. The
- * default implementation wraps a <code>BufferedReader</code> around the
- * servlet input stream returned by <code>createInputStream()</code>.
- *
- * @return a buffered reader for the request
- * @exception IllegalStateException if <code>getInputStream()</code>
- * has already been called for this request
- * @exception IOException if an input/output error occurs
- */
- @Override
- public BufferedReader getReader() throws IOException {
- if (usingInputStream) {
- throw new IllegalStateException
- (sm.getString("coyoteRequest.getReader.ise"));
- }
- usingReader = true;
- inputBuffer.checkConverter();
- if (reader == null) {
- reader = new CoyoteReader(inputBuffer);
- }
- return reader;
- }
这里调用的是catalina的Requst对象的getReader方法,返回的是一个BufferedReader对象,这里最终实例化出了一个CoyoteReader对象。
- /**
* Reader.
*/
protected CoyoteReader reader = new CoyoteReader(inputBuffer);
我们来看下CoyoteReader对象:
- /**
- * Coyote implementation of the buffered reader.
- *
- * @author Remy Maucherat
- */
- public class CoyoteReader
- extends BufferedReader {
- // -------------------------------------------------------------- Constants
- private static final char[] LINE_SEP = { '\r', '\n' };
- private static final int MAX_LINE_LENGTH = 4096;
- // ----------------------------------------------------- Instance Variables
- protected InputBuffer ib;
- protected char[] lineBuffer = null;
- // ----------------------------------------------------------- Constructors
- public CoyoteReader(InputBuffer ib) {
- super(ib, 1);
- this.ib = ib;
- }
- }
再看下它里面的InputBuffer对象:
- /**
- * The buffer used by Tomcat request. This is a derivative of the Tomcat 3.3
- * OutputBuffer, adapted to handle input instead of output. This allows
- * complete recycling of the facade objects (the ServletInputStream and the
- * BufferedReader).
- *
- * @author Remy Maucherat
- */
- public class InputBuffer extends Reader
- implements ByteChunk.ByteInputChannel, ApplicationBufferHandler {
- /**
- * The string manager for this package.
- */
- protected static final StringManager sm = StringManager.getManager(InputBuffer.class);
- private static final Log log = LogFactory.getLog(InputBuffer.class);
- public static final int DEFAULT_BUFFER_SIZE = 8 * 1024;
- // The buffer can be used for byte[] and char[] reading
- // ( this is needed to support ServletInputStream and BufferedReader )
- public final int INITIAL_STATE = 0;
- public final int CHAR_STATE = 1;
- public final int BYTE_STATE = 2;
- /**
- * Encoder cache.
- */
- private static final ConcurrentMap<Charset, SynchronizedStack<B2CConverter>> encoders = new ConcurrentHashMap<>();
- // ----------------------------------------------------- Instance Variables
- /**
- * The byte buffer.
- */
- private ByteBuffer bb;
- /**
- * The char buffer.
- */
- private CharBuffer cb;
- /**
- * State of the output buffer.
- */
- private int state = 0;
- /**
- * Flag which indicates if the input buffer is closed.
- */
- private boolean closed = false;
- /**
- * Encoding to use.
- */
- private String enc;
- /**
- * Current byte to char converter.
- */
- protected B2CConverter conv;
- /**
- * Associated Coyote request.
- */
- private Request coyoteRequest;
- /**
- * Buffer position.
- */
- private int markPos = -1;
- /**
- * Char buffer limit.
- */
- private int readLimit;
- /**
- * Buffer size.
- */
- private final int size;
- // ----------------------------------------------------------- Constructors
- /**
- * Default constructor. Allocate the buffer with the default buffer size.
- */
- public InputBuffer() {
- this(DEFAULT_BUFFER_SIZE);
- }
- /**
- * Alternate constructor which allows specifying the initial buffer size.
- *
- * @param size Buffer size to use
- */
- public InputBuffer(int size) {
- this.size = size;
- bb = ByteBuffer.allocate(size);
- clear(bb);
- cb = CharBuffer.allocate(size);
- clear(cb);
- readLimit = size;
- }
- }
通过调试发现,当我的请求里没有中文时,CoyoteReader对象的InputBuffer属性的ByteBuffer的hb属性是能取到请求消息体的,而包含了中文则无法获取,protobuf直接转换报错了。
protobuf接口调用报错:java.nio.charset.MalformedInputException: Input length = 1的更多相关文章
- scala文件读取报错“java.nio.charset.MalformedInputException: Input length = 1”
今天写spark程序的时候遇到了一个问题就是,读取文件的时候报了一个错:“Exception in thread "main" java.nio.charset.Malformed ...
- windows中文编码报错 com.google.gson.JsonIOException: java.nio.charset.MalformedInputException: Input length = 1
昨天碰到一个问题:同一个请求页面,页面经过匹配后调用http的post协议接口,部署在linux环境的没问题,本地Eclipse启动的tomcat也没问题,直接启动本地tomcat却报错了: 18:4 ...
- org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length = 1
项目启动报错2018-12-21 14:06:24.917 INFO 23472 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refr ...
- 我的Java开发学习之旅------>Java NIO 报java.nio.charset.MalformedInputException: Input length = 1异常
今天在使用Java NIO的Channel和Buffer进行文件操作时候,报了java.nio.charset.MalformedInputException: Input length = 1异常, ...
- Caused by: java.nio.charset.MalformedInputException: Input length = 1
java.lang.IllegalStateException: Failed to load property source from location 'classpath:/applicatio ...
- [bug] org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length = 2
原因 SpringBoot启动加载yml配置文件出现编码格式错误 参考 https://www.pianshen.com/article/2431144034/
- 转载:回编译APK出错:java.nio.char set.MalformedInputException: Input length = 1
使用APKtool回编译APK,出现错误如下: Exception in thread "main" org.yaml.snakeyaml.error.YAMLExcepti ...
- dubbo 使用zookeeper 出现 Dubbo客户端调用报错NullPointerException
现在将网上的方法总结一下 方法一:.https://blog.csdn.net/u011294519/article/details/81810631 dubbo-provider.xml:提供者先扫 ...
- springcloud采坑--Zuul上传文件报java.nio.charset.IllegalCharsetNameException: UTF-8;boundary=sqgzzmMxl1UPdIp0IAYnQgUIAr9yNewVAzKIX
报错日志: 2018-12-17 10:01:19,688 ERROR [io.undertow.request] (default task-3) UT005023: Exception handl ...
随机推荐
- Xcode各版本
官方下载, 用开发者账户登录,建议用Safari浏览器下载. 官方下载地址: https://developer.apple.com/xcode/downloads/ Xcode 7 beta 3:h ...
- 015PHP基础知识——流程控制(三)
<?php /** *流程控制(三) */ /* 循环结构: while(){ } */ //设置脚本最长执行时间:100秒 //set_time_limit(100); $lantian = ...
- 模式窗体中调用父页面js与非模式化调用非父页面的js方法
最近项目中使用模式窗体,遇到以下问题记录一下: 模式窗体:你必须关闭该窗体,才能操作其它窗体:比如说,必须按确定或取消,或者按关闭. 非模式窗体:不必关闭该窗体,就可转换到其它窗体上进行操作. 一:非 ...
- WIFI 基础知识
转载自:wifi基本知识 如侵犯您的版权,请联系:2378264731@qq.com 1. IE802.11简介 标准号 IEEE 802.11b IEEE 802.11a IEEE 802.11g ...
- Python中注释的添加
1.Python中注释,有助于我们对程序的理解:但注释不需要每行都写,可以在方法前面注释该方法的功能 或重要的一行进行注释. 2.单行注释,使用#号: 3.多行注释,使用""&qu ...
- functools 和 itertools
functools 补充 1 wraps 在编写装饰器时,在实现前加入 @functools.wraps(func) 可以保证装饰器不会对被装饰函数造成影响.wraps 保存被装饰函数的原信息 def ...
- ICE实现服务器客户端
本文将结合实际项目,做一个基于ice的实际项目实例应用,该实例完成客户端调用服务端接口完成消息发送,计算的功能.1,创建java项目ICEServer,导入ice.jar. 2,在项目下创建slice ...
- js之留言字数限制
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- a链接嵌套无效,嵌套链接最优解决办法
<a>不支持嵌套.例如: <a href="#1">11111111111<a href="#2">22222222222& ...
- POJ3068 "Shortest" pair of paths 【费用流】
POJ3068 "Shortest" pair of paths Description A chemical company has an unusual shortest pa ...