【岁月留声(GitLab)】org.springframework.http.converter.HttpMessageNotReadableExcep
Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parseerror: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token; nested ..
·
问题:
这个是在Spring Cloud配置中心(Config Server)拉取配置文件时引起的报错。
公司Config Server使用的版本库是GitLab。在启动时会访问微服务配置的GitLab地址,正常的情况下在GitLab中需要配置Webhooks信息,系统访问GitLab后会对Webhooks配置地址进行回调处理,报错就发生在微服务解析回调信息时,报错内容如下:
Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse
error: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token; nested exception is
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of
`java.lang.String` out of START_OBJECT token at [Source: (PushbackInputStream); line: 1, column: 449]
(through reference chain: java.util.LinkedHashMap["project"])
解决:
这个错误是因为GitLab11.10之后,使用Webhook返回响应JSON对象无法使用Jackson进行反序列化导致。
因此只需要在Spring Cloud配置中心(Config Server)中增加过滤器进行JSON数据序列化就可以了。
UrlFilter.java
package io.yzh.component.filter;
import java.io.BufferedReader;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import io.yzh.component.wrapper.CustometRequestWrapper;
/**
* @Function url过滤器
*/
@WebFilter(filterName = "urlFilter", urlPatterns = "/*")
@Order(1)
@Component
public class UrlFilter implements Filter {
public static final Logger logger = LoggerFactory.getLogger(UrlFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String url = new String(httpServletRequest.getRequestURI());
// 只过滤/actuator/bus-refresh请求
if (!url.endsWith("/bus-refresh")) {
chain.doFilter(request, response);
return;
}
CustometRequestWrapper requestWrapper = new CustometRequestWrapper(httpServletRequest);
chain.doFilter(requestWrapper, response);
}
@Override
public void destroy() {
}
/**
* 以char形式读取
*
* @param request
* @return
*/
public static String readAsChars(HttpServletRequest request) {
BufferedReader br = null;
StringBuilder sb = new StringBuilder("");
try {
br = request.getReader();
String str;
while ((str = br.readLine()) != null) {
sb.append(str);
}
br.close();
} catch (IOException e) {
logger.info(" --------- An exception occurred : " + e.getMessage() + " --------- ");
} finally {
if (null != br) {
try {
br.close();
} catch (IOException e) {
logger.info(" --------- An exception occurred : " + e.getMessage() + " --------- ");
}
}
}
return sb.toString();
}
}
CustometRequestWrapper.java
package io.yzh.component.wrapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
* @Function 自定义请求包装器
*/
public class CustometRequestWrapper extends HttpServletRequestWrapper {
public CustometRequestWrapper(HttpServletRequest request) {
super(request);
}
/**
* 以流输出
*/
@Override
public ServletInputStream getInputStream() throws IOException {
byte[] bytes = new byte[0];
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return byteArrayInputStream.read() == -1 ? true : false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
}
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献4条内容
所有评论(0)