gpt4 book ai didi

java - 对公共(public)和私有(private)资源使用不同的路径 Jersey + Spring boot

转载 作者:IT老高 更新时间:2023-10-28 13:59:28 33 4
gpt4 key购买 nike

我正在使用 Spring boot + Jersey + Spring security,我想要公共(public)和私有(private)端点,我想要如下架构:

  • /rest -- 我的根上下文
  • /public -- 我想将我的公共(public)端点放在这个上下文中,它必须在根上下文中,例如 /rest/public/pings
  • /private -- 我想将我的私有(private)端点放在这个上下文中,它必须在根上下文中,例如 /rest/private/accounts

我的配置如下:

Jersey 配置:

@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?

注意:我尝试创建另一个 ResourceConfig,如下所示:

@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 和过滤器的,分别是通过 ServletRegistrationBeans 和 FilterRegistrationBeans。要了解该配置如何在幕后工作,您可以查看 JerseyAutoConfiguration 的源代码。

JerseyAutoConfiguration中可以看到注入(inject)了一个ResourceConfig,也就是用于创建Jersey servlet或Jersey的ResourceConfig过滤器(取决于您选择的配置)。所以错误的原因是你不能有模棱两可的bean,你有两个ResourceConfig bean。所以 Spring 不知道该注入(inject)哪一个。

可以 做的是为每个ResourceConfig 使用两个不同的servlet。问题是 Spring Boot 只为 Jersey 连接了一个 servlet,因此您需要自己配置另一个。有两种选择:

  1. 为其中一个 Jersey 应用程序使用 Spring Boot 自动配置,并为您的另一个应用程序添加另一个 ServletRegistrationBean。需要注意的一件事是,您创建的 ServletRegistrationBeanResourceConfig 不应是 Spring 组件(即没有 @Component@配置),否则你仍然会面临同样的错误。

     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;
    }
  2. 根本不要使用 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;
    }

就个人而言,我更喜欢第二种选择,因为当它们都在一个地方时,更容易推理配置。

另外需要注意的是,两个 Jersey 应用程序将完全独立,这意味着您需要为两个应用程序注册提供程序(如过滤器)

关于java - 对公共(public)和私有(private)资源使用不同的路径 Jersey + Spring boot,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35208439/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com