美文网首页java高级开发
Feign文件上传问题

Feign文件上传问题

作者: 老鼠AI大米_Java全栈 | 来源:发表于2019-09-29 08:57 被阅读0次

    单服务中使用MultipartFile上传文件没有问题,但Cloud中使用Feign文件上传就会有问题,不会自动跳到下一个服务中,查了下原来Feign默认不支持,后来通过三方的依赖包实现。

    添加三方依赖包

    Feign客户端中添加依赖配置,注意,一定要是>=3.0.0
    3.0.0之前的版本有Bug,通过feign-form实现文件上传,会导致无法解码@Requestboby中传递的Map、User等等对象,会造成500错误,鉴于此在feign-form项目中提了一个Issue(https://github.com/OpenFeign/feign-form/issues/19

    <!-- feign实现上传文件 -->
       <dependency>
           <groupId>io.github.openfeign.form</groupId>
           <artifactId>feign-form</artifactId>
           <version>3.0.0</version>
       </dependency>
       <dependency>
           <groupId>io.github.openfeign.form</groupId>
           <artifactId>feign-form-spring</artifactId>
           <version>3.0.0</version>
       </dependency>
    

    修改配置Feign客户端

    这里使用接口内部类方式,给接口扩展对文件的编写转换支持,这是java8的方式,java9接口又有增强。

    • 必须在客户端接口配置consumes = MULTIPART_FORM_DATA_VALUE,否则MultipartFile实例无法被正常encode解析.
    • 修改Encoder定义,需要通过构造函数载入当前定义的所有HttpMessageConverters
    • @RequestParam,@RequestPart同样支持multipart/form-data请求
    • @RequestParam适用于name-valueString类型的请求域,@RequestPart适用于复杂的请求域(像JSON,XML)。
    @FeignClient(value = "service-producer", fallback = DevServiceFallback.class, configuration = {DevService.MultipartSupportConfig.class})
    public interface DevService extends IDevService {
    
        /**设备系统文件上传*/
        @ApiOperation("设备系统文件上传")
        @PostMapping(value = "/dev/reg/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
        ApiResult devFileUpload(@RequestPart("uploadFile") MultipartFile uploadFile,
                                @RequestParam(value = "name") String name,
                                @RequestParam(value = "type") String type,
                                @RequestParam(value = "desc", required = false) String desc,
                                @RequestParam(value = "version") String version);
    
        @Configuration
        class MultipartSupportConfig {
    
            @Autowired
            private ObjectFactory<HttpMessageConverters> messageConverters;
    
            @Bean
            @Primary
            @Scope("prototype")
            public Encoder feignEncoder() {
                return new SpringFormEncoder(new SpringEncoder(messageConverters));
            }
        }
    }
    

    @Requestboby功能验证

    注意:下面包括三种参数:

    • RequestBody - Json
    • RequestParam - keyValue(string)
    • PathVariable - {}
    @RequestMapping(value = "/postBobyAParamAPathVar/{id}", method = RequestMethod.POST)
    public String postBobyAParamAPathVar(
            @RequestBody(required = true) Map<String, Object> map,
            @RequestParam(value = "userName") String userName,
            @PathVariable(value = "id") String id) {
        ServiceInstance instance = client.getInstances("service1").get(0);
        String retValue = map.get("username") + "(英文名:" + userName + ") ask that(id:" + id + "), host:" +
                instance.getHost() + ";port:" + instance.getPort() + "; service_id:" + instance.getServiceId();
        logger.info(retValue);
        return retValue;
    }
    

    文件上传功能验证

    • @RequestParam,@RequestPart同样支持multipart/form-data请求
    • @RequestParam适用于name-valueString类型的请求域,@RequestPart适用于复杂的请求域(像JSON,XML)。
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public @ResponseBody
    String handleFileUpload(@RequestParam(value = "file", required = true) MultipartFile file,
                            @RequestParam(value = "name") String name) throws IOException {
        byte[] bytes = file.getBytes();
        File fileToSave = new File(file.getOriginalFilename());
        FileCopyUtils.copy(bytes, fileToSave);
        System.out.println(name);
        return fileToSave.getAbsolutePath();
    }
    

    小结

    在微服务中传递file, json, key-value(string)及路径{}等参数,其中file需要使用三方库feign-form。

    相关文章

      网友评论

        本文标题:Feign文件上传问题

        本文链接:https://www.haomeiwen.com/subject/nwdoectx.html