前面文章記錄了在spring中如何整合cxf開發webservice客戶端和服務端,其實,相較於原生開發方式,已經有了不少優化。rest風格的開發,作爲一種極爲流行的開發規範,可以幫助我們更加簡潔高效的發佈服務,接收服務。
客戶端
- 添加依賴
之前的都是jaxws,現在都將w編程了r,也就是rest的意思。
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.3.5</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.3.5</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-rs-client -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-client</artifactId>
<version>3.3.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-rs-extension-providers -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-extension-providers</artifactId>
<version>3.3.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.codehaus.jettison/jettison -->
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<version>1.4.0</version>
</dependency>
- 配置web.xml
和之前的沒有更多的變動
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>cXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cXFServlet</servlet-name>
<url-pattern>/webService/*</url-pattern>
</servlet-mapping>
<!-- 2.配置spring容器-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
<!-- 3.監聽器-->
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
- 編寫實體類
@XmlRootElement註解指定了對象序列化爲json/xml過後的根節點。
@XmlRootElement(name="student")
public class Student {
private Integer id;
private String name;
private String gender;
private Integer age;
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;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
'}';
}
}
- service接口和實現類
IStudnetService 接口,其中: @Path表示訪問當前服務接口對應的路徑; @Consumes指定服務器支持的接收的數據類型; @Produces指定服務器支持的返回的數據類型
public interface IStudnetService {
/**
* post對應的是insert操作
* get對應的是select操作
* put對應的是update操作
* delete對應的是delete操作
*
* @param student
*/
@POST
@Path("/student")
@Consumes({"application/xml","application/json"})
public void addStudent(Student student);
@PUT
@Path("/student")
@Consumes({"application/xml","application/json"})
public void saveStudent(Student student);
@GET
@Path("/student/{id}")
@Consumes({"application/xml","application/json"})
@Produces({"application/xml","application/json"})
public Student getStudentById(@PathParam("id") Integer id);
@GET
@Path("/student")
@Produces({"application/xml","application/json"})
public List<Student> getStudent();
@DELETE
@Path("/student/{id}")
@Consumes({"application/xml","application/json"})
public void deleteStudent(@PathParam("id") Integer id);
}
StudentService 實現類
這裏模擬rest風格的增刪改查,當客戶端調用服務時,服務端打印日誌記錄。
public class StudentService implements IStudnetService {
@Override
public void addStudent(Student student) {
System.out.println(student.getName()+"學生信息添加成功!");
}
@Override
public void saveStudent(Student student) {
System.out.println(student.getName()+"學生信息修改成功!");
}
@Override
public Student getStudentById(Integer id) {
Student student = new Student();
student.setId(id);
student.setAge(13);
student.setGender("男");
student.setName("william");
System.out.println("id爲"+id+"學生信息查詢成功!");
return student;
}
@Override
public List<Student> getStudent() {
Student student1 = new Student();
student1.setId(1);
student1.setAge(13);
student1.setGender("男");
student1.setName("william");
Student student2 = new Student();
student2.setId(2);
student2.setAge(12);
student2.setGender("女");
student2.setName("elaine");
List<Student> studentList = new ArrayList<Student>();
studentList.add(student1);
studentList.add(student2);
System.out.println("成功查詢所有學生信息成功!");
return studentList;
}
@Override
public void deleteStudent(Integer id) {
System.out.println("id爲"+id+"的學生信息刪除成功!");
}
}
- 配置applicationContext.xml
配置服務的方式基本沒有什麼變化,需要注意一下jaxrs標籤以及對應的命名空間。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:cxf="http://cxf.apache.org/jaxws"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd ">
<jaxrs:server address="/studentService">
<jaxrs:serviceBeans>
<bean class="com.wuwl.service.impl.StudentService"></bean>
</jaxrs:serviceBeans>
</jaxrs:server>
</beans>
- 啓動tomcat服務
啓動成功後,我們通過瀏覽器訪問:http://localhost:8081/webService/studentService/student/123
,會在頁面上顯示:
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<student>
<age>13</age>
<gender>男</gender>
<id>123</id>
<name>william</name>
</student>
客戶端
客戶端的編寫則更加簡潔明瞭了。
7. 引入相關的依賴
8. 導入實體類
這裏需要導入Student
這個實體類。
9. 編寫測試代碼Client
通過webClient對象調用服務,發送不同的請求類型,自動匹配對應的服務方法
public class Client {
@Test
public void testPost(){
Student st1 = new Student();
st1.setId(10);
st1.setName("jack");
st1.setGender("男");
st1.setAge(15);
//通過webClient對象遠程調用服務
WebClient.create("http://localhost:8081/webService/studentService/student").type(MediaType.APPLICATION_JSON).post(st1);
}
@Test
public void testDelete(){
WebClient.create("http://localhost:8081/webService/studentService/student/12").type(MediaType.APPLICATION_JSON).delete();
}
@Test
public void testPut(){
Student st1 = new Student();
st1.setId(10);
st1.setName("marry");
st1.setGender("/女");
st1.setAge(15);
//通過webClient對象遠程調用服務
WebClient.create("http://localhost:8081/webService/studentService/student").type(MediaType.APPLICATION_JSON).put(st1);
}
@Test
public void testGetById(){
Student student = WebClient.create("http://localhost:8081/webService/studentService/student/12").accept(MediaType.APPLICATION_JSON).get(Student.class);
System.out.println(student);
}
@Test
public void testGet(){
List<Student> studentList = (List<Student>) WebClient.create("http://localhost:8081/webService/studentService/student")
.accept(MediaType.APPLICATION_JSON).getCollection(Student.class);
System.out.println(studentList);
}
}
我們自上而下依次執行單元測試方法,由於除了GET請求以外,都沒有返回值,客戶端看不到任何輸出,而服務端可以查看對應請求記錄。
jack學生信息添加成功!
id爲12的學生信息刪除成功!
marry學生信息修改成功!
接着,我們測試testGetById方法。
客戶端輸出:
Student{id=12, name='william', gender='男', age=13}
服務端輸出:
id爲12學生信息查詢成功!
最後,測試testGet方法。
客戶端輸出:
[Student{id=1, name='william', gender='男', age=13}, Student{id=2, name='elaine', gender='女', age=12}]
服務端輸出:
成功查詢所有學生信息成功!