OpenFeign调用出错:java.io.IOException: UT000036: Connection terminated parsing multipart data解决方案

原因:

1、Controller层上传文件导入

    @PostMapping("/importAccount")
    public ResultInfo importAccount(@RequestParam("file") MultipartFile file,
                                    @RequestParam String code,
                                    @RequestParam String type) throws IOException {
        accountManagerService.importAccount(file, code, type);
        return ResultInfo.success();
    }

2、Service层调用feign接口

    @Override
    public void importAccount(MultipartFile file, String code, String type) {

        //...此处省略其他业务逻辑...
        /**
		 * 远程feign调用
		 */
	    NetworkFeign networkFeign = (NetworkFeign)StaticApplication.getBean("networkFeign");
        dto = networkFeign.loadNetworkDTOByBankCode(bankCode);
    }

3、FeignClient定义

@FeignClient(name= "${application.name}",path = "/user/api/network", qualifiers = {"networkFeign"})
public interface NetworkFeign {

    @PostMapping(value = "/loadNetworkDTOByBankCode")
    NetworkDTO loadNetworkDTOByBankCode(@RequestParam("code") String code);


}

4、FeignProvider定义

@Slf4j
@RequestMapping(value = "/user/api/network")
@RestController
public class NetworkAPI {

    @PostMapping(value = "/loadNetworkDTOByBankCode")
    NetworkDTO loadNetworkDTOByBankCode(@RequestParam("code") String code) {
        return networkOperateService.queryNetWorkByBankCode(code);
    }
}

5、调用报错

Client报错日志:

feign.FeignException$InternalServerError: [500 Internal Server Error] during [POST] to [http://user/user/api/network/loadNetworkDTOByBankCode?bank_code=002] [NetworkFeign#loadNetworkDTOByBankCode(String)]:
│     at feign.FeignException.serverErrorStatus(FeignException.java:250)
│     at feign.FeignException.errorStatus(FeignException.java:197)
│     at feign.FeignException.errorStatus(FeignException.java:185)
│     at feign.codec.ErrorDecoder$Default.decode(ErrorDecoder.java:92)
│     at feign.AsyncResponseHandler.handleResponse(AsyncResponseHandler.java:96)
│     at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:138)
│     at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:89)
│     at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:100)
│     at org.springframework.cloud.openfeign.FeignCachingInvocationHandlerFactory$1.proceed(FeignCachingInvocationHandlerFactory.java:66)
│     at org.springframework.cache.interceptor.CacheInterceptor.lambda$invoke$0(CacheInterceptor.java:54)
│     at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:351)
│     at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:64)
│     at org.springframework.cloud.openfeign.FeignCachingInvocationHandlerFactory.lambda$create$1(FeignCachingInvocationHandlerFactory.java:53)
			at com.sun.proxy.$Proxy182.loadNetworkDTOByBankCode(Unknown Source)
│     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
│     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
│     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
│     at java.lang.reflect.Method.invoke(Method.java:498)
│     at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
│     at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
│     at com.sun.proxy.$Proxy183.loadNetworkDTOByBankCode(Unknown Source)

Server报错日志:

java.lang.RuntimeException: java.io.IOException: UT000036: Connection terminated parsing multipart data
│     at io.undertow.servlet.spec.HttpServletRequestImpl.parseFormData(HttpServletRequestImpl.java:863)
│     at io.undertow.servlet.spec.HttpServletRequestImpl.getParameter(HttpServletRequestImpl.java:734)
│     at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:85)
│     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
│     at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
│     at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
│     at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96)
│     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
│     at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
│     at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
│     at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
│     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
│     at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
│     at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
│     at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
│     at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
			at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
│     at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
│     at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68)
│     at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117)
│     at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
│     at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
│     at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
│     at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
│     at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
│     at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
│     at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
│     at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
│     at io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52)
│     at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
│     at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:275)
│     at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:79)
│     at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:134)
│     at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:131)
			at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
│     at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
│     at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:255)
│     at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:79)
│     at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:100)
│     at io.undertow.server.Connectors.executeRootHandler(Connectors.java:387)
│     at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:852)
│     at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
│     at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2019)
│     at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1558)
│     at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1449)
│     at org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1280)
│     at java.lang.Thread.run(Thread.java:750)
│ Caused by: java.io.IOException: UT000036: Connection terminated parsing multipart data
│     at io.undertow.server.handlers.form.MultiPartParserDefinition$MultiPartUploadHandler.parseBlocking(MultiPartParserDefinition.java:231)
│     at io.undertow.servlet.spec.HttpServletRequestImpl.parseFormData(HttpServletRequestImpl.java:857)
│     ... 46 common frames omitted

分析:

因为从client端调用的requestfeign调用是同一个请求,请求头也是同一个。而且从service端调用feign的时候,并没有传fileprovider,所以导致请求头丢失。

有两种解决办法:

方式一:在拦截器里改请求头,把content-type的头带过去;

public class FeignBasicAuthRequestInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        // 对于自动任务,起服务就调用参数的,没有请求信息,不需要传递
        if (attributes == null) {
            return;
        }
        HttpServletRequest request = attributes.getRequest();
        Enumeration<String> headerNames = request.getHeaderNames();
        if (headerNames != null) {
            while (headerNames.hasMoreElements()) {
                String name = headerNames.nextElement();
                String values = request.getHeader(name);
                // 跳过content-length,不然可能会报too many bites written问题
                if ("content-length".equalsIgnoreCase(name) || "cookie".equalsIgnoreCase(name)) {
                    continue;
                }
                // 此处:把content-type的头带过去
                if ("content-type".equalsIgnoreCase(name)) {
                    continue;
                }
                requestTemplate.header(name, values);
            }
        }
    }
}

方式二:改request:不用feign调用,用普通的http调用;

    @Override
    public void importAccount(MultipartFile file, String code, String type) {

        //...此处省略其他业务逻辑...
        /**
		 * 远程feign调用
		 */
	    // NetworkFeign networkFeign = (NetworkFeign)StaticApplication.getBean("networkFeign");
        // dto = networkFeign.loadNetworkDTOByBankCode(bankCode);
        
        // 此处不用feign调用,改用http调用,这里用hutool的工具类
        String response = HttpRequest.post("http://user/user/api/network/loadNetworkDTOByBankCode?code=" + code).execute().body();
        // 用http调用
        log.info("'=====response======{}",response);
        dto = JSONUtil.toBean(response, NetworkDTO.class);
    }

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值