Use different paths for public and private resources Jersey + Spring boot(对公共和私有资源使用不同的路径 Jersey + Spring boot)
问题描述
我正在使用 Spring boot + Jersey + Spring security,我想要公共和私有端点,我想要如下架构:
I'm using Spring boot + Jersey + Spring security, I want to have public and private endpoints, I want an schema as follow:
- /rest -- 我的根上下文
- /public -- 我想将我的公共端点放在这个上下文中,它必须在根上下文中,例如
/rest/public/pings
- /private -- 我想将我的私有端点放在这个上下文中,它必须在根上下文中,例如
/rest/private/accounts
- /rest -- My root context
- /public -- I want to place my public endpoints in this context, It must be inside of the root context like
/rest/public/pings
- /private -- I want to place my private endpoints in this context, It must be inside of the root context like
/rest/private/accounts
我的配置如下:
球衣配置:
@Configuration
@ApplicationPath("/rest")
public class RestConfig extends ResourceConfig {
public RestConfig() {
register(SampleResource.class);
}
}
Spring 安全配置:
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
........
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/rest/public/**").permitAll();
http.antMatcher("/rest/**").authorizeRequests().anyRequest().fullyAuthenticated().and().httpBasic();
http.csrf().disable();
}
}
问题是如何在我的/rest 上下文中注册两个应用程序路径,一个用于/public,另一个用于/private?
The question is how can I register two application paths inside of my /rest context, one for /public and the other one for /private ?
注意:我尝试创建另一个 ResourceConfig,如下所示:
NOTE: I tried to create another ResourceConfig as follow:
@Configuration
@ApplicationPath("/rest/public")
public class RestPublicConfig extends ResourceConfig{
public RestPublicConfig() {
register(PingResource.class);
}
}
但我收到下一个错误:
No qualifying bean of type [org.glassfish.jersey.server.ResourceConfig] is defined: expected single matching bean but found 2: restConfig,restPublicConfig
感谢您的帮助:)
推荐答案
在 servlet 容器中,Jersey 运行时作为 servlet 或 servlet 过滤器运行.spring boot 是如何配置 servlet 和过滤器的,分别是通过 ServletRegistrationBean
s 和 FilterRegistrationBeans
.要了解该配置如何在幕后工作,您可以查看 JerseyAutoConfiguration
In a servlet container, the Jersey runtime, runs as either a servlet or as a servlet filter. How spring boot configures servlets and filters is through ServletRegistrationBean
s and FilterRegistrationBeans
, respectively. To get an idea of how that configuration works behind scenes, you can look at the source code for the JerseyAutoConfiguration
在JerseyAutoConfiguration
中可以看到注入了一个ResourceConfig
,也就是用于创建Jersey servlet或Jersey的ResourceConfig
过滤器(取决于您选择的配置).所以错误的原因是你不能有模棱两可的bean,你有两个ResourceConfig
bean.所以 Spring 不知道该注入哪一个.
In the JerseyAutoConfiguration
, you can see that a ResourceConfig
is injected, and that is the ResourceConfig
used to create the Jersey servlet or Jersey filter (depending on your choice of configuration). So the reason for the error is that you can't have ambiguous beans, which you have two ResourceConfig
beans. So Spring doesn't know which one to inject.
您可以 做的是为每个ResourceConfig
使用两个不同的servlet.问题是 Spring Boot 只为 Jersey 连接了一个 servlet,因此您需要自己配置另一个.有两种选择:
What you can do though, is use two different servlets for each ResourceConfig
. The problem is that Spring Boot only hooks you up with one servlet for Jersey, so you need to configure the other one yourself. There are two options:
为其中一个 Jersey 应用程序使用 Spring Boot 自动配置,并为您的另一个应用程序添加另一个
ServletRegistrationBean
.需要注意的一点是,您创建的ServletRegistrationBean
的ResourceConfig
不应是 Spring 组件(即没有@Component
或@配置
),否则你仍然会面临同样的错误.
Use the Spring Boot auto-configuration for one of the Jersey applications, and add another
ServletRegistrationBean
for your other one. The one thing to note is that theResourceConfig
for your createdServletRegistrationBean
should not be a Spring component (i.e. no@Component
or@Configuration
), or else you will still face the same error.
public class PublicConfig extends ResourceConfig {
public PublicConfig() {
register(PingResource.class);
}
}
...
// in your Spring Boot configuration class
@Bean
public ServletRegistrationBean publicJersey() {
ServletRegistrationBean publicJersey
= new ServletRegistrationBean(new ServletContainer(new PublicConfig()));
publicJersey.addUrlMappings("/rest/public/*");
publicJersey.setName("PublicJersey");
publicJersey.setLoadOnStartup(0);
return publicJersey;
}
根本不要使用 Spring Boot 配置.只需创建两个 ServletRegistrationBean
.在这种情况下,您的 ResourceConfig
类都不应该是 Spring bean.
Don't use the Spring Boot configuration at all. Just create two ServletRegistrationBean
s. In this case, none of your ResourceConfig
classes should be Spring beans.
@Bean
public ServletRegistrationBean publicJersey() {
ServletRegistrationBean publicJersey
= new ServletRegistrationBean(new ServletContainer(new PublicConfig()));
publicJersey.addUrlMappings("/rest/public/*");
publicJersey.setName("PublicJersey");
publicJersey.setLoadOnStartup(0);
return publicJersey;
}
@Bean
public ServletRegistrationBean privateJersey() {
ServletRegistrationBean privateJersey
= new ServletRegistrationBean(new ServletContainer(new PrivateConfig()));
privateJersey.addUrlMappings("/rest/private/*");
privateJersey.setName("PrivateJersey");
privateJersey.setLoadOnStartup(1);
return privateJersey;
}
就个人而言,我更喜欢第二种选择,因为当它们都在一个地方时,更容易推理配置.
Personally, I prefer the second option, as it is easier to reason about the configurations when they are all in one place.
另外需要注意的是,两个 Jersey 应用程序将完全独立,这意味着您需要为两个应用程序注册提供程序(如过滤器)
Another thing to note is that the two Jersey applications will be completely independent, meaning you will need to register providers (like filters) for both applications
这篇关于对公共和私有资源使用不同的路径 Jersey + Spring boot的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:对公共和私有资源使用不同的路径 Jersey + Spring boot
基础教程推荐
- 降序排序:Java Map 2022-01-01
- 在 Libgdx 中处理屏幕的正确方法 2022-01-01
- 减少 JVM 暂停时间 >1 秒使用 UseConcMarkSweepGC 2022-01-01
- FirebaseListAdapter 不推送聊天应用程序的单个项目 - Firebase-Ui 3.1 2022-01-01
- 无法使用修饰符“public final"访问 java.util.Ha 2022-01-01
- “未找到匹配项"使用 matcher 的 group 方法时 2022-01-01
- Java:带有char数组的println给出乱码 2022-01-01
- Java Keytool 导入证书后出错,"keytool error: java.io.FileNotFoundException &拒绝访问" 2022-01-01
- 如何使用 Java 创建 X509 证书? 2022-01-01
- 设置 bean 时出现 Nullpointerexception 2022-01-01