首先这里有两个服务,一个是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