欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用Feign實現(xiàn)微服務(wù)間文件傳輸

 更新時間:2019年04月24日 14:05:12   作者:浮生夢浮生  
這篇文章主要為大家詳細(xì)介紹了使用Feign實現(xiàn)微服務(wù)間文件傳輸,具有一定的參考價值,感興趣的小伙伴們可以參考一下

在很多時候我們會遇到微服務(wù)之間文件傳輸,很多時候我們可以通過序列化等方式解決(如圖片等)。

最近項目中有個excel上傳,以及多媒體文件上傳,直接報錯。

也試了2種解決方式,都不可行。

1.寫一個文件Encoder解析器,會出現(xiàn)其他的rest請求出現(xiàn)encoder錯誤

2.springcloud feign有一個規(guī)范,不可以傳輸2個對象,可以是一個對象帶幾個參數(shù)方式。

那么我們現(xiàn)在需要一種方式,不配置全局的解析器,而是通過Feign Builder 去管理上傳文件,這種方式管理起來也較為方便。

引用包

<dependency>
  <groupId>com.netflix.feign</groupId>
  <artifactId>feign-core</artifactId>
  <version>8.17.0</version>
</dependency>
<dependency>
  <groupId>com.netflix.feign</groupId>
  <artifactId>feign-jackson</artifactId>
  <version>8.17.0</version>
</dependency>
<dependency>
  <groupId>com.netflix.feign</groupId>
  <artifactId>feign-slf4j</artifactId>
  <version>8.17.0</version>
</dependency>

調(diào)用方式 

@ApiOperation(value = "上傳Excel", notes = "上傳Excel")
@RequestMapping(value = "/imExcel", method = RequestMethod.POST, produces = request_headers)
public ActionResult imExcel(@RequestBody MultipartFile file,@RequestParam("operatorId") Integer operatorId){
 
  if(file == null || file.isEmpty()|| operatorId==null)
    return new ActionResult<>(ResultType.BAD_REQUEST,"文件與操作用戶ID都不能為空");
  String fileName = file.getOriginalFilename();
  if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
    return new ActionResult<>(ResultType.BAD_REQUEST,"上傳文件格式錯誤,請上傳后綴為.xls或.xlsx的文件");
  }
  Feign.Builder encoder = Feign.builder()
      .decoder(new JacksonDecoder())
      .encoder(new FeignEncoder());
  FileUpload complainFileUpload = encoder.target(FileUpload.class,LABEL_URL);
  return complainFileUpload.imComplainExcel(file,operatorId);
 
}

文件Encode

import feign.RequestTemplate;
import feign.codec.EncodeException;
import feign.codec.Encoder;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
 
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
 
/**
 * @author lxl
 */
public class FeignEncoder implements Encoder {
 
 
  private final List<HttpMessageConverter<?>> converters = new RestTemplate().getMessageConverters();
  private final HttpHeaders multipartHeaders = new HttpHeaders();
  private final HttpHeaders jsonHeaders = new HttpHeaders();
 
  public static final Charset UTF_8 = Charset.forName("UTF-8");
 
  public FeignEncoder() {
    multipartHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
    jsonHeaders.setContentType(MediaType.APPLICATION_JSON);
  }
 
 
  @Override
  public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {
    if (isFormRequest(bodyType)) {
      encodeMultipartFormRequest((Map<String, ?>) object, template);
    } else {
      encodeRequest(object, jsonHeaders, template);
    }
  }
 
 
  private void encodeMultipartFormRequest(Map<String, ?> formMap, RequestTemplate template) throws EncodeException {
    if (CollectionUtils.isEmpty(formMap)) {
      throw new EncodeException("參數(shù)不能為空.");
    }
    LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
    for (Entry<String, ?> entry : formMap.entrySet()) {
      Object value = entry.getValue();
      if (isMultipartFile(value)) {
        map.add(entry.getKey(), encodeMultipartFile((MultipartFile) value));
      } else if (isMultipartFileArray(value)) {
        encodeMultipartFiles(map, entry.getKey(), Arrays.asList((MultipartFile[]) value));
      } else {
        map.add(entry.getKey(), encodeJsonObject(value));
      }
    }
    encodeRequest(map, multipartHeaders, template);
  }
 
  private boolean isMultipartFile(Object object) {
    return object instanceof MultipartFile;
  }
 
  private boolean isMultipartFileArray(Object o) {
    return o != null && o.getClass().isArray() && MultipartFile.class.isAssignableFrom(o.getClass().getComponentType());
  }
 
  /**
   * 設(shè)置頭
   * @param file
   * @return
   */
  private HttpEntity<?> encodeMultipartFile(MultipartFile file) {
    HttpHeaders filePartHeaders = new HttpHeaders();
    filePartHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    try {
      Resource multipartFileResource = new MultipartFileResource(file.getOriginalFilename(), file.getSize(), file.getInputStream());
      return new HttpEntity<>(multipartFileResource, filePartHeaders);
    } catch (IOException ex) {
      throw new EncodeException("Cannot encode request.", ex);
    }
  }
 
  /**
   * 映射
   * @param map
   * @param name
   * @param files
   */
  private void encodeMultipartFiles(LinkedMultiValueMap<String, Object> map, String name, List<? extends MultipartFile> files) {
    HttpHeaders filePartHeaders = new HttpHeaders();
    filePartHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    try {
      for (MultipartFile file : files) {
        Resource multipartFileResource = new MultipartFileResource(file.getOriginalFilename(), file.getSize(), file.getInputStream());
        map.add(name, new HttpEntity<>(multipartFileResource, filePartHeaders));
      }
    } catch (IOException ex) {
      throw new EncodeException("Cannot encode request.", ex);
    }
  }
 
  /**
   * {@link HttpEntity} {@code Content-type}
   * {@code application/json}
   *
   * @param o
   * @return
   */
  private HttpEntity<?> encodeJsonObject(Object o) {
    HttpHeaders jsonPartHeaders = new HttpHeaders();
    jsonPartHeaders.setContentType(MediaType.APPLICATION_JSON);
    return new HttpEntity<>(o, jsonPartHeaders);
  }
 
  /**
   * {@link org.springframework.web.client.RestTemplate}
   *
   * @param value
   * @param requestHeaders
   * @param template
   * @throws EncodeException
   */
  private void encodeRequest(Object value, HttpHeaders requestHeaders, RequestTemplate template) throws EncodeException {
    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<Object>) messageConverter).write(
              value, requestContentType, dummyRequest);
          break;
        }
      }
    } catch (IOException ex) {
      throw new EncodeException("Cannot encode request.", ex);
    }
    HttpHeaders headers = dummyRequest.getHeaders();
    if (headers != null) {
      for (Entry<String, List<String>> entry : headers.entrySet()) {
        template.header(entry.getKey(), entry.getValue());
      }
    }
    /*
    使用bytearray方式傳輸
     */
    template.body(outputStream.toByteArray(), UTF_8);
  }
 
  /**
   * {@link org.springframework.http.HttpOutputMessage}
   * {@link org.springframework.http.converter.HttpMessageConverter}
   */
  private class HttpOutputMessageImpl implements HttpOutputMessage {
 
    private final OutputStream body;
    private final HttpHeaders headers;
 
    public HttpOutputMessageImpl(OutputStream body, HttpHeaders headers) {
      this.body = body;
      this.headers = headers;
    }
 
    @Override
    public OutputStream getBody() throws IOException {
      return body;
    }
 
    @Override
    public HttpHeaders getHeaders() {
      return headers;
    }
 
  }
 
 
  static boolean isFormRequest(Type type) {
    return MAP_STRING_WILDCARD.equals(type);
  }
 
 
  static class MultipartFileResource extends InputStreamResource {
 
    private final String filename;
    private final long size;
 
    public MultipartFileResource(String filename, long size, InputStream inputStream) {
      super(inputStream);
      this.size = size;
      this.filename = filename;
    }
 
    @Override
    public String getFilename() {
      return this.filename;
    }
 
    @Override
    public InputStream getInputStream() throws IOException, IllegalStateException {
      return super.getInputStream(); //To change body of generated methods, choose Tools | Templates.
    }
 
    @Override
    public long contentLength() throws IOException {
      return size;
    }
 
  }
 
}

Feign調(diào)用接口

@RequestLine("POST /punish/imExcel")
ActionResult<List<String>> imPunishExcel(@Param("file") MultipartFile file, @Param("operatorId") Integer operatorId);

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 注解@TableName,@TableField,pgsql的模式對應(yīng)方式

    注解@TableName,@TableField,pgsql的模式對應(yīng)方式

    這篇文章主要介紹了注解@TableName,@TableField,pgsql的模式對應(yīng)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • IDEA中沒有Mapper.xml模板選項的處理方法

    IDEA中沒有Mapper.xml模板選項的處理方法

    這篇文章主要介紹了IDEA中沒有Mapper.xml模板選項的處理方法,需其實解決方法很簡單,只需要在idea中導(dǎo)入模板即可,本文圖文的形式給大家分享解決方法,需要的朋友可以參考下
    2021-04-04
  • Java模擬HTTP Get Post請求 輕松實現(xiàn)校園BBS自動回帖

    Java模擬HTTP Get Post請求 輕松實現(xiàn)校園BBS自動回帖

    這篇文章主要介紹了Java模擬HTTP Get Post請求,輕松實現(xiàn)校園BBS自動回帖,感興趣的小伙伴們可以參考一下
    2015-12-12
  • 利用Java簡單實現(xiàn)一個代碼行數(shù)統(tǒng)計器方法實例

    利用Java簡單實現(xiàn)一個代碼行數(shù)統(tǒng)計器方法實例

    這篇文章主要給大家介紹了關(guān)于如何利用Java簡單實現(xiàn)一個代碼行數(shù)統(tǒng)計器的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • MAVEN_HOME、M2_HOME,maven環(huán)境變量設(shè)置方式

    MAVEN_HOME、M2_HOME,maven環(huán)境變量設(shè)置方式

    這篇文章主要介紹了MAVEN_HOME、M2_HOME,maven環(huán)境變量設(shè)置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 小白教程! Linux服務(wù)器上JDK安裝配置方法

    小白教程! Linux服務(wù)器上JDK安裝配置方法

    這篇文章主要為大家詳細(xì)介紹了Linux服務(wù)器上JDK安裝配置方法,小白教程!具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • java 商戶PC端接入支付寶支付的實現(xiàn)方法

    java 商戶PC端接入支付寶支付的實現(xiàn)方法

    這篇文章主要介紹了java 商戶PC端接入支付寶支付的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • 關(guān)于mybatis一對一查詢一對多查詢遇到的問題

    關(guān)于mybatis一對一查詢一對多查詢遇到的問題

    這篇文章主要介紹了關(guān)于mybatis一對一查詢,一對多查詢遇到的錯誤,接下來是對文章進行操作,要求查詢?nèi)课恼?,并關(guān)聯(lián)查詢作者,文章標(biāo)簽,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • Mybatis-plus3.4.3下使用lambdaQuery報錯解決

    Mybatis-plus3.4.3下使用lambdaQuery報錯解決

    最近在使用lambdaQuery().eq(CommonUser::getOpenId, openId).one()進行查詢報錯,本文主要介紹了Mybatis-plus3.4.3下使用lambdaQuery報錯解決,具有一定的參考價值,感興趣的可以了解一下
    2024-07-07
  • SparkSQL讀取hive數(shù)據(jù)本地idea運行的方法詳解

    SparkSQL讀取hive數(shù)據(jù)本地idea運行的方法詳解

    這篇文章主要介紹了SparkSQL讀取hive數(shù)據(jù)本地idea運行的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09

最新評論