Ale*_*sta 12 java rest spring jersey spring-boot
我正在使用Spring boot + Jersey + Spring安全性,我想拥有公共和私有端点,我想要一个架构如下:
/rest/public/pings/rest/private/accounts我的配置如下:
泽西配置:
@Configuration
@ApplicationPath("/rest")
public class RestConfig extends ResourceConfig {
public RestConfig() {
register(SampleResource.class);
}
}
Run Code Online (Sandbox Code Playgroud)
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();
}
}
Run Code Online (Sandbox Code Playgroud)
问题是如何在my/rest上下文中注册两个应用程序路径,一个用于/ public,另一个用于/ private?
注意:我尝试创建另一个ResourceConfig,如下所示:
@Configuration
@ApplicationPath("/rest/public")
public class RestPublicConfig extends ResourceConfig{
public RestPublicConfig() {
register(PingResource.class);
}
}
Run Code Online (Sandbox Code Playgroud)
但是我得到了下一个错误:
No qualifying bean of type [org.glassfish.jersey.server.ResourceConfig] is defined: expected single matching bean but found 2: restConfig,restPublicConfig
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助 :)
Pau*_*tha 13
在servlet容器中,Jersey运行时作为servlet或servlet过滤器运行.spring boot如何配置servlet和过滤器分别是通过ServletRegistrationBeans和FilterRegistrationBeans.要了解该配置如何在幕后工作,您可以查看该源代码JerseyAutoConfiguration
在JerseyAutoConfiguration,你可以看到a ResourceConfig被注入,那就是ResourceConfig用来创建Jersey servlet或Jersey过滤器(取决于你选择的配置).所以错误的原因是你不能有不明确的bean,你有两个ResourceConfigbean.所以Spring不知道要注入哪一个.
但你可以做的是为每个使用两个不同的servlet ResourceConfig.问题是Spring Boot只为你提供了一个针对Jersey的servlet,所以你需要自己配置另一个.有两种选择:
对其中一个Jersey应用程序使用Spring Boot自动配置,为另一个应用程序添加另一个ServletRegistrationBean.需要注意的一点是,ResourceConfig你创建的ServletRegistrationBean不应该是Spring组件(即no @Component或@Configuration),否则你仍然会面临同样的错误.
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;
}
Run Code Online (Sandbox Code Playgroud)根本不要使用Spring Boot配置.只需创建两个ServletRegistrationBean.在这种情况下,您的ResourceConfig类都不应该是Spring bean.
@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;
}
Run Code Online (Sandbox Code Playgroud)就个人而言,我更喜欢第二种选择,因为当它们都在一个地方时,更容易推断配置.
另外需要注意的是,两个Jersey应用程序将完全独立,这意味着您需要为两个应用程序注册提供程序(如过滤器)
您将不被允许为您的资源类创建两个 bean。您也可以使用单个资源类来实现您想要实现的目标。
这是一个例子:
@Path("rest")
public class SampleResourceClass {
@Path("/public/pings")
@GET
public Responce getPings(){
/* Code Here */
}
@Path("/private/accounts")
@GET
public Response getAccounts(){
/* Code Here */
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3523 次 |
| 最近记录: |