最近公司一个新项目,开发团队分布在不同的国度,加拿大团队负责网站前端开发,国内团队负责后台服务端开发,前端和后端需要进行数据交互和对接,这就少不了使用REST编写API接口这种场景,两个开发小组之间就需要已规范的文档作为标准和协作基础。对于Jersey和swagger,我以前并未了解过,在最近的学习过程中也发现这方面的中文文档也不是很多(英文不好),于是把我最近学习到的整理分享给大家,一来给后面学习的博友们做个参考,二来也方便自己以后查阅。废话不多说,先介绍下如何使用Jersey构建RESTful Web服务。
REST:是Roy Fielding 2000年在博士论文中提出的。需要注意的是REST是设计风格,不是标准。REST中最重要的概念就是资源(Resources),使用URL定位到唯一资源,对于资源的创建、删除、修改和获取(CRUD)正好对应HTTP协议提供的POST、DELETE、PUT和GET方法。首先我们需要做到一点,将所有REST请求发送到Jersey容器中,那么我们在web.xml中定义一个servlet调度程序,清单如下:
pom.xml
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
<version>2.5.1</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-jersey-jaxrs_2.10</artifactId>
<version>1.3.2</version>
<exclusions>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-multipart</artifactId>
</exclusion>
</exclusions>
</dependency>
一、 jersey配置:
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.yourcompany.service.rs.RestJaxRsApplication</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.yourcompany.service.rs.resources;com.wordnik.swagger.jaxrs.listing</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
二、swagger配置:
<servlet>
<servlet-name>Jersey2Config</servlet-name>
<servlet-class>com.wordnik.swagger.jersey.config.JerseyJaxrsConfig</servlet-class>
<init-param>
<param-name>api.version</param-name>
<param-value>1.0.0</param-value>
</init-param>
<init-param>
<param-name>swagger.api.basepath</param-name>
<param-value>http://localhost:8080/api</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
RestJaxRsApplication类:
public class RestJaxRsApplication extends ResourceConfig{
public RestJaxRsApplication(){
register(ProductResource.class);
register(RequestContextFilter.class);
register(CORSResponseFilter.class);
register(JacksonFeature.class);
}
}
ProductResource类:
/**
* 产品资源服务API
*/
@Component
@Path("/products")
@Api(value = "/products", description = "core product")
public class ProductResource {
@Autowired
private ProductDAO productDAO;
@POST
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.TEXT_HTML})
@ApiOperation(value = "create product", notes = "More notes about this method", response = String.class, httpMethod = "POST")
@ApiResponses(value = {
@ApiResponse(code = 400, message = "Invalid ID supplied"),
@ApiResponse(code = 404, message = "Product not found")
})
public Response createProduct(Product product) {
//TODO create
return Response.status(Response.Status.CREATED).build();
}
@GET
@Produces({MediaType.APPLICATION_JSON})
@ApiOperation(value = "Find product by ID", notes = "More notes about this method", response = Product.class, httpMethod = "GET")
@ApiResponses(value = {
@ApiResponse(code = 400, message = "Invalid ID supplied"),
@ApiResponse(code = 404, message = "Product not found")
})
public Response getProduct(@ApiParam(value = "Resource identifier", required = false) @QueryParam("id") Integer id) {
if(id ==null){
//TODO getAll
return Response.status(Response.Status.NO_CONTENT).allow("OPTIONS").build();
}else {
//TODO getById
return Response.status(Response.Status.NO_CONTENT).allow("OPTIONS").build();
}
}
@PUT
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.TEXT_HTML})
@ApiOperation(value = "update product", notes = "More notes about this method", response = String.class, httpMethod = "PUT")
@ApiResponses(value = {
@ApiResponse(code = 404, message = "Product not found")
})
public Response updateProduct(Product product) {
//TODO update
return Response.status(Response.Status.OK).build();
}
@DELETE
@Produces({MediaType.TEXT_HTML})
@ApiOperation(value = "remove product by ID", notes = "More notes about this method", response = String.class, httpMethod = "DELETE")
@ApiResponses(value = {
@ApiResponse(code = 404, message = "Product not found")
})
public Response removeProductById(@ApiParam(value = "ID values must", required = true)
@QueryParam("id") Integer id) {
//TODO remove
return Response.status(Response.Status.OK).build();
}
}
启动访问http://localhost:8080/api/api-docs 即可看到所有RESTful接口apis列表,查看单个接口及加上path即可。
配置swagger-ui:
下载swagger-ui相关库,https://github.com/swagger-api/swagger-ui,将dist目录下所有拷贝到项目webapp目录下,修改dist目录中index.html页面中的url。
启动服务器访问:http://localhost:8080/swagger-ui/index.html 看到如下界面就恭喜你了!!!
测试的话,看到页面就懂了,非常简单。
关于jersey和swagger的注解配置说明在下篇博客整理。