【问题标题】:How to generate Java client proxy for RESTful service implemented with Spring?如何为使用 Spring 实现的 RESTful 服务生成 Java 客户端代理?
【发布时间】:2013-05-06 21:42:47
【问题描述】:

我们使用Spring来实现REST控制器,例如:

@Controller
@RequestMapping("/myservice") 
public class MyController {
    @RequestMapping(value = "foo", method = RequestMethod.GET)
    public @ResponseBody string foo() {...}
}

我可以使用 spring RestTemplate 调用此服务,它工作正常,但我更喜欢使用代理调用它,而不是使用字符串 url 进行无类型调用:

// client code:
MyController proxy = getProxy("baseUrl", MyController.class);
String results = proxy.foo();

因此,代理生成的输入是带有描述 REST 详细信息的注释的 java 接口。 我阅读了this article,看起来所有类型的远程调用都有代理,而我需要的 REST 就是RestProxyFactoryBean,它将采用我的 REST java 接口并返回使用 RestTemplate 作为实现的类型安全代理。

我找到的最接近的解决方案是JBoss RESTEasy

但它似乎使用了不同的注释集,所以我不确定它是否适用于我已经拥有的注释:@Controller@RequestMapping。 是否有其他选择,或者 RESTEasy 是唯一的选择? 请注意,我是春季新手,所以一些明显的春季事物对我来说很新。

谢谢。
迪玛

【问题讨论】:

  • 你找到解决办法了吗?
  • 就个人而言,我发现 Spring MVC 测试框架是正确的工具。以 RESTful 方式进行测试可以消除很多意外。见docs.spring.io/spring-framework/docs/current/…
  • 代理到底应该做什么?如果您正在寻找 REST 协议的另一种实现,还有 cxf 项目。
  • 我最终编写了自己的代码生成器:rest api 编写为带有注释的 java 接口,代理生成器反映它并生成实现该接口的客户端代理类。像往常一样,必须编写服务器端实现。
  • 这其实是一件很有趣的事情。从我的角度来看,拥有代理很重要,以确保 URL 和参数名称不是硬编码的。所以版本升级不需要查找和替换。代理可能会固执己见并自行使用RestTemplate,但这不是重点

标签: spring rest resteasy resttemplate


【解决方案1】:

您可以尝试 Netflix 的Feign,这是一个基于代理的轻量级 REST 客户端。它通过注解以声明方式工作,并被 Spring Cloud 项目用于与 Netflix Eureka 交互。

【讨论】:

  • 我想知道 Feign 是否在 2013 年我需要它时就可以投入生产了。 Feign 的初始提交是在 2012 年春季,第一个问题记录在 2013 年夏季。
  • 嗯.. 我无法判断 Feign 是否在 2013 年准备好生产,但可以肯定的是,我知道许多已经存在的 Netflix 项目在那个时期都是开源的。也许 Feign 是其中之一?但我当然不确定:)
【解决方案2】:

发明 REST 范式的原因之一是,对其他远程处理技术(RMI、CORBA、SOAP)的经验告诉我们,基于代理的方法通常会产生比它解决的问题更多的问题。

理论上,代理使得函数调用对其用户是远程透明的,因此他们可以像使用本地函数调用一样使用函数。

然而,在实践中,这个承诺并不能实现,因为远程函数调用除了本地调用之外还有其他属性。网络中断、拥塞、超时、负载问题等等。如果您选择忽略所有这些远程调用可能出错的事情,您的代码可能不会很稳定。

TL;DR:您可能不应该使用代理,它不再是最先进的。只需使用RestTemplate

【讨论】:

  • 您对代理调用的远程性质的担忧可以通过额外的参数来解决,例如超时、重试计数、网络错误处理程序、远程方法的命名。我正在尝试解决客户端和服务器之间简单而愚蠢的不匹配问题(经常发生),并使用编译器的功能来捕捉我的拼写错误。
  • 这似乎是传统的智慧,但我很难理解如何构建 http 调用来消除这些问题。无论您使用代理客户端还是 RestTemplate,您是否仍在捕获相同的异常?我认为开发人员很容易看到一个充满 REST 注释的界面并意识到这是一个远程调用。感觉反对代理的原因有些模糊,而不使用代理的痛苦却非常具体(样板代码、与服务器版本的潜在差异、程序性而非声明性编码等......)
  • @MichaelHaefele:是的,当然问题仍然存在,这不是重点。但是当我阅读代码时,很明显这些问题可能会发生,而代理向读者隐藏了事实。
  • @Dima:如果您向代理添加额外的技术参数,那很好,这会使代码更具可读性,并且开发人员在超时时不会感到惊讶。但是,如果您这样做,那么您为什么首先需要代理?使用代理的全部意义在于隐藏“远程”或您的函数调用,不是吗?
  • @Bastian Voigt,生成代理的目的是隐藏构建和解析 json、处理 HTTP 客户端设置等的复杂性。但它最大的好处(IMO)是将一些运行时错误转换为编译错误由于代理的强类型性质。是的,代理可以隐藏呼叫的远程性质,但这不是目标。事实上,现代代理(我的不是)使用 Future 之类的东西来处理网络缓慢,但仍然使其易于使用并保护客户端免受某些协议更改的影响。
【解决方案3】:

这是一个尝试从控制器注释生成运行时代理的项目(在后台使用 RestTemplate 来处理代理调用):spring-rest-proxy-client 不过在实现的早期。

【讨论】:

    【解决方案4】:

    这似乎做到了:https://swagger.io/swagger-codegen/,并且 swagger 为 REST API 提供了许多其他好东西。

    【讨论】:

      【解决方案5】:

      看看https://github.com/ggeorgovassilis/spring-rest-invoker。 您只需要注册 FactoryBean:

      @Configuration
      public class MyConfiguration {
      
          @Bean
          SpringRestInvokerProxyFactoryBean BankService() {
              SpringRestInvokerProxyFactoryBean proxyFactory = new SpringRestInvokerProxyFactoryBean();
              proxyFactory.setBaseUrl("http://localhost/bankservice");
              proxyFactory.setRemoteServiceInterfaceClass(BankService.class);
              return proxyFactory;
          }
      

      然后你可以自动装配接口类:

      @Autowired
      BookService bookService;
      

      【讨论】:

        【解决方案6】:

        我也为此制作了my own library。我想要一些尽可能小的东西,只将自己添加到类路径中并且没有传递依赖。

        一个客户端是这样创建的:

        final StoreApi storeApi = SpringRestTemplateClientBuilder
          .create(StoreApi.class)
          .setRestTemplate(restTemplate)
          .setUrl(this.getMockUrl())
          .build();
        

        调用方法时会执行休息请求:

        storeApi.deleteOrder(1234L);
        

        is 支持两种方法签名:

        • ResponseEntity<X> deleteOrder(Long)
        • X deleteOrder(Long)

        【讨论】:

          猜你喜欢
          • 2018-01-18
          • 1970-01-01
          • 1970-01-01
          • 2013-07-27
          • 2010-10-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多