Java 使用Apache Thrift和TServlet执行服务多路复用
我有一个系统(Java with Spring Framework),它使用TServlet类通过HTTP公开了7个不同的Apache Thrift servlet。目前,它们都需要自己的servlet、servlet映射、处理器、处理程序等。因此,实现客户端还必须保留不同服务的所有不同URL的内部列表 我知道Apache Thrift在使用Java 使用Apache Thrift和TServlet执行服务多路复用,java,spring,servlets,thrift,Java,Spring,Servlets,Thrift,我有一个系统(Java with Spring Framework),它使用TServlet类通过HTTP公开了7个不同的Apache Thrift servlet。目前,它们都需要自己的servlet、servlet映射、处理器、处理程序等。因此,实现客户端还必须保留不同服务的所有不同URL的内部列表 我知道Apache Thrift在使用TServer及其衍生产品时支持多路复用,使用TMultiplexingProcessor,但是由于我使用的是Spring和我的Servlet,处理程序和处
TServer
及其衍生产品时支持多路复用,使用TMultiplexingProcessor
,但是由于我使用的是Spring和我的Servlet,处理程序和处理器都是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;
}
}
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
等等。好的,算出了。这可能不是最好的方法,所以我欢迎批评
以下是我的艰难步骤:
TMultiplexedProcessor
UserServiceProcessor
都有handler
属性和相应的getter和setterApiMultiplexingProcessor
:
@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
在我的情况下,这一切都可能对其他人有所帮助,所以请享受
注意:在调整客户端时,请确保使用t多路协议
,以便在与服务器通话时传递服务名称,例如:
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);
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);