使用 javax.ws.rs.core.Application 实现通用 JAX-RS Web 服务
Implementing generic JAX-RS web service using javax.ws.rs.core.Application
启用 Servlet 3.0 的容器允许我们跳过 web.xml servlet 配置并在您扩展 javax.ws.rs.core.Application
后自动扫描您的代码以获取资源和提供程序,用 @ApplicationPath
注释并执行不覆盖 getClasses()
方法。 (希望我做对了:\)
目前我正在使用 Jersey 实现并使用 @RolesAllowed
注释保护资源方法。为此,我需要注册 org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature
提供商 class,但是,我知道的唯一方法是:
- 在我的
Application
class 的 getClasses()
方法中注册 class (我认为这会导致 Servlet 3.0 容器不自动扫描)
继续使用 web.xml Jersey servlet 设置
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature</param-value>
</init-param>
现在这个问题背后的背景是我可能不得不切换到使用 RESTeasy,如果我使用选项 1,它会在代码中添加一个 Jersey 依赖项并且代码不再是通用的。
如何编写我的代码以使用安全注释,同时维护可以部署到另一个 Servlet 3.0 JAX-RS 实现的通用 JAX-RS 代码?
一种选择是使用 javax.ws.rs.core.Feature
(JAX-RS 标准 class)。您可以在那里注册任何组件,然后用 @Provider
注释 class,它将像任何其他 @Provider
或 @Path
注释 class
@Provider
public class MyFeature implements Feature {
@Overrride
public boolean configure(FeatureContext context) {
context.register(RolesAllowedDynamicFeature.class);
}
}
请注意,由于您正在使用 Jersey 功能,您的应用程序不再独立于实现,因此您不妨一直使用 Jersey。其一,Jersey 不建议扫描 class 路径,这是你正在做的事情的影响。相反,Jersey 有一种机制允许您递归扫描包(及其子包)。所以你可以改为
@ApplicationPath("..")
public class AppConfig extends ResourceConfig {
public AppConfig() {
packages("the.packages.to.scan");
register(RolesAllowedDynamicFeature.class);
}
}
请注意 ResourceConfig
是 Application
的子class
另请参阅:
注:
如果您想坚持使用 class 路径扫描机制,并希望使项目独立于任何 Jersey 依赖项,您还可以覆盖 Application
[中的 Map<String, Object> getProperties()
class。在返回的 Map
中,您可以添加本来要添加到 web.xml
中的 属性
@Override
public Map<String, Object> getProperties() {
Map<String, Object> props = new HashMap<>();
props.put("jersey.config.server.provider.classnames",
"org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature");
return props;
}
但是即使源代码是独立于实现的,应用程序仍然依赖于 Jersey 角色功能。如果您决定要移植,您仍然需要替换该功能。
如果您想保持完全独立,您可以自己实现该功能。并没有那么复杂。您可以查看 the source code for RolesAllowedDynamicFeature
。如果您决定尝试实施相同的方法,只需将您的实施 class 注释为 @Provider
,它就会被采纳。
启用 Servlet 3.0 的容器允许我们跳过 web.xml servlet 配置并在您扩展 javax.ws.rs.core.Application
后自动扫描您的代码以获取资源和提供程序,用 @ApplicationPath
注释并执行不覆盖 getClasses()
方法。 (希望我做对了:\)
目前我正在使用 Jersey 实现并使用 @RolesAllowed
注释保护资源方法。为此,我需要注册 org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature
提供商 class,但是,我知道的唯一方法是:
- 在我的
Application
class 的getClasses()
方法中注册 class (我认为这会导致 Servlet 3.0 容器不自动扫描) 继续使用 web.xml Jersey servlet 设置
<init-param> <param-name>jersey.config.server.provider.classnames</param-name> <param-value>org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature</param-value> </init-param>
现在这个问题背后的背景是我可能不得不切换到使用 RESTeasy,如果我使用选项 1,它会在代码中添加一个 Jersey 依赖项并且代码不再是通用的。
如何编写我的代码以使用安全注释,同时维护可以部署到另一个 Servlet 3.0 JAX-RS 实现的通用 JAX-RS 代码?
一种选择是使用 javax.ws.rs.core.Feature
(JAX-RS 标准 class)。您可以在那里注册任何组件,然后用 @Provider
注释 class,它将像任何其他 @Provider
或 @Path
注释 class
@Provider
public class MyFeature implements Feature {
@Overrride
public boolean configure(FeatureContext context) {
context.register(RolesAllowedDynamicFeature.class);
}
}
请注意,由于您正在使用 Jersey 功能,您的应用程序不再独立于实现,因此您不妨一直使用 Jersey。其一,Jersey 不建议扫描 class 路径,这是你正在做的事情的影响。相反,Jersey 有一种机制允许您递归扫描包(及其子包)。所以你可以改为
@ApplicationPath("..")
public class AppConfig extends ResourceConfig {
public AppConfig() {
packages("the.packages.to.scan");
register(RolesAllowedDynamicFeature.class);
}
}
请注意 ResourceConfig
是 Application
另请参阅:
注:
如果您想坚持使用 class 路径扫描机制,并希望使项目独立于任何 Jersey 依赖项,您还可以覆盖 Application
[中的 Map<String, Object> getProperties()
class。在返回的 Map
中,您可以添加本来要添加到 web.xml
@Override
public Map<String, Object> getProperties() {
Map<String, Object> props = new HashMap<>();
props.put("jersey.config.server.provider.classnames",
"org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature");
return props;
}
但是即使源代码是独立于实现的,应用程序仍然依赖于 Jersey 角色功能。如果您决定要移植,您仍然需要替换该功能。
如果您想保持完全独立,您可以自己实现该功能。并没有那么复杂。您可以查看 the source code for RolesAllowedDynamicFeature
。如果您决定尝试实施相同的方法,只需将您的实施 class 注释为 @Provider
,它就会被采纳。