Java技术升华jersey

Jersey 开发RESTful(十八) Springboot集

2018-02-08  本文已影响940人  叩丁狼教育

【原创文章,转载请注明原文章地址,谢谢!】

在本节中,我们将介绍Springboot对Jersey的集成。Springboot简化了太多的第三方框架集成,在Springboot中使用Jersey是非常简单的事情。

Springboot支持Jersey1.x和Jersey2.x,我们这里只介绍Springboot对Jersey2.x的支持。因为我们前面介绍了Spring对Jersey有原生的集成策略,所以springboot对jersey的集成变得非常简单。

第一步,引入Springboot对jersey的starter包:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jersey</artifactId>
</dependency>

第二步,Springboot需要对Jersey的配置对象,有三种配置方式,第一种方式创建一个自定义的ResourceConfig,第二种方式,返回一个ResourceConfig类型的@Bean,第三种方式,配置一组ResourceConfigCustomizer对象;我们分别来看看。在测试之前,我们还是准备好我们的服务对象和资源类:

public interface ISomeService {

    void sayHi(String msg);
}

@Service
public class SomeServiceImpl implements ISomeService {
    @Override
    public void sayHi(String msg) {
        System.out.println(msg);
    }
}

接下来准备我们的资源类:

@Component
@Path("resource")
public class SpringbootResource {

    @Autowired
    private ISomeService someService;

    @Path("sayhi")
    @GET
    public String sayHi(@QueryParam("msg") String msg) {
        this.someService.sayHi(msg);
        return "success";
    }
}

这三段代码非常简单,就不做过多解释了。接下来看看我们Springboot的主配置对象:

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

    public static void main(String[] args) {
        new Application()
                .configure(new SpringApplicationBuilder(Application.class))
                .run(args);
    }
}

我这里使用的是Springboot提供的SpringBootServletInitializer类启动的应用,当然在main方法中也可以使用最简单的SpringApplication.run(Application.class, args)来启动也行。

创建自定义ResourceConfig:

@Component
public class JerseyConfig extends ResourceConfig {
    public JerseyConfig() {
        register(SpringbootResource.class);
    }
}

只需要保证JerseyConfig在Application类能够扫描的包下即可。
这个时候发送测试请求:
localhost:8080/resource/sayhi?msg=wolfcode即可。

这个地方注意两点,

@Component
@ApplicationPath("webapi")
public class JerseyConfig extends ResourceConfig {

那么我们的资源地址就变为了:
localhost:8080/webapi/resource/sayhi?msg=wolfcode

Jersey’s support for scanning executable archives is rather limited. For example, it cannot scan for endpoints in a package found in WEB-INF/classes when running an executable war file. To avoid this limitation, the packages method should not be used and endpoints should be registered individually using the register method

即使用Jersey的packages是比较局限的,比如在应用运行在war包中的时候,就不能扫描到其中的包。所以建议单独的为每一个资源类独立使用register方法注册。

ResourceConfig类型的@Bean

第二种方式,使用@Bean创建一个ResourceConfig类实例即可。注释掉上节中的JerseyConfig类,我们只需要修改一下Appication类,添加方法:

@Bean
public ResourceConfig resourceConfig() {
    ResourceConfig config = new ResourceConfig();
    config.register(SpringbootResource.class);
    return config;
}

即可。但是在这种情况下,想要配置Jersey的基础路径,就需要在application.properties文件中配置一个

spring.jersey.application-path=webapi

即可。

使用ResourceConfigCustomizer

Springboot提供了一个ResourceConfigCustomizer接口,让我们更灵活的对ResourceConfig对象进行配置。要使用该接口,我们先注释掉上面两节的相关代码,然后创建一个类:

@Component
public class MyResourceConfigCustomizer implements ResourceConfigCustomizer {
    @Override
    public void customize(ResourceConfig config) {
        config.register(SpringbootResource.class);
    }
}

该接口很简单,传入一个ResourceConfig实例,我们就可以针对这个实例进行相关配置。但是要让这个传入的config生效,我们还需要在Application类中提供一个基础的ResourceConfig类即可:

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

    @Bean
    public ResourceConfig resourceConfig() {
        return new ResourceConfig();
    }

    public static void main(String[] args) {
        new Application()
                .configure(new SpringApplicationBuilder(Application.class))
                .run(args);
    }
}

这种方式对比第二种方式的好处在于,我们可以把资源类的注册,过滤器,拦截器,Entity Provider,Feature等不同类型的组件注册从主类中分开,在代码管理上会更加清晰。

其他细节

1,Jersey和Springboot的集成有两种方式,一种是使用Filter的方式注册,一种是使用Servlet的方式注册,默认使用的是Servlet的方式,也可以通过spring.jersey.type=filter或者spring.jersey.type=servlet来控制。具体的代码可以参考JerseyAutoConfiguration类中的:

@Bean
@ConditionalOnMissingBean(name = "jerseyFilterRegistration")
@ConditionalOnProperty(prefix = "spring.jersey", name = "type", havingValue = "filter")
public FilterRegistrationBean jerseyFilterRegistration() {


@Bean
@ConditionalOnMissingBean(name = "jerseyServletRegistration")
@ConditionalOnProperty(prefix = "spring.jersey", name = "type", havingValue = "servlet", matchIfMissing = true)
public ServletRegistrationBean jerseyServletRegistration() {

从这两段代码我们也能看出来,当使用的是Filter的时候,Springboot实际上注册了一个名字为jerseyFilterRegistration的FilterRegistrationBean;而使用的是Servlet的时候,Springboot实际上注册了一个名字为jerseyServletRegistration的ServletRegistrationBean。那么这些都是如果我们要更进一步定制Jersey启动方式可以扩展的点。

2,如果使用Servlet的方式启动,默认是使用的延迟启动。我们可以通过jerseyServletRegistration方法的代码就可以看出来:

    registration.setName(getServletRegistrationName());
    registration.setLoadOnStartup(this.jersey.getServlet().getLoadOnStartup());
    return registration;

第二句代码setLoadOnStartup方法,调用的是this.jersey.getServlet().getLoadOnStartup(),而这个地方的jersey就是JerseyProperties对象:

@ConfigurationProperties(prefix = "spring.jersey")
public class JerseyProperties {

其中servlet的类代码为:

public static class Servlet {

    /**
     * Load on startup priority of the Jersey servlet.
     */
    private int loadOnStartup = -1;

    public int getLoadOnStartup() {
        return this.loadOnStartup;
    }

    public void setLoadOnStartup(int loadOnStartup) {
        this.loadOnStartup = loadOnStartup;
    }

}

可以看到,默认值为-1;那么我们只需要在application.properties中配置spring.jersey.servlet.loadOnStartup=1即可迫切让Jersey的Servlet实例化。

更多的配置,建议有兴趣的童鞋可以去看看org.springframework.boot.autoconfigure.jersey包中的两个类:

@ConfigurationProperties(prefix = "spring.jersey")
public class JerseyProperties {

    /**
     * Init parameters to pass to Jersey via the servlet or filter.
     */
    private Map<String, String> init = new HashMap<String, String>();

小结

Springboot集成Jersey总体来说还是非常简单。只是额外想说的就是,针对Springboot集成第三方框架,还是希望童鞋们能够理解Springboot的自动配置原理,那么看看相关代码,那么该怎么集成,该怎么配置,有哪些配置,有哪些扩展点都非常简单了。

至此,Jersey的普通使用我们就介绍到这里。当然,Jersey还有非常多非常多的细节的点,比如URI构造,比如WADL支持,比如基于Hyperlink的应用构建,比如基础的权限控制,OAuth2.0的支持,比如Jersey应用的监控,异步请求的支持,基于JSR-330的验证等,因为使用的频率和篇幅的问题,我们就后面有机会再介绍。

当然,如果通过Jersey这系列的文章,当你对Jersey有了一个初步的理解之后,通过Jersey的官方文档https://jersey.github.io/documentation/latest/user-guide.html学习相关内容也是非常轻松的。

后面我们将开始介绍REST API文档生成相关内容。

WechatIMG7.jpeg
上一篇下一篇

猜你喜欢

热点阅读