Spring MVC升级为Spring Cloud碰到的问题注意点
现象:问题出现在一个由spring-mvc老工程改造成spring boot项目中,在Application.java类中通过@ImportResource(“classpath:applicationContext-*.xml”)把xml的配置实例化,下面的自定义webmvc注入器无效
@Bean
public WebMvcRegistrations feignWebRegistrations() {
return new WebMvcRegistrations() {
@Override
public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
return new FeignRequestMappingHandlerMapping();
}
};
}
private static class FeignRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
@Override
protected boolean isHandler(Class<?> beanType) {
return super.isHandler(beanType) &&
!AnnotatedElementUtils.hasAnnotation(beanType, FeignClient.class);
}
}
原因:resources目录下有一个applicationContext-mvc.xml文件,里面有
解决方案:删除applicationContext-mvc.xml文件或者去掉
正常情况下DELETE最好不要加上body
升级为Spring Cloud后调用老接口方式简单的通过添加@LoadBalanced改为了Ribbon调用的方式,发现DELETE请求的body体丢失了
解决方案临时解决:将DELETE方法的调用修改为FeignClient调用即可
后续解决:应该将所有请求方式都修改为feign调用
升级为Spring Cloud以后在idea下启动都是正常的,但是jar包运行就报下面的错误,pom中和Eureka相关的也没有包冲突
解决方案: 去掉pom中所有没有用到的依赖,没有时间去排查具体是哪个多余的依赖导致
错误现象如下:
Caused by: java.lang.VerifyError: Stack map does not match the one at exception handler 16
Exception Details:
Location:
org/springframework/cloud/netflix/eureka/serviceregistry/EurekaRegistration$$EnhancerBySpringCGLIB$$fb307af2.<init>(Lorg/springframework/cloud/netflix/eureka/CloudEurekaInstanceConfig;Lcom/netflix/discovery/EurekaClient;Lcom/netflix/appinfo/ApplicationInfoManager;Lorg/springframework/beans/factory/ObjectProvider;Lorg/springframework/cloud/netflix/eureka/serviceregistry/EurekaRegistration$1;)V @16: athrow
Reason:
Current frame's flags are not assignable to stack map frame's.
Current Frame:
bci: @0
flags: { flagThisUninit }
locals: { uninitializedThis, 'org/springframework/cloud/netflix/eureka/CloudEurekaInstanceConfig', 'com/netflix/discovery/EurekaClient', 'com/netflix/appinfo/ApplicationInfoManager', 'org/springframework/beans/factory/ObjectProvider', 'org/springframework/cloud/netflix/eureka/serviceregistry/EurekaRegistration$1' }
stack: { 'java/lang/RuntimeException' }
Stackmap Frame:
bci: @16
flags: { }
locals: { top, 'org/springframework/cloud/netflix/eureka/CloudEurekaInstanceConfig', 'com/netflix/discovery/EurekaClient', 'com/netflix/appinfo/ApplicationInfoManager', 'org/springframework/beans/factory/ObjectProvider', 'org/springframework/cloud/netflix/eureka/serviceregistry/EurekaRegistration$1' }
stack: { 'java/lang/Throwable' }
Bytecode:
0x0000000: 2a59 2b2c 2d19 0419 05b7 025f b800 3eb1
0x0000010: bfbb 0054 5a5f b700 57bf
Exception Handler Table:
bci [0, 16] => handler: 16
bci [0, 16] => handler: 16
bci [0, 16] => handler: 17
Stackmap Table:
full_frame(@16,{Top,Object[#170],Object[#609],Object[#157],Object[#144],Object[#611]},{Object[#82]})
same_locals_1_stack_item_frame(@17,Object[#82])
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:563)
at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:363)
at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:582)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:110)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:108)
at org.springframework.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54)
at java.util.concurrent.FutureTask.run(Unknown Source)
at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)
... 113 common frames omitted
现象: Spring MVC升级为Spring cloud以后发现同一个浏览器每次请求的sessionid都不一样
解决: 原来使用的tomcat是8.0版本的,升级到高级版本问题解决
现象: tomcat升级到8.5.54出现, 设置cookie的时候报错
解决方案:
方案1.不修改代码,在tomcat的context.xml中增加下面的配置问题得到解决
<CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor"/>
方案2.修改代码中设置cookie的方法
cookie.setDomain(".**.com");
去掉域名前面的.
cookie.setDomain("***.com");
现象: 在有些Spring boot中@ImportResource进来的xml文件会找不到application.properties中的变量
解决方案:
方案一:java代码中加入下面的配置
@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer(){
PropertySourcesPlaceholderConfigurer c = new PropertySourcesPlaceholderConfigurer();
c.setIgnoreUnresolvablePlaceholders(true);
return c;
}
方案二:xml引入配置文件
<bean id="jdbc" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="locations">
<list>
<value>classpath:jdbc.propertiesvalue>
<value>classpath:application.propertiesvalue>
list>
property>
bean>
现象:升级为Spring Cloud以后,老的Spring MVC接口.html结尾的会报406
解决方案:
方案一: 将接口的名字修改了,例如/menu.html 修改为menu.do
方案二: 将.html接口直接用response输出
方案三: 新增一个jsp文件输出对象字符串,用ModelAndView指向该jsp文件,有一个坏处就是response的contentType不是application/json
return new ModelAndView("common/result", "resultMessage", new ObjectMapper().writeValueAsString(obj));
result.jsp代码如下
<%@ page language="java" pageEncoding="UTF-8"%>
${resultMessage}
现象: 因为有两个域名指向同一个服务,nginx的域名1-url1 proxy_pass http://gateway, 直接访问url1是正常的;
但是设置了域名2-url2重定向到url1时,打开的则跳转到了内网服务的ip:port上
解决方案:暂时未找到原因,需要重定向的服务暂时先不走网关代理
大神写的WrapperResponseGlobalFilter确实能解决问题,但是同时会产生另外一个问题所有服务的302重定向到一个新的域名上无效