【摘要】本文介绍 JAXRS 常用语法与语义,案例则使用 Maven 多模块构建,集成 spring boot,
并使用 swagger 可视化工具测试服务。最终,给出同时支持 JSON 和 XML 的服务配置。
1. 下载 CXF 案例
计算机学习看文档,找教程固然重要。运行官方案例 + 模仿编程才是最佳的学习方法。
编程学习总是满足“一万行定律”,即编写相关代码足够,自然理解编程的要领。
用教学学术语叫“程序性知识”,也如同学习驾驶汽车,开一万公里就学会了。
CXF 提供的案例可在官方下载获取,请下载最新二进制发行版:
http://cxf.apache.org/download.html
解压 samples 目录,作为参考
2. 创建项目
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.me.testgroupId>
<artifactId>my-samplesartifactId>
<packaging>pompackaging>
<version>1.0-SNAPSHOTversion>
<name>My REST Service Samplesname>
<description>My REST Service Samplesdescription>
<url>http://blog.csdn.net/pmlpmlurl>
<properties>
<maven.deploy.skip>truemaven.deploy.skip>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<spring.boot.version>1.3.6.RELEASEspring.boot.version>
<spring.cloud.version>1.1.3.RELEASEspring.cloud.version>
<cxf.version>3.1.10cxf.version>
<feign.version>8.18.0feign.version>
properties>
<dependencies>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-jdk14artifactId>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>jcl-over-slf4jartifactId>
dependency>
dependencies>
<modules>
modules>
project>
这里,我们定义了父项目,包括第三方组件的版本与公共依赖声明。
3. 创建 Spring Boot 模块
1.创建新模块
<parent>
<artifactId>my-samplesartifactId>
<groupId>com.me.testgroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<groupId>com.me.test.springbootgroupId>
<artifactId>springboot-testartifactId>
<version>1.0-SNAPSHOTversion>
2.导入 cxf 官方案例 spring_boot
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>${spring.boot.version}version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-spring-boot-starter-jaxrsartifactId>
<version>${cxf.version}version>
dependency>
<dependency>
<groupId>org.webjarsgroupId>
<artifactId>swagger-uiartifactId>
<version>2.2.6version>
dependency>
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-rt-rs-service-description-swaggerartifactId>
<version>${cxf.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-jdk14artifactId>
<scope>testscope>
dependency>
dependencies>
3.修改 java 文件
4.在 IDEA 直接运行 SampleRestApplication 类
在运行输出的 INFO 中仔细查看 服务器端口 和 服务绑定的根
...
...Tomcat initialized with port(s): 8080 (http)
...
...Mapping servlet: 'CXFServlet' to [/services/*]
...
然后,根据JAX-RS映射,在浏览器中分别输入以下 url:
http://localhost:8080/services/sayHello/cxf1
http://localhost:8080/services/sayHello2/cxf2
http://localhost:8080/services/swagger.json
http://localhost:8080/services/services
这个案例展示了服务api映射与实现的关系,以及服务可视化工具 swagger 的使用
The Java API for RESTful Web Services provides portable APIs for developing, exposing and accessing Web applications designed and implemented in compliance with principles of REST architectural style.
https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/index.html
https://jax-rs-spec.java.net/
它由一组软件包构成,最常用的就是高层包 javax.ws.rs ,它是 High-level interfaces and annotations used to create RESTful service resources
一个 Java POJO 类,使用 申明式 的javax.ws.rs 注释标记技术,成为能被暴露访问的 Web 资源。
主资源(Root Resource),它字少有 @Path 注释,且被注册发布。
例如:创建一个主资源对象的接口 CustomerService
@Path("/customer")
public interface CustomerService {
@GET
@Path("/id/{id}")
@Produces(MediaType.TEXT_PLAIN)
String GetCustomerName(@PathParam("id") String id);
}
添加它的实现类 CustomerServiceImpl
, 注意 @api(“\customer”)
就可以使用 swagger 调试服务了!!!
@Api("/customer")
public class CustomerServiceImpl implements CustomerService {
public String GetCustomerName(String id) {
return "hello" + id;
}
}
然后,修改发布代码:
endpoint.setServiceBeans(Arrays.
运行!
浏览 http://localhost:8080/services/customer/id/123
,或者
使用 swagger http://localhost:8080/services/services
@Path: 用于类型和方法的注释,用于识别资源的 URI
例如:调用 GetCustomerName 方法的 URI 是 \customer\id\{id}
@PathParam : 用于方法参数的注释,绑定 URI 路径的模板
例如:请求 /customer/id/123
对应的模板{id},则 123 作为参数输入。
@GET : 用于主资源方法的注释,用于指定该方法处理 HTTP 请求的方法
例如:调用 GetCustomerName 方法的请求是 GET 方法
注:
@Produces : 定义 HTTP 响应 消息体 类型。javax.ws.rs.core.MediaType 给出了常用的枚举
例如:MediaType.TEXT_PLAIN = “text/plain” 的结果:
$ curl -v http://localhost:8080/services/customer/id/123
...
< Content-Type: text/plain;charset=UTF-8
...
@Consumes : 定义请求消息体的类型。
参数注释就是将 HTTP 的请求行、header行、body体的内容映射到函数输入之中。
除了 @PathParam 外:
@QueryParam : 将 URL 中 QueryString 作为参数。
例如:我们希望修改客户信息,因此添加服务接口方法:
@PUT
@Path("/update")
public Response updateCustomer(@DefaultValue("123") @QueryParam("id") Long id, @QueryParam("name") String name);
@PUT :修改一个对象;
@DefaultValue :参数不存在时的默认值;
服务实现中代码:
public Response updateCustomer(Long id, String name){
System.out.println("----invoking updateCustomer, Customer name is: " + name);
Response r;
//if modify OK!
if (id == 123) {
r = Response.ok().build();
} else {
r = Response.notModified().build();
}
return r;
}
其中,Response 是 javax.ws.rs.core.Response
用 swagger 测试。
@FormParam : 从输入 body 中提取参数。
例如:我们希望添加客户信息,因此添加服务接口方法:
@POST
@Path("/add/")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.TEXT_PLAIN)
public Response addCustomer(@DefaultValue("123") @FormParam("id") Long id, @FormParam("name") String name);
@Consumes 必须是 MediaType.APPLICATION_FORM_URLENCODED
服务实现中代码:
public Response addCustomer(Long id, String name){
System.out.println("----invoking updateCustomer, Customer name is: " + name);
Response r;
r = Response.ok().build();
return r;
}
略
@BeanParam : 将一个对象与 HTTP 请求映射
@Context,@MatrixParam, @HeaderParam, @CookieParam 的使用,建议看文档:
https://jersey.java.net/documentation/latest/jaxrs-resources.html#d0e2225
添加 Customer 对象
samples/jax_rs/basic/src/main/java/demo/jaxrs/server/
中将 Customer 类拖入项目添加服务接口方法:
@POST
@Path("/addObj/")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.TEXT_PLAIN)
public Response addCustomer(Customer customer);
public Response addCustomer(Customer customer) {
System.out.println("----invoking updateCustomer, Customer name is: " + customer.getName());
Response r;
r = Response.ok().build();
return r;
}
用 swagger 测试 服务!
如果,返回的也是 Customer 对象,应该如何修改?
<dependency>
<groupId>org.codehaus.jacksongroupId>
<artifactId>jackson-jaxrsartifactId>
<version>1.9.13version>
dependency>
endpoint.setProviders(Arrays.
它为 endpoint 配置了两种读写 body 的方法处理
@POST
@Path("/addObj/")
@Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
@Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
public Customer addCustomer(Customer customer);
运行!
https://jersey.java.net/documentation/latest/user-guide.html#d0e2495
使用curl指令測試REST服務 http://ju.outofmemory.cn/entry/84875