pbe*_*ean 11 java rest spring jax-rs resteasy
我在一个应用程序中有两个单独的REST服务.让我们说一个主要的"人"服务和一个辅助"管理"服务.我想要的是在服务器上的不同路径中公开它们.我正在使用JAX-RS,RESTEasy和Spring.
例:
@Path("/people")
public interface PeopleService {
// Stuff
}
@Path("/management")
public interface ManagementService {
// Stuff
}
Run Code Online (Sandbox Code Playgroud)
在web.xml我目前有如下设置:
<listener>
<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<listener>
<listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/public</param-value>
</context-param>
<servlet>
<servlet-name>Resteasy</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Resteasy</servlet-name>
<url-pattern>/public/*</url-pattern>
</servlet-mapping>
Run Code Online (Sandbox Code Playgroud)
在PeopleService和ManagementService实施只是春豆.上面的web.xml配置将它们都暴露在外/public(因此分别具有/public/people和/public/management).
我想要完成的是暴露PeopleServiceon /public,以便完整路径将成为/public/people并暴露ManagementServiceon /internal,以便它的完整路径将成为/internal/management.
不幸的是,我无法更改@Path注释的值.
我该怎么办?
Ant*_*ton 15
实际上你可以.经过几个小时的调试后,我想出了这个:
1)在你的声明中声明多个resteasy servlet web.xml(在我的情况下为两个)
<servlet>
<servlet-name>resteasy-servlet</servlet-name>
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
<init-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/openrest</param-value>
</init-param>
<init-param>
<param-name>resteasy.resources</param-name>
<param-value>com.mycompany.rest.PublicService</param-value>
</init-param>
</servlet>
<servlet>
<servlet-name>private-resteasy-servlet</servlet-name>
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
<init-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/protectedrest</param-value>
</init-param>
<init-param>
<param-name>resteasy.resources</param-name>
<param-value>com.mycompany.rest.PrivateService</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>private-resteasy-servlet</servlet-name>
<url-pattern>/protectedrest/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>resteasy-servlet</servlet-name>
<url-pattern>/openrest/*</url-pattern>
</servlet-mapping>
Run Code Online (Sandbox Code Playgroud)
请注意我们初始化个人resteasy.servlet.mapping.prefix和resteasy.resources每个servlet 的事实.请不要忘记不包含任何botstrap类作为过滤器或servlet!并禁用自动扫描.
2)创建一个过滤器,清除RESTeasy在上下文中保存的全局信息中的应用程序:
public class ResteasyCleanupFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
request.getServletContext().setAttribute(ResteasyProviderFactory.class.getName(), null);
request.getServletContext().setAttribute(Dispatcher.class.getName(), null);
chain.doFilter(request, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
Run Code Online (Sandbox Code Playgroud)
注册它以获取对您服务的任何请求(此处我将其用于所有简化请求):
<filter>
<filter-name>CleanupFilter</filter-name>
<filter-class>com.mycompany.ResteasyCleanupFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CleanupFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Run Code Online (Sandbox Code Playgroud)
这就是它!现在你有两个不同的REST服务,它们位于不同的前缀下:/openrest这意味着服务所有的公共请求/protectedrest,并关注应用程序中的所有私有内容.
那么它为什么会起作用(或者为什么它不起作用)呢?
当你openrest第一次调用实例时,它会尝试初始化自己,并在完成时将状态保存在全局中,servletContext如下所示:
servletContext.setAttribute(ResteasyProviderFactory.class.getName(), deployment.getProviderFactory());
servletContext.setAttribute(Dispatcher.class.getName(), deployment.getDispatcher());
Run Code Online (Sandbox Code Playgroud)
如果你愿意,那么你的第二个电话/protectedrest就会得到相同的配置!这就是为什么你需要在某些地方清理这些信息.这就是为什么我们使用我们CleanupFilter清空上下文的原因,所以全新的rest servlet可以使用我们声明的所有init参数初始化自己.
这是一个黑客攻击,但它可以解决问题.
该解决方案针对RESTEasy 2.3.6进行了测试
EDITED
兼容3.0.9.final!
AFAIK,您的 JAX-RS 实现不能有多个 servlet 映射。您可以做的是:将 RESTEasy 映射到'/'(或者'/api'例如,如果您的应用程序有其他资源需要服务,并且您不希望 JAX-RS 部分干扰),然后使用以下@Path注释:
@Path("/public/people")
public interface PeopleService {
// Stuff
}
@Path("/internal/management")
public interface ManagementService {
// Stuff
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6893 次 |
| 最近记录: |