Feign解决服务之间传递文件、传递list,map、对象( 二 )

) object, multipartHeaders, template);} else {final HttpHeaders jsonHeaders = new HttpHeaders();jsonHeaders.setContentType(MediaType.APPLICATION_JSON);encodeRequest(object, jsonHeaders, template);}}/*** 对有文件、表单的进行编码* @param formMap* @param multipartHeaders* @param template*/private void encodeMultipartFormRequest(Map formMap, HttpHeaders multipartHeaders, RequestTemplate template){if (formMap == null){throw new EncodeException("无法对格式为null的请求进行编码 。 ");}LinkedMultiValueMap map = new LinkedMultiValueMap<>();//对每个参数进行检查校验for (Entry entry : formMap.entrySet()){Object value = http://kandian.youth.cn/index/entry.getValue();//不同的数据类型进行不同的编码逻辑处理if (isMultipartFile(value)){//单个文件map.add(entry.getKey(), encodeMultipartFile((MultipartFile)value));} else if (isMultipartFileArray(value)){//多个文件encodeMultipartFiles(map, (String) entry.getKey(), Arrays.asList((MultipartFile[]) value));} else {//普通请求数据map.add(entry.getKey(), encodeJsonObject(value));}}encodeRequest(map, multipartHeaders, template);}/*** 对请求进行编码* @param value* @param requestHeaders* @param template*/private void encodeRequest(Object value, HttpHeaders requestHeaders, RequestTemplate template){ByteArrayOutputStream outputStream = new ByteArrayOutputStream();HttpOutputMessage dummyRequest = new HttpOutputMessageImpl(outputStream, requestHeaders);try {Class requestType = value.getClass();MediaType requestContentType = requestHeaders.getContentType();for (HttpMessageConverter messageConverter : converters){if (messageConverter.canWrite(requestType, requestContentType)){((HttpMessageConverter) messageConverter).write(value, requestContentType, dummyRequest);break;}}} catch (IOException e) {throw new EncodeException("无法对请求进行编码:", e);}HttpHeaders headers = dummyRequest.getHeaders();if (headers != null){for (Entry> entry : headers.entrySet()){template.header(entry.getKey(), entry.getValue());}}/*请使用模板输出流 。。。 如果文件太大 , 这将导致问题 , 因为整个请求都将在内存中 。*/template.body(outputStream.toByteArray(), UTF_8);}/*** 编码为json对象* @param obj* @return*/private HttpEntity encodeJsonObject(Object obj){HttpHeaders jsonPartHeaders = new HttpHeaders();jsonPartHeaders.setContentType(MediaType.APPLICATION_JSON);return new HttpEntity<>(obj, jsonPartHeaders);}/*** 编码MultipartFile文件 , 将其转换为HttpEntity , 同时设置 Content-type 为 application/octet-stream* @param map 当前请求 map.* @param name 数组字段的名称* @param fileList 要处理的文件*/private void encodeMultipartFiles(LinkedMultiValueMap map, String name, List fileList){HttpHeaders filePartHeaders = new HttpHeaders();//设置 Content-typefilePartHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);try {for (MultipartFile file : fileList){Resource multipartFileResource = new MultipartFileResource(file.getInputStream(), file.getOriginalFilename(), file.getSize());map.add(name, new HttpEntity<>(multipartFileResource, filePartHeaders));}} catch (IOException e) {throw new EncodeException("无法对请求进行编码:", e);}}/*** 编码MultipartFile文件 , 将其转换为HttpEntity , 同时设置 Content-type 为 application/octet-stream* @param file 要编码的文件* @return*/private HttpEntity encodeMultipartFile(MultipartFile file){HttpHeaders filePartHeaders = new HttpHeaders();//设置 Content-typefilePartHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);try {Resource multipartFileResource = new MultipartFileResource(file.getInputStream(), file.getOriginalFilename(), file.getSize());return new HttpEntity<>(multipartFileResource, filePartHeaders);} catch (IOException e) {throw new EncodeException("无法对请求进行编码:", e);}}/*** 判断是否多个 MultipartFile* @param object* @return*/private boolean isMultipartFileArray(Object object){return object != null}/*** 判断是否MultipartFile文件* @param object 要判断的对象* @return*/private boolean isMultipartFile(Object object){return object instanceof MultipartFile;}}将该编码器注册为bean
import feign.Contract;import feign.codec.Encoder;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * 上传文件所用配置 * @author admin */@Configurationpublic class MultipartSupportConfig {/*** 启用feigin自定义注解支持 , 如 @RequestLine 和 @Param* @return*/@Beanpublic Contract feignContract(){return new Contract.Default();}/*** feign 实现多pojo传输与MultipartFile上传 编码器 , 需配合开启feign自带注解使用* @return*/@Beanpublic Encoder feignSpringFormEncoder(){//注入自定义编码器return new FeignSpringFormEncoder();}}这个时候就基本告一段落 ,
所有的请求按照这个标准来写
/*** 示例代码:请求方式和路径之间须有一个空格 。表单提交的话请求方式只能是post* 支持如下的所有请求方式 。* 请求参数需要 @Param 修饰* 在接收端 , 采用@RequestPart注解接收每一个参数 。 所有接收都用 @RequestPart(value = "http://kandian.youth.cn/index/advertiser", required = false)* @return*/@RequestLine(value = "http://kandian.youth.cn/index/POST /data/test01")ResultJson test01(@Param(value = "http://kandian.youth.cn/index/name") String name,@Param(value = "http://kandian.youth.cn/index/nametwo") String nametwo,@Param(value = "http://kandian.youth.cn/index/file") MultipartFile file,@Param(value = "http://kandian.youth.cn/index/advertiserMap") Map advertiserMap,@Param(value = "http://kandian.youth.cn/index/materials") List