最近公司内部系统要做数据对接,故使用 jersey 来做 restful webservice 接口设计。由于 spring boot 已经集成 jersey,估计直接导入 spring-boot-starter-jersey 就好了。

在测试时候除了遇到中文乱码之外花费了比较长的时间,其余暂时没遇到大的问题。然而发布的时候发现了一个坑。

public class JerseyConfig extends ResourceConfig {

    public JerseyConfig(){
//registerClasses(findAllClasses());
packages("com.xx");
// 注册日志
register(LoggingFeature.class);
// 异常处理
register(ExceptionHandler.class);
// 跨域过滤器注册
register(CorsFilter.class); }
}

jersey 是使用 register(Class clazz) 或者 packages("packageName") 来注册或者扫描来加载所需的类到容器中的。然而在实际项目中,使用 register(Class clazz) 会写大量的注册类,依赖性太强,而且在maven多模块中更不好处理。

而使用 packages 来扫描,在开发测试的时候倒没发现什么问题,但是使用 spring boot 打成 jar 包运行时,会产生 FileNotFound 的错误,这是因为 使用 jersey 的 packages 扫描的机制是无法扫描到 jar 中的 class 文件的。

由于使用的是 spring boot,spring 的 component scan 是可以做到的。故参考 spring 扫描机制的源码,将 jar 中的 class 文件加载进来就好了。

代码如下:

import lombok.extern.slf4j.Slf4j;
import org.glassfish.jersey.logging.LoggingFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.util.ClassUtils; import java.io.IOException;
import java.util.HashSet;
import java.util.Set; /**
* @author gongtao
* @version 2018-04-23 10:15
**/
@Configuration
@Slf4j
public class JerseyConfig extends ResourceConfig { public JerseyConfig(){
//扫描注册
registerClasses(findAllClasses());
// 注册日志
register(LoggingFeature.class);
// 异常处理
register(ExceptionHandler.class);
// 跨域过滤器注册
register(CorsFilter.class); } /**
* 由于spring boot 打包为jar包,jersey packages 无法扫描jar对应的文件夹的文件,故自定义包扫描
* @return
*/
private Set<Class<?>> findAllClasses(){
String scanPackages = "com.xxx.eoms.innerinterface.interfaces.resource.*";
ClassLoader loader = this.getClass().getClassLoader();
Resource[] resources = new Resource[0];
try {
resources = scan(loader, scanPackages);
} catch (IOException e) {
log.error("加载class异常",e);
}
return convert(loader, resources);
} /**
* 扫描 jar 包
* @param loader
* @param packageName
* @return
* @throws IOException
*/
private Resource[] scan(ClassLoader loader, String packageName) throws IOException {
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(loader);
String pattern = "classpath*:" + ClassUtils.convertClassNameToResourcePath(packageName) + "/**/*.class";
return resolver.getResources(pattern);
} /**
* 加载 class
* @param loader
* @param resource
* @return
*/
private Class<?> loadClass(ClassLoader loader,Resource resource) {
try {
CachingMetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(loader);
MetadataReader reader = metadataReaderFactory.getMetadataReader(resource);
return ClassUtils.forName(reader.getClassMetadata().getClassName(), loader);
} catch (LinkageError | ClassNotFoundException e) {
if (log.isDebugEnabled()) {
log.debug("Ignoring candidate class resource " + resource + " due to " + e);
}
return null;
} catch (Throwable e) {
if (log.isWarnEnabled()) {
log.warn("Unexpected failure when loading class resource " + resource, e);
}
return null;
}
} /**
* resources 转换为 Set<Class>
* @param loader
* @param resources
* @return
*/
private Set<Class<?>> convert(ClassLoader loader,Resource[] resources){
Set<Class<?>> classSet = new HashSet<>(resources.length);
for (Resource resource : resources){
Class<?> clazz = loadClass(loader, resource);
if (clazz != null){
classSet.add(clazz);
}
}
return classSet;
}

jersey在 spring boot 添加 packages 扫描路径支持的更多相关文章

  1. Spring boot 默认静态资源路径与手动配置访问路径的方法

    这篇文章主要介绍了Spring boot 默认静态资源路径与手动配置访问路径的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下   在application.propertis中配置 ##端口号 ...

  2. Spring Boot 添加JSP支持【转】

    Spring Boot 添加JSP支持 大体步骤: (1)            创建Maven web project: (2)            在pom.xml文件添加依赖: (3)     ...

  3. spring boot: @EnableScheduling开启计划任务支持,@Scheduled计划任务声明

    spring boot: @EnableScheduling开启计划任务支持, @Scheduled计划任务声明 package ch2.scheduler2; //日期转换方式 import jav ...

  4. spring boot 添加拦截器

    构建一个spring boot项目. 添加拦截器需要添加一个configuration @Configuration @ComponentScan(basePackageClasses = Appli ...

  5. Spring Boot 添加jersey-mvc-freemarker依赖后内置tomcat启动不了解决方案

    我在我的Spring Boot 项目的pom.xml中添加了jersey-mvc-freemarker依赖后,内置tomcat启动不了. 报错信息如下: org.springframework.con ...

  6. spring boot 添加拦截器的简单实例(springBoot 2.x版本,添加拦截器,静态资源不可访问解决方法)

    spring中拦截器主要分两种,一个是HandlerInterceptor,一个是MethodInterceptor 一.HandlerInterceptor HandlerInterceptor是s ...

  7. spring boot 添加整合ssl使得http变成https方法

    1. https出现的背景:(1)都知道http传输协议是裸漏的,明文传输的,极易被黑客拦截,因此,(2)人们想出的使用加密,也就是 对称加密 例如aes,不过这个由于因为对称加密需要每个客户端和服务 ...

  8. spring boot mybatis没有扫描jar中的Mapper接口

    只需要在spring boot启动类上加上注解,并指定jar包中接口文件包路径即可 如下: @ComponentScan(basePackages = "com.xx") @Map ...

  9. 为项目配置了Bean,结果Spring Boot并没有扫描到

    问题如图,而这个问题遇见的场景是因为自己在一个基础项目里面配置cros,按照网上的说法都配置了一边,结果发现前后端的通讯仍然报跨域问题.后来怀疑是否bean并没有被注入进去,导致没有生效,于是在代码中 ...

随机推荐

  1. 过滤emoji表情符

    1.使用正则匹配 public  function remove_emoji($text){        return preg_replace('/([0-9|#][\x{20E3}])|[\x{ ...

  2. Python sys和shutil模块

    # !/user/bin/python # -*- coding: utf-8 -*- import sys # version 获取版本信息 sys.version # maxint 支持的最大in ...

  3. 电脑开机失败提示"用户配置文件服务登录失败"的三种解决办法

    最近遇到这样一个怪现象,就是每次打开电脑输入密码,突然提示"User Profile Service 服务未能登录,无法加载用户配置文件",然后就没办法正常开机了,为什么会这样呢? ...

  4. wukong.go

    package wukong import (     _ "github.com/boltdb/bolt"     _ "github.com/cznic/kv&quo ...

  5. 复仇者联盟3热映,我用python爬取影评告诉你它都在讲什么

    Python(发音:英[?pa?θ?n],美[?pa?θɑ:n]),是一种面向对象.直译式电脑编程语言,也是一种功能强大的通用型语言,已经具有近二十年的发展历史,成熟且稳定.它包含了一组完善而且容易理 ...

  6. linux学习之路(3)

    vim编辑器使用  命令模式:控制光标移动,可对文本进行复制.粘贴.删除和查找等工作. 输入模式:正常的文本录入. 末行模式:保存或退出文档,以及设置编辑环境. vim中常用命令: dd 删除(剪切) ...

  7. Dubbo原理和源码解析之服务引用

    一.框架设计 在官方<Dubbo 开发指南>框架设计部分,给出了引用服务时序图: 另外,在官方<Dubbo 用户指南>集群容错部分,给出了服务引用的各功能组件关系图: 本文将根 ...

  8. 关于linux下部署JavaWeb项目,nginx负责静态资源访问,tomcat负责处理动态请求的nginx配置

    1.项目的运行环境 linux版本 [root@localhost ~]# cat /proc/version Linux version -.el6.x86_64 (mockbuild@x86-.b ...

  9. LVS+keepalived负载均衡

    背景:         随着你的网站业务量的增长你网站的服务器压力越来越大?需要负载均衡方案!商业的硬件如F5又太贵,你们又是创业型互联公司如何有效节约成本,节省不必要的浪费?同时实现商业硬件一样的高 ...

  10. Java基础-工厂设计模式(三锅的肥鸡)

    ---恢复内容开始---   1)还没有工厂时代:假如还没有工业革命,如果一个你要一架飞机,一般的做法是自己去建造一架飞机,然后拿来开 通常的结果就是 有些时候 要么专科螺钉 没打好  要么就是 那个 ...