feign 调用服务上传同时传递token 失败,求大神支招?

问题描述:我这边有一个tools服务,然后我会另一个服务调用tools服务controller实现文件上传,由于tools服务有token校验,因此我在服务这边实现了feign的token传递,单都请求其他接口是可以实现token传递,但是就是文件上传接口却意外的报错了,但是我去掉token拦截传递的代码之后是可以成功上传的,所以很奇怪,不知道问题出在了哪里

ERROR 54308 --- [nio-8202-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: java.io.EOFException: Unexpected EOF read on the socket] with root cause

java.io.EOFException: Unexpected EOF read on the socket
at org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:788) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
at org.apache.coyote.http11.Http11InputBuffer.access$300(Http11InputBuffer.java:42) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
at org.apache.coyote.http11.Http11InputBuffer$SocketInputBuffer.doRead(Http11InputBuffer.java:1133) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
at org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:102) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
at org.apache.coyote.http11.Http11InputBuffer.doRead(Http11InputBuffer.java:249) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
at org.apache.coyote.Request.doRead(Request.java:551) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
at org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:336) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
at org.apache.catalina.connector.InputBuffer.checkByteBufferEof(InputBuffer.java:632) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:362) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:132) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
at java.io.FilterInputStream.read(FilterInputStream.java:133) ~[na:1.8.0_181]

文件上传服务端,tools服务文件上传代码

    @PostMapping(value = "/updateFile",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String updateFile(@RequestParam("file") MultipartFile file) {
        try {
            String fileName ="";
            if (!file.isEmpty()) {
                fileName = FileUploadUtils.uploadText(WebConfig.getUploadPath(), file);
                log.info("-----------------------------------------------");
                log.info("文件上传完成,fileName={}",fileName);
            }
            return "success--->>>fileName:="+fileName;
        } catch (Exception e) {
            return "error";
        }
    }

feign端调用代码


@FeignClient(value = "TOOLS-SERVER",configuration = FeginConfig.class,fallback = ToolsFeginClientFallBack.class)
@Component
public interface ToolsFeginClient {

    @GetMapping("/hi")
    String getHi();

    @PostMapping(value = "/updateFile",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    String updateFile(@RequestParam("file") MultipartFile file);
}

feign的token传递代码


@Configuration
public class FeginConfig implements RequestInterceptor{

    @Autowired
    private ObjectFactory<HttpMessageConverters> messageConverters;

    /**
     * fegin失败默认重试策略,重试间隔100毫秒,最大重试时间为1s,重试次数为5次
     * @return
     */
    @Bean
    public Retryer feginRetryer(){
        return new Retryer.Default();
    }

    @Bean
    public Encoder feignFormEncoder() {
        return new SpringFormEncoder(new SpringEncoder(messageConverters));
    }

    @Override
    public void apply(RequestTemplate requestTemplate) {
        HttpServletRequest request = getHttpServletRequest();
        if (Objects.isNull(request)) {
            return;
        }

        Map<String, String> headers = getHeaders(request);
        if (headers.size() > 0) {
            Iterator<Map.Entry<String, String>> iterator = headers.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, String> entry = iterator.next();
                // 把请求过来的header请求头 原样设置到feign请求头中
                if("Content-Type".equals(entry.getKey())){
                    continue;
                }
                requestTemplate.header(entry.getKey(), entry.getValue());
            }
        }
    }

    private HttpServletRequest getHttpServletRequest() {
        try {
            // 这种方式获取的HttpServletRequest是线程安全的
            return ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getRequest();
        } catch (Exception e) {
            return null;
        }
    }

    private Map<String, String> getHeaders(HttpServletRequest request) {
        Map<String, String> map = new LinkedHashMap<>();
        Enumeration<String> enums = request.getHeaderNames();
        while (enums.hasMoreElements()) {
            String key = enums.nextElement();
            String value = request.getHeader(key);
            map.put(key, value);
        }
        return map;
    }
}

1个回答

http请求头要设置 contentType=multipart/form-data

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问