V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Vimax
V2EX  ›  Java

服务 A 调用服务 B 接口,返回 ResponseEntity 数据异常

  •  1
     
  •   Vimax · 2020-06-15 11:12:12 +08:00 · 1071 次点击
    这是一个创建于 1404 天前的主题,其中的信息可能已经有所发展或是发生改变。

    服务提供者 A 返回 ResponseEntity 封装的 json 数据。 服务调用者 B,调用服务提供者 A,同样返回 ResponseEntity 给前端。 服务 A 调用服务 B 接口,返回 ResponseEntity 数据异常。

    之前方式:返回数据上加 responbody 注解返回 json 数据,这种远程调用是没问题。现在使用 spring 提供的 ResponseEntity,调用接口,单独调用自身是没有问题。服务间相互调用是会报错。

    服务提供者 A:

      @GetMapping
        public ResponseEntity<List<Payment>> getPayment(Payment payment) {
            QueryWrapper<Payment> paymentQueryWrapper = new QueryWrapper<>();
            paymentQueryWrapper.setEntity(payment);
            List<Payment> list = paymentService.list(paymentQueryWrapper);
            return ResponseEntity.ok(list);
        }
    

    服务提供者单独调用接口,可以正常返回数据。

    服务调用者 B Controlelr:

    @RestController
    @RequestMapping("order")
    @Slf4j
    public class OrderFeignController {
    
        @Resource
        private IPaymentService paymentService;
    
        @GetMapping("feignPayment")
        public ResponseEntity<List<Payment>> getPayment(Payment payment) {
            return paymentService.getPayment(payment);
        }
    }
    

    服务调用者 B Feign 接口:

    @Component
    @FeignClient("cloud-payment-service")
    public interface IPaymentService {
    
        @GetMapping()
        public ResponseEntity<List<Payment>> getPayment(Payment payment) ;
    }
    
    

    使用 Feign 或者 RestTemplate 调用服务 A 接口会报错,无法返回数据:

    {
        "timestamp": "2020-06-15T02:55:28.978+0000",
        "status": 500,
        "error": "Internal Server Error",
        "message": "status 404 reading IPaymentService#getPayment(Payment)",
        "trace": "feign.FeignException$NotFound: status 404 reading IPaymentService#getPayment(Payment)\n\tat feign.FeignException.clientErrorStatus(FeignException.java:165)\n\tat feign.FeignException.errorStatus(FeignException.java:141)\n\tat feign.FeignException.errorStatus(FeignException.java:133)\n\tat feign.codec.ErrorDecoder$Default.decode(ErrorDecoder.java:92)\n\tat feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:151)\n\tat feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:80)\n\tat feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)\n\tat com.sun.proxy.$Proxy115.getPayment(Unknown Source)\n\tat xyz.demo.springcloud.controller.OrderFeignController.getPayment(OrderFeignController.java:30)\n\tat sun.reflect.GeneratedMethodAccessor85.invoke(Unknown Source)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:45005)\n\tat java.lang.reflect.Method.invoke(Method.java:498)\n\tat org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888)\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)\n\tat org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\n\tat org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:634)\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:741)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:108)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)\n\tat org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:96)\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:41002)\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526)\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)\n\tat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367)\n\tat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\n\tat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1591)\n\tat org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\n\tat java.lang.Thread.run(Thread.java:748)\n",
        "path": "/order/feignPayment"
    }
    
    第 1 条附言  ·  2020-06-15 17:24:58 +08:00
    答案:是 5 楼和 9 楼的解答。
    服务调用者 A 的 Feign 接口调用映射 应该与服务提供者 B 的接口地址对应。
    12 条回复    2020-06-16 17:04:58 +08:00
    lff0305
        1
    lff0305  
       2020-06-15 12:49:11 +08:00
    用 wireshark 或者 Fiddler 抓下看看 request 到底发的是什么,
    content-type 之类的 header 对不对
    Kyle18Tang
        2
    Kyle18Tang  
       2020-06-15 14:21:10 +08:00
    非功能#里面为啥还有要 ResponseEntity,直接用 list 接试试
    Kyle18Tang
        3
    Kyle18Tang  
       2020-06-15 14:22:15 +08:00
    @Kyle18Tang feign 里面
    Kyle18Tang
        4
    Kyle18Tang  
       2020-06-15 14:23:57 +08:00
    仔细看了下报错好像是 404 ?链接有没有问题
    xuanbg
        5
    xuanbg  
       2020-06-15 14:26:06 +08:00
    @GetMapping 没路径的吗?
    Vimax
        6
    Vimax  
    OP
       2020-06-15 17:09:07 +08:00
    @Kyle18Tang 链接是对的,2L 应为 Feign 调用的远程接口地址返回是 ResponseEntity 。
    Vimax
        7
    Vimax  
    OP
       2020-06-15 17:09:50 +08:00
    @xuanbg 恩,方法上是没有,类上有个路径。
    Vimax
        8
    Vimax  
    OP
       2020-06-15 17:10:33 +08:00
    @lff0305 好的。回头用大白鲨或 tcpdump 抓抓看。
    Kyle18Tang
        9
    Kyle18Tang  
       2020-06-15 17:13:43 +08:00
    @Vimax #6 FeignClient 里的 GetMapping 的路径加上你说的那个类上的路径
    Vimax
        10
    Vimax  
    OP
       2020-06-15 17:22:40 +08:00
    @xuanbg 哥们,你是对的。是少个路径。服务调用者的接口上少个路径,没有和服务提供者的服务路径对应起来。
    Vimax
        11
    Vimax  
    OP
       2020-06-15 17:23:22 +08:00
    @Kyle18Tang 对的,采纳答案。
    hantsy
        12
    hantsy  
       2020-06-16 17:04:58 +08:00
    排除你程序中写法问题,在 A 中调用 B 返回结果也要处理 404 异常等。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   917 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 20:37 · PVG 04:37 · LAX 13:37 · JFK 16:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.