目录
七、打包、部署运行报错【no main manifest attribute, in /ms-eureka.jar】
一、SpringBoot 与 eureka适配性问题
1、结论:
1)、在SpringBoot1.x下,引入的eureka依赖: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> <version>1.4.6.RELEASE</version> </dependency> ----------------------------------------------------------------------------------------- 2)、在SpringBoot2.x下,引入的eureka依赖: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> <version>2.1.0.RELEASE</version> </dependency> -----------------------------------------------------------------------------------------
二、SpringBoot 与 Feign 适配性问题。
1、结论:
1)、在SpringBoot1.x下,引入的feign依赖: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> <version>1.4.6.RELEASE</version> </dependency> ----------------------------------------------------------------------------------------- 2)、在SpringBoot2.x下,引入的feign依赖: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.1.0.RELEASE</version> </dependency> ----------------------------------------------------------------------------------------- 3)、备注: 在spring boot2.x下,Spring Cloud对Feign的支持由 spring-cloud-netflix-core --> spring-cloud-openfeign-core, 而Finchley.M9版本下的 spring-cloud-starter-openfeign:2.0.0.M2 的pom依赖文件中导入的是spring-cloud-netflix-core而非spring-cloud-openfeign-core。故上述第二点需注意对版本的控制。
2、参考博客:
三、SpringBoot 与 Zuul适配性问题
1、结论:
1)、在SpringBoot1.x下,引入的zuul依赖: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> <version>1.4.6.RELEASE</version> </dependency> ----------------------------------------------------------------------------------------- 2)、在SpringBoot2.x下,引入的zuul依赖: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> <version>2.1.0.RELEASE</version> </dependency> -----------------------------------------------------------------------------------------
四、Feign 内部调用超时。
1、报错信息:
feign.RetryableException: Read timed out executing POST ***** …… java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) ~[na:1.8.0_25] at java.net.SocketInputStream.read(Unknown Source) ~[na:1.8.0_25] at java.net.SocketInputStream.read(Unknown Source) ~[na:1.8.0_25] at java.io.BufferedInputStream.fill(Unknown Source) ~[na:1.8.0_25] at java.io.BufferedInputStream.read1(Unknown Source) ~[na:1.8.0_25] at java.io.BufferedInputStream.read(Unknown Source) ~[na:1.8.0_25] at sun.net.www.http.HttpClient.parseHTTPHeader(Unknown Source) ~[na:1.8.0_25] ……
2、环境说明:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.1.0.RELEASE</version> </dependency>
3、解决方案:
@Configuration public class FeignConfig { public static int connectTimeoutMills = 60000; public static int readTimeoutMills = 60000; @Bean public Request.Options options(){ return new Request.Options(connectTimeoutMills, readTimeoutMills); } @Bean public Retryer feignRetryer(){ return new Retryer.Default(); } }
4、参考博客:
五、Feign 传递token
1、原理:设置拦截器,将postman中的请求头,原封不动的封装到feign的调用请求中去。
2、代码如下:
@Configuration public class FeignInterceptor implements RequestInterceptor{ @Override public void apply(RequestTemplate requestTemplate) { HttpServletRequest request = getHttpRequest(); if(Objects.isNull(request)){ return; } Map<String, String> headers = getHeaders(request); if(headers.size() > 0){ for(Map.Entry<String, String> entry : headers.entrySet()){ requestTemplate.header(entry.getKey(), entry.getValue()); } } } private HttpServletRequest getHttpRequest(){ try { return ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest(); } catch (IllegalStateException e) { return null; } } private Map<String, String> getHeaders(HttpServletRequest request){ Map<String, String> map = new LinkedHashMap<>(); Enumeration<String> headerNames = request.getHeaderNames(); while(headerNames.hasMoreElements()){ String key = headerNames.nextElement(); map.put(key, request.getHeader(key)); } return map; } }
六、Feign 消费端传参List<String>报错
1、报错信息:
feign.FeignException: status 500 reading FeignOrderInterface#****方法名****(List) at feign.FeignException.errorStatus(FeignException.java:78) at feign.codec.ErrorDecoder$Default.decode(ErrorDecoder.java:93) at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:149) at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78) at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) at com.sun.proxy.$Proxy146.findProgramOrderByTechnicianIdList(Unknown Source) at com.ywkj.spa.accounts.Demo2.method9(Demo2.java:279) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at
2、解决方案:
1)方案一:将服务端和消费端,参数List改为数组传递和接收,即可解决。List<String> strList --> String[] arr。
附上转换代码:
List<String> techList = new ArrayList<>(); techList.add("02"); techList.add("03"); String[] techArr = techList.toArray(new String[techList.size()]);
2)方案二:服务端改为对象接收,对象中声明属性List<String> tempList。消费端依旧以List<String> tempList形式传输。
七、打包、部署运行报错【no main manifest attribute, in /ms-eureka.jar】
1、现象描述:SpringCloud多模块打包,打包的jar包只有几k,jar包无法运行,运行报错:no main manifest attribute, in /ms-eureka.jar
2、解决方案:子模块pom文件中添加如下如下插件。【父级pom中不需要指定plugin】
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <!-- 指定该Main Class为全局的唯一入口 --> <mainClass>com.ywkj.spa.mall.SpaMallApplication</mainClass> <layout>ZIP</layout> </configuration> <executions> <execution> <goals> <!--可以把依赖的包都打包到生成的Jar包中--> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
八、authorization请求头经过zuul转发后丢失
1、解决方案:配置文件中添加如下代码(等号后不跟任何东西)
zuul.sensitive-headers=
2、过程分析:Zuul进行路由转发时,RibbonRoutingFilter过滤器,对请求参数和请求头进行了重新过滤和组装
1)、RibbonRoutingFiletr.class 中的 run() 方法:
2)、跟进 buildCommandContext(RequestContext context) 方法:
3)、在2)中,着重关注对head的封装。跟进 buildZuulRequestHeaders(HttpServletRequest request) 方法:
4)、在3)中,着重关注 isIncludedHeader(String headerName) 方法,如图所示打断点:
5)、如4)所示,authorization被默认过滤掉了。查该默认过滤是在哪里进行配置的:
6)结论:在application.properties中手动设置敏感请求头,"="后不跟任何东西,即设置为空。
zuul.sensitive-headers=
【本文持续更新】