gpt4 book ai didi

java - 使用 Apache Thrift 和 TServlet 执行服务多路复用

转载 作者:行者123 更新时间:2023-12-01 12:53:10 25 4
gpt4 key购买 nike

我有一个系统(带有 Spring Framework 的 Java),它使用 TServlet 类通过 HTTP 公开 7 个不同的 Apache Thrift servlet。目前,它们都需要自己的 Servlet、ServletMappings、处理器、处理程序等。因此实现客户端还必须保留不同服务的所有各种 URL 的内部列表。

我知道 Apache Thrift 在使用 TServer 及其派生产品时通过使用 TMultiplexingProcessor 支持多路复用,但是由于我使用 Spring 并且我的 Servlet、Handler 和 Processor 都是 Spring Bean 相互自动连接,我不确定如何继续。

以下是其中一项服务如何连接的示例:

UserServiceHandler.java

@Component
public class UserServiceHandler implements UserService.Iface {
@Override
public User getUser(String userId) throws TException {
// implementation logic goes here
}
}

UserServiceProcessor.java

@Component
public class UserServiceProcessor extends UserService.Processor<UserServiceHandler> {

private UserServiceHandler handler;

@Autowired
public UserServiceProcessor(UserServiceHandler iface) {
super(iface);
handler = iface;
}

public UserServiceHandler getHandler() {
return handler;
}

public void setHandler(UserServiceHandler handler) {
this.handler = handler;
}

}

UserServiceServlet.java

@Component
public class UserServiceServlet extends TServlet {
private UserServiceProcessor processor;

@Autowired
public UserServiceServlet(UserServiceProcessor p) {
super(p, new TBinaryProtocol.Factory());
processor = p;
}
}

Servlet 注册

ServletRegistration.Dynamic userService = servletContext.addServlet("UserServiceServlet", (UserServiceServlet) ctx.getBean("userServiceServlet"));
userService.setLoadOnStartup(1);
userService.addMapping("/api/UserService/*");
// This same block repeated 7 times for each *ServiceServlet with different mappings

我希望将所有 7 个服务处理程序映射到一个 URL,例如 /api/*。这可能吗?我想我必须创建一个 servlet 和处理器,但我不确定它们应该是什么样子。我的处理器扩展了 UserService.Processor 等。

最佳答案

好的,明白了。可能不是最好的方法,欢迎批评指正。

这是我的粗略步骤:

  1. 保持处理程序类的原样。
  2. 创建一个扩展 TMultiplexedProcessor 的新类
  3. 创建一个扩展 TServlet 的新类
  4. 所有处理器(例如UserServiceProcessor)都有一个handler属性和相应的getter和setter

这是我的ApiMultiplexingProcessor:

@Component
public class ApiMultiplexingProcessor extends TMultiplexedProcessor {

UserServiceHandler userServiceHandler;
ReportServiceHandler reportServiceHandler;
// ... more service handlers can go here

@Autowired
public ApiMultiplexingProcessor(UserServiceProcessor userServiceProcessor, ReportServiceProcessor reportServiceProcessor) {
this.registerProcessor("UserService", userServiceProcessor);
this.registerProcessor("ReportService", reportServiceProcessor);
// add more registerProcessor lines here for additional services

userServiceHandler = userServiceProcessor.getHandler();
reportServiceHandler = reportServiceProcessor.getHandler();
// set any additional service handlers here
}

// getters and setters for the handlers

public UserServiceHandler getUserServiceHandler() {
return userServiceHandler;
}

public void setUserServiceHandler(UserServiceHandler userServiceHandler) {
this.userServiceHandler = userServiceHandler;
}

public ReportServiceHandler getReportServiceHandler() {
return reportServiceHandler;
}

public void setReportServiceHandler(ReportServiceHandler reportServiceHandler) {
this.reportServiceHandler = reportServiceHandler;
}
}

因此,稍微解释一下上面的内容,如果添加任何其他服务,则需要将 *ServiceHandler 类添加为此类上的字段,并创建 getter 和 setter 等。

现在我们已经有了它,我们可以创建一个新的单个 servlet,并将其添加到 servlet 上下文中。

这是我的ApiServlet:

@Component
public class ApiServlet extends TServlet {
private ApiMultiplexingProcessor processor;

@Autowired
public ApiServlet(ApiMultiplexingProcessor p) {
super(p, new TBinaryProtocol.Factory());
processor = p;
}
}

然后您只需像以前一样将此 servlet 添加到 servlet 上下文(来自 bean)即可:

ServletRegistration.Dynamic api = servletContext.addServlet("ApiServlet", (ApiServlet) ctx.getBean("apiServlet"));
api.setLoadOnStartup(1);
api.addMapping("/api/*");
// yay now we have a single URL and a single servlet

这一切可能对其处于我这种情况的其他人有帮助,所以享受吧!

附注确保在调整客户端时使用 TMultiplexedProtocol ,以便在与服务器通信时可以传递服务名称,例如

TTransport transport = new THttpClient(new Uri("https://myapp.com/api/"));
TProtocol protocol = new TBinaryProtocol(transport);
TMultiplexedProtocol mp = new TMultiplexedProtocol(protocol, "UserService");
UserService.Client userServiceClient = new UserService.Client(mp);

关于java - 使用 Apache Thrift 和 TServlet 执行服务多路复用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24063686/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com