Springboot 整合Jersey
在查看EurekaServer 服务端代码时偶然看到Jersey这个东西,简单记录下。
1. 简介
Jersey是一个RESTFUL请求服务JAVA框架,与常规的JAVA编程使用的struts框架类似,它主要用于处理业务逻辑层。
1.X的版本是sun公司提供的独立的jar包,在2.X版本中已经将jersey融合到JavaSE中,在javax.ws.rs.*包中。
参考:https://eclipse-ee4j.github.io/jersey/
2. Springboot 整合Jersey
参考: https://docs.spring.io/spring-boot/docs/2.1.4.RELEASE/reference/htmlsingle/#boot-features-jersey
1. 引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jersey</artifactId> </dependency>
2. 编写资源(在Jersey 中一切借口皆为资源)
package cn.xm.controller; import cn.xm.bean.common.Message; import cn.xm.mapper.common.MessageMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.ws.rs.*; import java.util.List; @Component @Path("/{version}/messages") // 类似SpringMVC,这里可以不写, 也可以用通配符 //@Path("/messages") // 类似SpringMVC,这里可以不写, 也可以用通配符 @Slf4j //@Produces({"application/xml", "application/json"}) // 标记可生产的数据类型, 也就是客户端Accept 的类型 //@Consumes({"application/json", "application/xml", "*/*"}) // 标记可以接受的类型, 也就是Content-Type public class MessageResource { @Autowired private MessageMapper messageMapper; @GET @Path("/index") public String index() { return "cn.xm.controller.UserResource.index"; } @GET @Path("/get") public Message get() { List<Message> users = messageMapper.findAll(); return users.get(0); } @GET @Path("/get2") public Message get2() { List<Message> users = messageMapper.findAll(); return users.get(0); } @GET @Path("/get3") public Message get3() { List<Message> users = messageMapper.findAll(); return users.get(0); } @GET @Path("/get4/{pkUser}") public Message get4(@PathParam("pkUser") Integer pkUser, @PathParam("version") String version, @QueryParam("status") String status, @HeaderParam("my_token") String my_token) { log.info("pkUser: {}", pkUser); log.info("version: {}", version); log.info("status: {}", status); log.info("my_token: {}", my_token); return messageMapper.findOne(pkUser); } }
3. 注册资源
package cn.xm.config; import cn.xm.controller.MessageResource; import org.glassfish.jersey.server.ResourceConfig; import org.springframework.stereotype.Component; import javax.ws.rs.ApplicationPath; @Component @ApplicationPath("/testJersey") public class JerseyConfig extends ResourceConfig { public JerseyConfig() { register(MessageResource.class); // 还可以注册过滤器等 // 注册包 // packages("xxx") } }
这里需要注意,ApplicationPath 是指定Jersey 开始的路径,默认是/*。 当我们指定为/testJersey 之后,默认会被重置为/testJersey/*
4. Message 实体类
import cn.xm.bean.AbstractSequenceEntity; import javax.persistence.Column; import javax.persistence.Entity; import javax.xml.bind.annotation.XmlRootElement; //公共信息表 @Entity @XmlRootElement public class Message extends AbstractSequenceEntity { private String name; /** * 用于所属区域 */ private String messageblank; @Column(length = 20000) private String content; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name == null ? null : name.trim(); } public String getMessageblank() { return messageblank; } public void setMessageblank(String messageblank) { this.messageblank = messageblank == null ? null : messageblank.trim(); } public String getContent() { return content; } public void setContent(String content) { this.content = content == null ? null : content.trim(); } }
5. 启动后测试:(会根据我们接受的类型自动返回XML或者JSON)
j@x MINGW64 /e/ideaspace $ curl --header 'Accept: application/json' http://localhost:8088/testJersey/v1/messages/index % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 35 100 35 0 0 1666 0 --:--:-- --:--:-- --:--:-- 1842cn.xm.controller.UserResource.index j@x MINGW64 /e/ideaspace $ curl --header 'Accept: application/json' http://localhost:8088/testJersey/v1/messages/get % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 246 100 246 0 0 11181 0 --:--:-- --:--:-- --:--:-- 11714{"creator":"admin","createtime":"2021-03-11","remark1":null,"remark2":null,"remark3":null,"properties":null,"propertiesMap":{},"id":1,"name":"姹傜編椋?,"messageblank":"缇庨","content":"鍖椾含鍝噷鏈夊ソ鍚冪殑锛?,"createtimeStr":"2021-03-11"} j@x MINGW64 /e/ideaspace $ curl --header 'Accept: application/xml' http://localhost:8088/testJersey/v1/messages/get % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 261 100 261 0 0 13050 0 --:--:-- --:--:-- --:--:-- 13736<?xml version="1.0" encoding="UTF-8" standalone="yes"?><message><createtime>2021-03-11T10:38:19+08:00</createtime><creator>admin</creator><id>1</id><content>鍖椾含鍝噷鏈夊ソ鍚冪殑锛?/content><messageblank>缇庨</messageblank><name>姹傜編椋?/name></message> j@x MINGW64 /e/ideaspace $ curl --header 'Accept: application/xml' --header 'my_token: 111222' http://localhost:8088/testJersey/v1/messages/get4/1?status=1234 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 261 100 261 0 0 9000 0 --:--:-- --:--:-- --:--:-- 9321<?xml version="1.0" encoding="UTF-8" standalone="yes"?><message><createtime>2021-03-11T10:38:19+08:00</createtime><creator>admin</creator><id>1</id><content>鍖椾含鍝噷鏈夊ソ鍚冪殑锛?/content><messageblank>缇庨</messageblank><name>姹傜編椋?/name></message>
控制台日志如下:
2021-03-18 09:21:12.383 INFO 32328 --- [nio-8088-exec-4] cn.xm.controller.MessageResource : pkUser: 1
2021-03-18 09:21:12.383 INFO 32328 --- [nio-8088-exec-4] cn.xm.controller.MessageResource : version: v1
2021-03-18 09:21:12.383 INFO 32328 --- [nio-8088-exec-4] cn.xm.controller.MessageResource : status: 1234
2021-03-18 09:21:12.383 INFO 32328 --- [nio-8088-exec-4] cn.xm.controller.MessageResource : my_token: 111222
3. 自动配置简单查看
参考:org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration 类
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration#jerseyServletRegistration 这里注册一个Servlet:
@Bean @ConditionalOnMissingBean(name = "jerseyServletRegistration") @ConditionalOnProperty(prefix = "spring.jersey", name = "type", havingValue = "servlet", matchIfMissing = true) public ServletRegistrationBean jerseyServletRegistration() { ServletRegistrationBean registration = new ServletRegistrationBean( new ServletContainer(this.config), this.path); addInitParameters(registration); registration.setName(getServletRegistrationName()); registration.setLoadOnStartup(this.jersey.getServlet().getLoadOnStartup()); return registration; }
这里注册的这个ServletContainer 是一个Servlet 也是一个Filter。在下面方法注册为Filter
@Bean @ConditionalOnMissingBean(name = "jerseyFilterRegistration") @ConditionalOnProperty(prefix = "spring.jersey", name = "type", havingValue = "filter") public FilterRegistrationBean jerseyFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(new ServletContainer(this.config)); registration.setUrlPatterns(Arrays.asList(this.path)); registration.setOrder(this.jersey.getFilter().getOrder()); registration.addInitParameter(ServletProperties.FILTER_CONTEXT_PATH, stripPattern(this.path)); addInitParameters(registration); registration.setName("jerseyFilter"); registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class)); return registration; }
所以Jersey 相关的入口就是这个ServletContainer类。 可以理解为也是进入service 之后进行一系列判断之后获取到对应的Resource 进行处理,Resource 可以理解为Handler。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2018-03-27 面试笔记【自己总结】
2018-03-27 Java环境变量配置以及作用、JDK与JRE区别以及命令行引入jar包