axis2实践(二)Restful入门示例
1. 实例说明
本示例直接参照了RESTful Web Services with Apache Axis2,本示例基本就是沿用的原示例,就是一个对学生信息(包括姓名,年龄,课程)的管理的例子,提供如下Web服务:
1)获取所有学生信息
2)根据姓名获取单个学生信息
3)新增学生信息
4)修改学生信息
另外,本示例在原示例的基础上增加如下功能:
1)增加了与Web系统的集成
2)增加客户端调用代码
2. 创建WebService服务,
整个项目目录结构见下图
1)创建StudentService类,提供了查询,获取,新增,修改学生信息的功能,特别需要注意的是,getStudent()返回学生信息访问的URL.
1 import java.util.HashMap; 2 import java.util.Iterator; 3 import java.util.Map; 4 5 import org.apache.axis2.AxisFault; 6 import org.apache.axis2.addressing.EndpointReference; 7 import org.apache.axis2.context.MessageContext; 8 import org.apache.axis2.description.TransportInDescription; 9 import org.apache.axis2.engine.AxisConfiguration; 10 11 public class StudentService { 12 13 private Map<String, Student> map = new HashMap<String, Student>(); 14 private String baseURL = null; 15 16 public StudentService() { 17 map.put("jimmy", new Student("Jimmy", 20, new String[] { "English", "French", "Russian" })); 18 } 19 20 public String[] getStudents() { 21 int size = map.size(); 22 String[] students = new String[size]; 23 Iterator<String> iterator = map.keySet().iterator(); 24 int i = 0; 25 while (iterator.hasNext()) { 26 String studentName = iterator.next(); 27 students[i] = getBaseURL() + "student/" + studentName; 28 i++; 29 } 30 return students; 31 } 32 33 public Student getStudent(String name) throws StudentNotFoundException { 34 Student student = map.get(name); 35 if (student == null) { 36 throw new StudentNotFoundException("Details of student " + name + " cannot be found."); 37 } 38 return student; 39 } 40 41 public String addStudent(Student student) throws StudentAlreadyExistsException { 42 String name = student.getName(); 43 if (map.get(name) != null) { 44 throw new StudentAlreadyExistsException("Cannot add details of student " + name 45 + ". Details of student " + name + " already exists."); 46 } 47 map.put(name, student); 48 return getBaseURL() + "student/" + name; 49 } 50 51 public String updateStudent(Student student) throws StudentNotFoundException { 52 String name = student.getName(); 53 if (map.get(name) == null) { 54 throw new StudentNotFoundException("Details of student " + name + " cannot be found."); 55 } 56 map.put(name, student); 57 return getBaseURL() + "student/" + name; 58 } 59 60 public void deleteStudent(String name) throws StudentNotFoundException { 61 if (map.get(name) == null) { 62 throw new StudentNotFoundException("Details of student " + name + " cannot be found."); 63 } 64 map.remove(name); 65 } 66 67 // This method attempts to get the Base URI for this service. This will be 68 // used to construct 69 // the URIs for the various detsila returned. 70 private String getBaseURL() { 71 if (baseURL == null) { 72 MessageContext messageContext = MessageContext.getCurrentMessageContext(); 73 AxisConfiguration configuration = messageContext.getConfigurationContext() 74 .getAxisConfiguration(); 75 TransportInDescription inDescription = configuration.getTransportIn("http"); 76 try { 77 EndpointReference[] eprs = inDescription.getReceiver().getEPRsForService( 78 messageContext.getAxisService().getName(), null); 79 baseURL = eprs[0].getAddress(); 80 } catch (AxisFault axisFault) { 81 } 82 } 83 return baseURL; 84 } 85 }
2)实体类:Student类
1 public class Student { 2 3 private String name; 4 private int age; 5 private String[] subjects; 6 7 public Student() { 8 super(); 9 } 10 11 public Student(String name, int age, String[] subjects) { 12 super(); 13 this.name = name; 14 this.age = age; 15 this.subjects = subjects; 16 } 17 18 public String getName() { 19 return name; 20 } 21 22 public void setName(String name) { 23 this.name = name; 24 } 25 26 public int getAge() { 27 return age; 28 } 29 30 public void setAge(int age) { 31 this.age = age; 32 } 33 34 public String[] getSubjects() { 35 return subjects; 36 } 37 38 public void setSubjects(String[] subjects) { 39 this.subjects = subjects; 40 } 41 }
3)异常类
StudentAlreadyExistsException类:
1 public class StudentAlreadyExistsException extends Exception { 2 private static final long serialVersionUID = 1L; 3 4 public StudentAlreadyExistsException(String message) { 5 super(message); 6 } 7 }
StudentNotFoundException类:
public class StudentNotFoundException extends Exception { private static final long serialVersionUID = 1L; public StudentNotFoundException(String message) { super(message); } }
4)服务描述文件,创建此文件,并将此文件置于\WEB-INF\services\StudentService\META-INF目录下,如果不存在此目录,则创建
service.xml文件:
1 <serviceGroup> 2 <service name="StudentService" scope="application"> 3 <parameter name="ServiceClass">demo.axis2.restful.student.StudentService 4 </parameter> 5 <messageReceivers> 6 <messageReceiver mep="http://www.w3.org/ns/wsdl/in-only" 7 class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" /> 8 <messageReceiver mep="http://www.w3.org/ns/wsdl/in-out" 9 class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" /> 10 </messageReceivers> 11 </service> 12 </serviceGroup>
3. 利用java2wsdl工具生成WSDL2.0文档
生成命令如下:
java2wsdl -wv 2.0 -o <output directory> -of <output file name> -sn <Name of the service> -cp <classpath uri> -cn <fully qualified name of the service class>
本示例执行的命令如下:
java2wsdl -wv 2.0 -o D:\example\demo.axis2.restful\src\main\webapp\WEB-INF\services\StudentService\META-INF -of StudentService.wsdl -sn StudentService -cp D:\example\demo.axis2.restful\target\classes\ -cn demo.axis2.restful.student.StudentService
命令成功执行完之后,将在指定目录下生成StudentService.wsdl,本示例将StudentService.wsdl文件放在 D:\example\demo.axis2.restful\src\main\webapp\WEB-INF\services \StudentService\META-INF下,也是在maven打包整个项目时,便于将相应的文件构建到指定目录中。
4. 构建Restful服务
1)修改StudentService.wsdl文件如下部分
1 <wsdl2:binding name="StudentServiceHttpBinding" 2 interface="tns:ServiceInterface" whttp:methodDefault="POST" 3 type="http://www.w3.org/ns/wsdl/http"> 4 <wsdl2:fault ref="tns:StudentServiceStudentNotFoundException" /> 5 <wsdl2:fault ref="tns:StudentServiceStudentAlreadyExistsException" /> 6 <wsdl2:operation ref="tns:deleteStudent" 7 whttp:location="student/{name}" whttp:method="DELETE"> 8 <wsdl2:input /> 9 <wsdl2:output /> 10 <wsdl2:outfault ref="tns:StudentServiceStudentNotFoundException" /> 11 </wsdl2:operation> 12 <wsdl2:operation ref="tns:updateStudent" 13 whttp:location="student/{name}" whttp:method="PUT"> 14 <wsdl2:input /> 15 <wsdl2:output /> 16 <wsdl2:outfault ref="tns:StudentServiceStudentNotFoundException" /> 17 </wsdl2:operation> 18 <wsdl2:operation ref="tns:getStudent" whttp:location="student/{name}" 19 whttp:method="GET"> 20 <wsdl2:input /> 21 <wsdl2:output /> 22 <wsdl2:outfault ref="tns:StudentServiceStudentNotFoundException" /> 23 </wsdl2:operation> 24 <wsdl2:operation ref="tns:addStudent" whttp:location="students" 25 whttp:method="POST"> 26 <wsdl2:input /> 27 <wsdl2:output /> 28 <wsdl2:outfault ref="tns:StudentServiceStudentAlreadyExistsException" /> 29 </wsdl2:operation> 30 <wsdl2:operation ref="tns:getStudents" whttp:location="students" 31 whttp:method="GET"> 32 <wsdl2:input /> 33 <wsdl2:output /> 34 </wsdl2:operation> 35 </wsdl2:binding>
2)修改web.xml,增加如下内容
<servlet> <servlet-name>AxisServlet</servlet-name> <display-name>Apache-Axis Servlet</display-name> <servlet-class> org.apache.axis2.transport.http.AxisServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping>
5. maven的项目管理文件pom.xml
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 <groupId>demo.axis2.restful</groupId> 5 <artifactId>demo.axis2.restful</artifactId> 6 <packaging>war</packaging> 7 <version>1.0</version> 8 <name>demo.axis2.restful Maven Webapp</name> 9 <url>http://maven.apache.org</url> 10 <dependencies> 11 <dependency> 12 <groupId>javax.servlet</groupId> 13 <artifactId>servlet-api</artifactId> 14 <version>2.4</version> 15 </dependency> 16 <dependency> 17 <groupId>org.apache.axis2</groupId> 18 <artifactId>axis2-kernel</artifactId> 19 <version>1.6.2</version> 20 </dependency> 21 <dependency> 22 <groupId>org.apache.axis2</groupId> 23 <artifactId>axis2-jaxws</artifactId> 24 <version>1.6.2</version> 25 </dependency> 26 <dependency> 27 <groupId>org.apache.axis2</groupId> 28 <artifactId>axis2-codegen</artifactId> 29 <version>1.6.2</version> 30 </dependency> 31 <dependency> 32 <groupId>org.apache.axis2</groupId> 33 <artifactId>axis2-adb</artifactId> 34 <version>1.6.2</version> 35 </dependency> 36 <dependency> 37 <groupId>org.apache.axis2</groupId> 38 <artifactId>axis2-transport-local</artifactId> 39 <version>1.6.2</version> 40 </dependency> 41 <dependency> 42 <groupId>org.apache.axis2</groupId> 43 <artifactId>addressing</artifactId> 44 <version>1.6.2</version> 45 <type>mar</type> 46 </dependency> 47 <dependency> 48 <groupId>com.sun.xml.ws</groupId> 49 <artifactId>jaxws-rt</artifactId> 50 <version>2.1.3</version> 51 <exclusions> 52 <exclusion> 53 <groupId>javax.xml.ws</groupId> 54 <artifactId>jaxws-api</artifactId> 55 </exclusion> 56 <exclusion> 57 <groupId>com.sun.xml.bind</groupId> 58 <artifactId>jaxb-impl</artifactId> 59 </exclusion> 60 <exclusion> 61 <groupId>com.sun.xml.messaging.saaj</groupId> 62 <artifactId>saaj-impl</artifactId> 63 </exclusion> 64 <exclusion> 65 <groupId>com.sun.xml.stream.buffer</groupId> 66 <artifactId>streambuffer</artifactId> 67 </exclusion> 68 <exclusion> 69 <groupId>com.sun.xml.stream</groupId> 70 <artifactId>sjsxp</artifactId> 71 </exclusion> 72 <exclusion> 73 <groupId>org.jvnet.staxex</groupId> 74 <artifactId>stax-ex</artifactId> 75 </exclusion> 76 <exclusion> 77 <groupId>com.sun.org.apache.xml.internal</groupId> 78 <artifactId>resolver</artifactId> 79 </exclusion> 80 <exclusion> 81 <groupId>org.jvnet</groupId> 82 <artifactId>mimepull</artifactId> 83 </exclusion> 84 </exclusions> 85 </dependency> 86 <dependency> 87 <groupId>commons-logging</groupId> 88 <artifactId>commons-logging</artifactId> 89 <version>1.1.2</version> 90 </dependency> 91 <dependency> 92 <groupId>log4j</groupId> 93 <artifactId>log4j</artifactId> 94 <version>1.2.17</version> 95 </dependency> 96 <dependency> 97 <groupId>commons-logging</groupId> 98 <artifactId>commons-logging</artifactId> 99 <version>1.1.2</version> 100 </dependency> 101 <dependency> 102 <groupId>commons-lang</groupId> 103 <artifactId>commons-lang</artifactId> 104 <version>2.6</version> 105 </dependency> 106 <dependency> 107 <groupId>junit</groupId> 108 <artifactId>junit</artifactId> 109 <version>3.8.1</version> 110 <scope>test</scope> 111 </dependency> 112 </dependencies> 113 <build> 114 <finalName>demo.axis2.restful</finalName> 115 <plugins> 116 <plugin> 117 <groupId>org.apache.maven.plugins</groupId> 118 <artifactId>maven-compiler-plugin</artifactId> 119 <configuration> 120 <source>1.6</source> 121 <target>1.6</target> 122 </configuration> 123 </plugin> 124 </plugins> 125 <resources> 126 <resource> 127 <directory>src/main/resources</directory> 128 <includes> 129 <include>**/*</include> 130 </includes> 131 </resource> 132 <resource> 133 <directory>src/main/java</directory> 134 <includes> 135 <include>**/*.xml</include> 136 </includes> 137 </resource> 138 </resources> 139 </build> 140 </project>
6. 发布程序到tomcat或其他J2EE服务器,
启动服务器,就可在浏览器中通过如下URL http://localhost/demo.axis2.restful/services/StudentService?wsdl ,看到services定义了,说明服务发布成功
7. 客户端访问服务代码,
1 import org.apache.axiom.om.OMAbstractFactory; 2 import org.apache.axiom.om.OMElement; 3 import org.apache.axiom.om.OMFactory; 4 import org.apache.axiom.om.OMNamespace; 5 import org.apache.axis2.AxisFault; 6 import org.apache.axis2.Constants; 7 import org.apache.axis2.addressing.EndpointReference; 8 import org.apache.axis2.client.Options; 9 import org.apache.axis2.client.ServiceClient; 10 11 public class StudentClient { 12 private static String toEpr = "http://localhost/demo.axis2.restful/services/StudentService"; 13 14 public static void main(String[] args) throws AxisFault { 15 16 Options options = new Options(); 17 options.setTo(new EndpointReference(toEpr)); 18 19 options.setProperty(Constants.Configuration.ENABLE_REST, Constants.VALUE_TRUE); 20 21 ServiceClient sender = new ServiceClient(); 22 //sender.engageModule(new QName(Constants.MODULE_ADDRESSING)); 23 sender.setOptions(options); 24 OMElement result = sender.sendReceive(getPayload()); 25 System.out.println(result); 26 27 } 28 29 private static OMElement getPayload() { 30 OMFactory fac = OMAbstractFactory.getOMFactory(); 31 OMNamespace omNs = fac.createOMNamespace("http://student.restful.axis2.demo", "tns"); 32 OMElement method = fac.createOMElement("addStudent", omNs); 33 34 OMElement student = fac.createOMElement("addStudent", omNs); 35 36 OMElement value = fac.createOMElement("name", omNs); 37 value.addChild(fac.createOMText(value, "eric")); 38 student.addChild(value); 39 40 value = fac.createOMElement("age", omNs); 41 value.addChild(fac.createOMText(value, "30")); 42 student.addChild(value); 43 44 value = fac.createOMElement("subjects", omNs); 45 value.addChild(fac.createOMText(value, "English")); 46 student.addChild(value); 47 48 value = fac.createOMElement("subjects", omNs); 49 value.addChild(fac.createOMText(value, "Russian")); 50 student.addChild(value); 51 52 method.addChild(student); 53 return method; 54 } 55 }
另外还可以通过浏览直接访问,例如:http://localhost/demo.axis2.restful/services/StudentService/students 可以查询所有的学生信息,返回的信息如下:
1 <ns:getStudentsResponse xmlns:ns="http://student.restful.axis2.demo"> 2 <ns:return> 3 http://Localhost/demo.axis2.restful/services/StudentService/student/jimmy 4 </ns:return> 5 </ns:getStudentsResponse>
以上信息是在存在一个姓名为jimmy学生信息的情况下返回的。把 http://Localhost/demo.axis2.restful/services/StudentService/student /jimmy 复制到浏览器的地址栏,就可以查看学生的详细信息了。