SpringCloud版本:Camden.SR6
项目结构:
platform-core-client : 服务消费者(feign client)
platform-core-server:服务提供者
platform-eureka:eureka注册中心
platform-gateway:zuul网关
platform-core-server中方法:
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Map importExcel(@RequestParam MultipartFile file, @RequestParam String userId) {
System.out.println(file.getOriginalFilename());
return null;
}
如果直接调用server没有任何问题,但这样做毫无意义。不走zuul网关通过platform-core-client去调用platform-core-server浏览器返回200,但根本没进入platform-core-server直接进入platform-core-client的fallback方法
platform-core-client代码:
@FeignClient(name = "platform-core-server", fallback = SysUserFallback.class)
public interface SysUserFeignClient {
@RequestMapping(value = "/sysUserServerHandler/importExcel", method = RequestMethod.POST)
public Map importExcel(@RequestPart("file") MultipartFile file, @RequestParam("userId") String userId);
}
在platform-core-client引入依赖:
io.github.openfeign.form
feign-form
2.1.0
io.github.openfeign.form
feign-form-spring
2.1.0
加入配置类:
@Configuration
public class FeignMultipartSupportConfig {
@Bean
@Primary
@Scope("prototype")
public Encoder multipartFormEncoder() {
return new SpringFormEncoder(new SpringEncoder(new ObjectFactory() {
@Override
public HttpMessageConverters getObject() throws BeansException {
return new HttpMessageConverters(new RestTemplate().getMessageConverters());
}
}));
}
}
同时修改FeignClient,加入configuration
@FeignClient(name = "platform-core-server", fallback = SysUserFallback.class, configuration = FeignMultipartSupportConfig.class)
测试后附件成功读取
通过问题1,附件可从platform-core-client进入platform-core-server,附件名称也是正确的,但不走网关代表没了权限校验,这种方式也不可取,走网关但是附件名称乱码:
platform-gateway 部分配置:
zuul:
routes:
core:
path: /core/**
serviceId: platform-core-client
通过解决问题1可以确定问题出在zuul上。但不知道是什么地方出的问题,尝试的ctrl+鼠标左键进入yml中zuul的配置类
ctrl+f 尝试搜索已知的关键词(如:file,upload,multipart )
找到如下代码:
借助于翻译工具简单了解到默认请求会先走的springmvc的DispatcherServlet,而请求前加了/zuul的则只走zuul自己的servlet不过DispatcherServlet。
为了验证结论,给请求前面加上了/zuul,果然文件名不乱码了,但在请求前面加个zuul感觉怪怪的,于是配置默认的servletPath为:/
zuul:
servletPath: /
routes:
core:
path: /core/**
serviceId: platform-core-client
去掉/zuul后访问一切正常,但是新的问题又来了,写在platform-gateway中的方法无法调用,如登陆(不走ZuulFilter的方法)
后台报错:
No route found for uri: /platformLogin
通过报错信息调试发现/platformLogin被zuulServlet拦截了,没有被DispatcherServlet拦截
于是修改yml文件,把DispatcherServlet默认的url改成/platformLogin即可
server:
port: 8080
servlet-path: /platformLogin
tomcat:
uri-encoding: UTF-8