【GitLab】Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableExcep

青旅半醒 2024-04-18 17:30 138阅读 0赞

问题:

这个是在Spring Cloud配置中心(Config Server)拉取配置文件时引起的报错。

公司Config Server使用的版本库是GitLab。在启动时会访问微服务配置的GitLab地址,正常的情况下在GitLab中需要配置Webhooks信息,系统访问GitLab后会对Webhooks配置地址进行回调处理,报错就发生在微服务解析回调信息时,报错内容如下:

  1. Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse
  2. error: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token; nested exception is
  3. com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of
  4. `java.lang.String` out of START_OBJECT token at [Source: (PushbackInputStream); line: 1, column: 449]
  5. (through reference chain: java.util.LinkedHashMap["project"])

解决:

这个错误是因为GitLab11.10之后,使用Webhook返回响应JSON对象无法使用Jackson进行反序列化导致。

因此只需要在Spring Cloud配置中心(Config Server)中增加过滤器进行JSON数据序列化就可以了。

UrlFilter.java

  1. package io.yzh.component.filter;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import javax.servlet.Filter;
  5. import javax.servlet.FilterChain;
  6. import javax.servlet.FilterConfig;
  7. import javax.servlet.ServletException;
  8. import javax.servlet.ServletRequest;
  9. import javax.servlet.ServletResponse;
  10. import javax.servlet.annotation.WebFilter;
  11. import javax.servlet.http.HttpServletRequest;
  12. import org.slf4j.Logger;
  13. import org.slf4j.LoggerFactory;
  14. import org.springframework.core.annotation.Order;
  15. import org.springframework.stereotype.Component;
  16. import io.yzh.component.wrapper.CustometRequestWrapper;
  17. /** * @Function url过滤器 */
  18. @WebFilter(filterName = "urlFilter", urlPatterns = "/*")
  19. @Order(1)
  20. @Component
  21. public class UrlFilter implements Filter {
  22. public static final Logger logger = LoggerFactory.getLogger(UrlFilter.class);
  23. @Override
  24. public void init(FilterConfig filterConfig) throws ServletException {
  25. }
  26. @Override
  27. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  28. HttpServletRequest httpServletRequest = (HttpServletRequest) request;
  29. String url = new String(httpServletRequest.getRequestURI());
  30. // 只过滤/actuator/bus-refresh请求
  31. if (!url.endsWith("/bus-refresh")) {
  32. chain.doFilter(request, response);
  33. return;
  34. }
  35. CustometRequestWrapper requestWrapper = new CustometRequestWrapper(httpServletRequest);
  36. chain.doFilter(requestWrapper, response);
  37. }
  38. @Override
  39. public void destroy() {
  40. }
  41. /** * 以char形式读取 * * @param request * @return */
  42. public static String readAsChars(HttpServletRequest request) {
  43. BufferedReader br = null;
  44. StringBuilder sb = new StringBuilder("");
  45. try {
  46. br = request.getReader();
  47. String str;
  48. while ((str = br.readLine()) != null) {
  49. sb.append(str);
  50. }
  51. br.close();
  52. } catch (IOException e) {
  53. logger.info(" --------- An exception occurred : " + e.getMessage() + " --------- ");
  54. } finally {
  55. if (null != br) {
  56. try {
  57. br.close();
  58. } catch (IOException e) {
  59. logger.info(" --------- An exception occurred : " + e.getMessage() + " --------- ");
  60. }
  61. }
  62. }
  63. return sb.toString();
  64. }
  65. }

CustometRequestWrapper.java

  1. package io.yzh.component.wrapper;
  2. import java.io.ByteArrayInputStream;
  3. import java.io.IOException;
  4. import javax.servlet.ReadListener;
  5. import javax.servlet.ServletInputStream;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletRequestWrapper;
  8. /** * @Function 自定义请求包装器 */
  9. public class CustometRequestWrapper extends HttpServletRequestWrapper {
  10. public CustometRequestWrapper(HttpServletRequest request) {
  11. super(request);
  12. }
  13. /** * 以流输出 */
  14. @Override
  15. public ServletInputStream getInputStream() throws IOException {
  16. byte[] bytes = new byte[0];
  17. ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
  18. return new ServletInputStream() {
  19. @Override
  20. public boolean isFinished() {
  21. return byteArrayInputStream.read() == -1 ? true : false;
  22. }
  23. @Override
  24. public boolean isReady() {
  25. return false;
  26. }
  27. @Override
  28. public void setReadListener(ReadListener readListener) {
  29. }
  30. @Override
  31. public int read() throws IOException {
  32. return byteArrayInputStream.read();
  33. }
  34. };
  35. }
  36. }

发表评论

表情:
评论列表 (有 0 条评论,138人围观)

还没有评论,来说两句吧...

相关阅读