您的位置:首页 > 编程语言 > Java开发

【SpringCloud】搭建高可用分布式配置中心(Spring Cloud Config)(二)全过程详解(自动刷新)解决webhooks 400错误

2019-01-17 20:41 1291 查看
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_42684642/article/details/86530761

本文基于第一篇搭建好手动刷新的基础上进行的自动刷新。详见(一)全过程详解(手动刷新)

在搭建好第一步的手动更新的配置中心之后,要实现自动更新就很简单了。

一. config-client添加依赖

pom.xml文件中添加:

[code]        <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>

二. 配置文件application.yml文件增加配置

application.yml文件配置:

[code]spring:
rabbitmq:
host: localhost
port: 5672
username: user
password: password
cloud:
bus:
trace:
enabled: true
enabled: true

三. Gitee码云上添加webhooks

需要注意的是:

1.需要有公网ip,码云上需要使用公网ip进行访问(我使用的frp进行的内网穿透,感兴趣的同学可以自己尝试下)

2.访问地址的后缀为 /actuator/bus-refresh

如图所示,即可成功配置。

四.运行即可看到已经自动刷新配置了。

五. ERROR解决

{"timestamp":"2019-01-17T12:33:34.975+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: 326] (through reference chain: java.util.LinkedHashMap[\"commits\"])","path":"/actuator/bus-refresh"}

有不少同学配置之后却无法自动刷新,发现报400 error的错误,如图。

这是因为spring boot无法正常反序列化造成,我们需要写一个过滤器将Body直接返回为空,就可以达到过滤body的效果。

[code]@Component
public class UrlFilter  implements Filter {
@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;
HttpServletResponse httpServletResponse = (HttpServletResponse)response;

String url = new String(httpServletRequest.getRequestURI());

//只过滤/actuator/bus-refresh请求
if (!url.endsWith("/bus-refresh")) {
chain.doFilter(request, response);
return;
}

//获取原始的body
String body = readAsChars(httpServletRequest);

System.out.println("original body:   "+ body);

//使用HttpServletRequest包装原始请求达到修改post请求中body内容的目的
CustometRequestWrapper requestWrapper = new CustometRequestWrapper(httpServletRequest);

chain.doFilter(requestWrapper, response);

}

@Override
public void destroy() {

}

private 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();
}
};
}
}

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)
{
e.printStackTrace();
}
finally
{
if (null != br)
{
try
{
br.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
return sb.toString();
}
}

 再次运行项目,测试webhooks,可以发现成功返回 

 

控制台也成功打印出原来的body。

六.总结

很多人没有自动更新的原因可能就是webhooks这边出错,这个方法还是参考的https://blog.csdn.net/m0_37556444/article/details/82812816,感谢博主,这边写出来大家也一起分享下经验。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐