关于spring cloud bus client无法自动刷新问题(版本:Greenwich.SR1)

首先这里有两个服务,一个是config server,一个是config client,主要目的是通过消费消息队列中的消息(远端git配置文件更改的消息)来进行通过spring cloud bus实现自动刷新,但是期间遇到了一些问题,以此记录。

我用的是github,然后通过添加webhook来访问config server的/actuator/bus-refresh接口,一开始用了monitor这个接口,发现config server确实自动刷新了,但是config client没有,然后换回/actuator/bus-refresh的接口。此时出现了

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 

出现这种错误是因为github访问该接口时的载荷无法序列化。

我上网查看大佬们的博客找到两个方法,一个通过拦截器改变http请求的内容,一个是转发接口

第一种:

新建一个httpRequestWrapper,然后改写里面的读取流的方法,使他读取为空

package com.gdut.clouddemo.config.request;

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;

/**
 * @author lulu
 * @Date 2019/7/1 22:50
 */
public class FilterPayLoadWrapper extends HttpServletRequestWrapper {
    public FilterPayLoadWrapper(HttpServletRequest request) {

        super(request);
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final byte[] bytes = new byte[0];
        final 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();
            }
        };
    }
}

filter类:

package com.gdut.clouddemo.config.filter;

import com.gdut.clouddemo.config.request.FilterPayLoadWrapper;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * @author lulu
 * @Date 2019/7/1 22:51
 */
@Component
@ServletComponentScan
@WebFilter(urlPatterns = "/actuator/bus-refresh",filterName = "githubFilter")
public class GitHubHttpFilter implements Filter{




    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request=(HttpServletRequest)servletRequest;
            filterChain. doFilter(new FilterPayLoadWrapper(request),servletResponse);

    }

    @Override
    public void destroy() {

    }
}

这样对actuator/bus-refresh的路径进行拦截并构造一个有空的body的request

webhook添加地址如,这里要根据自己的配置。

http://1917n859t5.iok.la:36391/actuator/bus-refresh

==========================================================================================

第二种,就是转发的方法,定义一个restTemplate,这里的服务要有@EnableDiscoveryClient才可以给restTemplate发现,然后webhook里面填的地址为转发的地址。

package com.gdut.clouddemo.config.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @author lulu
 * @Date 2019/7/1 22:14
 */
@Configuration
public class RestTemplateConfig {

    @Bean
    @LoadBalanced
    public RestTemplate template(){
        return new RestTemplate();
    }
}
package com.gdut.clouddemo.config.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/config")
public class ConfigController {

    @Autowired
    private RestTemplate restTemplate;

    @PostMapping("/refresh")
    public Map refresh() {
        Map map = new HashMap<>();
        restTemplate.postForObject("http://config/actuator/bus-refresh", map, Map.class);
        map.put("code", 0);
        return map;
    }
}

webhook地址改为:

http://1917n859t5.iok.la:36391/config/refresh

 

你可能感兴趣的:(bug)