当前位置 : 主页 > 编程语言 > java >

【Java】Spring Cloud Config Server无法序列化JSON问题

来源:互联网 收集:自由互联 发布时间:2023-03-22
分析 今天说的这个异常是Spring Cloud配置中心(Config Server)拉取配置文件时引发的报错。 本次Config Server使用版本库为GitLab。在Spring Cloud相关服务在启动时会读取配置填写的GitLab地址,要

分析

今天说的这个异常是Spring Cloud配置中心(Config Server)拉取配置文件时引发的报错。

本次Config Server使用版本库为GitLab。在Spring Cloud相关服务在启动时会读取配置填写的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数据序列化就可以了。具体代码如下:

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;/** * url过滤器 */@WebFilter(filterName = "urlFilter", urlPatterns = "/*")@Order(1)@Componentpublic 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(); }}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;/** * 自定义请求包装器 */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(); } }; }}

亲测有效。

上一篇:View类的onMeasure方法介绍
下一篇:没有了
网友评论