标题:SpringCloud Config配置WebHooks,请求反序列化异常问题
一、问题描述:
配置中心利用git WebHooks实现动态刷新时,出现如下错误:
{
"timestamp": "2019-09-06T09:53:52.651+0000",
"status": 400,
"error": "Bad Request",
"message": "JSON parse error: Cannot deserialize instance of `java.lang.String` out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_ARRAY token\n at [Source: (PushbackInputStream); line: 1, column: 316] (through reference chain: java.util.LinkedHashMap[\"commits\"])",
"path": "/actuator/refresh"
}
二、参数描述(仅供参考):
StringBoot版本:2.0.0
SpringCloud版本:F
远程仓库:gitee,(github也一样,只是延迟较高,测试中经常出现TimeOut)
我的刷新接口是 /actuator/refresh (并非bus-refresh)
management:
endpoints:
web:
exposure:
include: refresh
三、问题解决
百度看了很多指导的文章,感觉问题类似,但是无法解决具体问题,最终找到两篇值得参考的帖子,参考自:https://bbs.csdn.net/topics/392378475
https://blog.csdn.net/m0_37556444/article/details/82812816
相信有人试过用postman调用是成功,但是使用git的WebHooks调用就无法成功,是因为WebHooks发起的请求中会加入Payload,java在接受到请求后解析这串json出现异常,目的就是将这串body内容置空,代码进行了细微的修改,仅供参考,欢迎讨论。
Filter类:
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class WebhooksFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
String url = new String(httpServletRequest.getRequestURI());
//只过滤/actuator/refresh
if (!url.endsWith("/actuator/refresh")) {
filterChain.doFilter(servletRequest, httpServletResponse);
return;
}
//使用HttpServletRequest包装原始请求达到修改post请求中body内容的目的
CustomerRequestWrapper requestWrapper = new CustomerRequestWrapper(httpServletRequest);
filterChain.doFilter(requestWrapper, servletResponse);
}
@Override
public void destroy() {
}
}
Wrapper类:
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class CustomerRequestWrapper extends HttpServletRequestWrapper {
public CustomerRequestWrapper(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();
}
};
}
}
重启,问题解决。