首页 > 学院 > 开发设计 > 正文

REST方式的CXF WebService实现

2019-11-08 01:37:17
字体:
来源:转载
供稿:网友

1. REST方式的WebService概述

1.1 REST架构风格

REST是 Roy Fielding 博士在 2000 年提出的。 REST(RePResentational State Transfer-表现层状态转化)是一种新的软件架构风格,它以资源(resource)为核心,使用 HTTP、 URI、xml 以及 HTML 等流行协议和标准来完成对资源的操作及显示。 这些操作包括获取、创建、修改和删除资源(CRUD),分别对应于 HTTP 协议的 GET、POST、PUT 和 DELETE 方法。

RESTful架构可以总结为以下三个内容: (1)每一个URI代表一种资源; (2)客户端和服务器之间,传递这种资源的某种表现层; (3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现”表现层状态转化”。

GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。

1.2. REST风格服务

REST (风格的)服务(RESTful Service)是一种基于 HTTP 和 REST 准则的轻量级 Web 服务。

这类服务可以看作一系列资源(resource)的集合,服务的定义可以视为以下三个切面的组合 : - 访问 Web Service 的 URI,如:http://example.com/resources。 - Web Service 所支持的数据 MIME 类型,如:JSON, XML, YAML 等。 - Web Service 使用 HTTP 协议支持的操作,如 GET, POST, PUT, DELETE。

1.3.优点

REST风格的服务的性能,效率和易用性等方面均优于 SOAP 协议: - 相比SOAP 和 XML-RPC, REST 服务更加简洁, - 它可以完全通过 HTTP 协议实现, - 支持多种消息格式,比如XML 、JSON - 还可以利用缓存 Cache 来提高响应速度(第一次访问资源 缓存,第二次访问资源,返回304客户端调用本地)。

1.4.JAX-RS

JAX-RS (JSR 311)是java世界中的另一套Web Service规范,用于开发RESTful Web Service。它属于Java EE 6规范中的子规范,逐步取代了JAX-WS(大WebService的规范)的地位。 基于JAX-RS规范实现的RESTful API可达到:支持资源抽象、统一接口的 “CRUD式Web服务”。

2.CXF服务端开发

CXF框架支持JAX-WS,也支持JAX-RS规范,都是远程调用。

2.1 新建maven项目,引入依赖

pom.xml

<properties> <cxf.version>3.1.9</cxf.version> <slf4j.version>1.7.21</slf4j.version> </properties> <!-- 依赖管理 --> <dependencies> <!-- CXF RS --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxrs</artifactId> <version>${cxf.version}</version> </dependency> <!-- 内置jetty Web服务器 --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>${cxf.version}</version> </dependency> <!-- slf4j-log4j12 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency> <!-- CXF的rs客户端 --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-client</artifactId> <version>${cxf.version}</version> </dependency> <!-- CXF扩展提供者:提供了转换json的接口 --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-extension-providers</artifactId> <version>${cxf.version}</version> </dependency> <!-- CXF扩展提供者转换json需要默认的一个工具包 --> <dependency> <groupId>org.codehaus.jettison</groupId> <artifactId>jettison</artifactId> <version>1.3.8</version> </dependency> </dependencies> <!-- 构建 --> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <!-- 编译的jdk版本 --> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build>

2.2 资源-实体类编写

@XmlRootElement 指定序列化(转换XML、JSON) 对象名字。

//指定序列化(转换XML、JSON) 对象名字 //实体类:资源对应的类 //@XmlRootElement//默认情况下,该对象在传输表现的时候,表现方式xml,要转成xml,根元素:<user类名></user> name:默认类名小写 @XmlRootElement(name="users")//根元素:<users></users> //比如查询列表:<users><user><id>123</id>....</user></users> //如果是json:{users:[{"id":"2342",...},{...}} public class User { private Integer id; private String username; private String passWord; private Integer age;

2.3 SEI业务

第一种 @Path 服务访问资源路径 如果访问saveUser方法 /userService/user 第二种 @Produces 生成(方法返回值) @Consumes 消费 (方法参数) @Consumes 指定能够处理客户端传递过来数据格式 @Produces 指定能否生成哪种格式数据返回给客户端 第三种 @GET 查询 @PUT 修改 @POST 增加 @DELETE 删除 第四种: @PathParam来自于URL的路径,@QueryParam来自于URL的查询参数

//SEI的接口:对外暴露 //加上注解path,类似于具体的服务的名字"/mobile" @Path("/userService")//暴露出去访问资源的服务路径:http://127.0.0.1:8888//userService/users/ public interface UserService { //定义CRUD方法 /** * 说明:保存用户 * @param user */ @Path("/users")//访问的资源 @POST//新建资源动作 //配置表现:setContenttype(....) //消费:接收客户端传过来的消息的格式 @Consumes({MediaType.application_XML,MediaType.APPLICATION_JSON}) //没有产品 public void saveUser(User user); /** * * 说明:修改用户 * @param user */ @Path("/users") @PUT//更新操作 //可接收客户端传递过来的格式 @Consumes({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON}) public void updateUser(User user); /** * * 说明:直接根据id删除 * @param id */ @Path("/users/{id}") @DELETE//删除,uri:/users/1 @Consumes({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})//消费 public void deleteUser(@PathParam("id")Integer id); /** * * 说明:查询所有数据列表 * @return */ @Path("/users") @GET //产品(生产):返回给客户端的格式 @Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON}) public List<User> findUserList(); /** * * 说明:根据id来查询用户 * @param id * @return */ @Path("/users/{id}") @GET //消费者 @Consumes({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON}) //生产者: @Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON}) //127.0.0.1:8888/cxf_jaxrs/userService/users/1 //资源后面都是参数,参数,类似于命名占位符 public User findUserById(@PathParam("id")Integer id); /** * * 说明:使用参数传参:/users?id=1 * @param id * @return */ @Path("/usersparam") @GET //消费者 @Consumes({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON}) //生产者: @Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON}) public User findUserById2(@QueryParam("id")Integer id); } /** * SEI实现 */ public class UserServiceImpl implements UserService { @Override public void save(User user) { //调用dao System.out.println("----保存:"+user); } @Override public void update(User user) { //调用dao System.out.println("-----更新对象:"+user); } @Override public void delete(Integer id) { //调用dao System.out.println("-----删除的id:"+id); } @Override public List<User> findUserList() { List<User> userList = new ArrayList<>(); userList.add(new User(1,"jack","123",19)); userList.add(new User(2,"rose","1234",18)); return userList; } @Override public User findUserById(Integer id) { System.out.println("----根据id查询,id是:"+id); return new User(1,"jack","123",19); } @Override public User findUserById2(Integer id) { System.out.println("----根据id参数查询,id是:"+id); return new User(2,"rose","1234",18); } }

2.4 发布服务

public class CxfJaxrsserver { public static void main(String[] args) { // 发布rest服务 //1.构建服务工厂对象 JAXRSServerFactoryBean jaxrsServiceFactoryBean = new JAXRSServerFactoryBean(); //2.在工厂上设置几个属性 //2.1服务地址 jaxrsServiceFactoryBean.setAddress("http://localhost:8888/cxf_jaxrs"); //2.2资源的类型 jaxrsServiceFactoryBean.setResourceClasses(User.class); //2.3服务对象.自动反射接口 jaxrsServiceFactoryBean.setServiceBean(new UserServiceImpl()); //c创建并发布服务 jaxrsServiceFactoryBean.create(); System.out.println("rest服务发布了!"); //资源访问的方式:web地址+服务地址+资源名字 } }

2.5 测试

浏览器测试(只能是get方法测试) 查询所有:http://localhost:8888/cxf_jaxrs/userService/users 根据id查询(路径方式):http://localhost:8888/cxf_jaxrs/userService/users/1 根据id查询(参数方式):http://localhost:8888/cxf_jaxrs/userService/users?id=1

3. CXF客户端开发

客户端编程有两种做法: 1)HttpClient工具需要自己对HTTP协议内容进行定制和解析。 2)WebClient工具类(CXF自带)(使用)。

3.1 客户端调用类

主要的方法说明: - create:调用服务资源路径,并建立连接 - type:客户端发送给服务器的数据(资源)格式,对应服务端的@consumes的数据类型 - accept:客户端接收服务器的数据(资源)格式,对应服务端的@Produces的数据类型 - get,post,put,delete四个方法,分别是要采用HTTP协议的那种方式访问服务器。

public class CxfRsClient { public static void main(String[] args) { //----方法说明 //create:调用服务资源路径,并建立连接 //type:客户端发送给服务器的数据(资源)格式,对应服务端的@consumes的数据类型 //accept:客户端接收服务器的数据(资源)格式,对应服务端的@Produces的数据类型 //get,post,put,delete四个方法,分别是要采用HTTP协议的那种方式访问服务器。 // 目标:调用服务端:crud //WebClient:客户端工具类 //保存 //new对象 // User user = new User(); // user.setId(101); // user.setUsername("xiaohong"); // user.setPassword("666"); // user.setAge(28); // //访问的资源http://127.0.0.1:8888/cxf_jaxrs/userService/users // //参数:访问的服务器上的资源 // WebClient.create("http://127.0.0.1:8888/cxf_jaxrs/userService/users") // //消费者(对于服务端) // .type(MediaType.APPLICATION_JSON)//设置表现形式,内容类型,怎么传数据,服务器可接收什么 // .post(user)//自动将对象转换成xml或json // ; //更新 // User user2 = new User(); // user2.setId(102); // user2.setUsername("xiaohong2"); // user2.setPassword("6662"); // user2.setAge(28); //资源uri // WebClient.create("http://127.0.0.1:8888/cxf_jaxrs/userService/users") // .type(MediaType.APPLICATION_JSON) // .put(user2); //删除 //资源uri // WebClient.create("http://127.0.0.1:8888/cxf_jaxrs/userService/users/1") //// .path("/"+id);//类似于Stringbuffer的.append("xxxx") // .type(MediaType.APPLICATION_JSON) // .delete(); //查询所有列表 //资源uri // Collection<? extends User> userList = WebClient.create("http://127.0.0.1:8888/cxf_jaxrs/userService/users") // //生产者(针对服务器来说,客户端能接收) // .accept(MediaType.APPLICATION_JSON) //// .get().getEntity()//获取内容 // .getCollection(User.class);//列表对象 // System.out.println(userList); //根据id查询一个对象 //资源uri // User user = WebClient.create("http://127.0.0.1:8888/cxf_jaxrs/userService/users/1") // //消费者 // .type(MediaType.APPLICATION_JSON) // //生产者 // .accept(MediaType.APPLICATION_JSON) // .get(User.class);//获取一个对象 // System.out.println(user); //有时候查询先判断有没有查询成功,还不想要结果。 int status = WebClient.create("http://127.0.0.1:8888/cxf_jaxrs/userService/users") .accept(MediaType.APPLICATION_JSON) .get() .getStatus(); System.out.println(status); System.out.println("客户端操作完成!"); }

4. CRM系统的CXF服务端构建开发(与spring整合)

4.1. SSH基础环境搭建

技术架构: Spring + Hibernate(spring和hibernate直接整合)+CXF+Oracle

4.1.1 新建Maven项目

引入Maven坐标: Spring、Hibernate、数据库和连接池、日志、Servlet、jsp、junit、编译版本覆盖、tomcat端口覆盖8888:

<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.0</modelVersion> <groupId>cn.aric.project</groupId> <artifactId>crm</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>crm</name> <description>物流的客户子系统</description> <properties> <spring.version>3.2.12.RELEASE</spring.version> <hibernate.version>3.6.10.Final</hibernate.version> <slf4j.version>1.7.5</slf4j.version> <c3p0.version>0.9.1.2</c3p0.version> <oracle.version>10.2.0.4.0</oracle.version> <servlet.version>2.5</servlet.version> <jsp.version>2.0</jsp.version> <junit.version>4.11</junit.version> <cxf.version>3.1.9</cxf.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>${c3p0.version}</version> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc14</artifactId> <version>${oracle.version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>${servlet.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>${jsp.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> <version>3.12.0.GA</version> </dependency> <!-- CXF RS --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxrs</artifactId> <version>${cxf.version}</version> </dependency> <!-- CXF扩展提供者:提供了转换json的接口 --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-extension-providers</artifactId> <version>${cxf.version}</version> </dependency> <!-- CXF扩展提供者转换json需要默认的一个工具包 --> <dependency> <groupId>org.codehaus.jettison</groupId> <artifactId>jettison</artifactId> <version>1.3.8</version> </dependency> <!-- CXF的rs客户端 --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-client</artifactId> <version>${cxf.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>tomcat-maven-plugin</artifactId> <version>1.1</version> <configuration> <port>8888</port> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.6</version> <configuration> <encoding>UTF-8</encoding> </configuration> </plugin> <!-- 编译的jdk版本 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build> </project> </project>

4.1.2 整合spring

配置Spring整合Hibernate(几个配置文件:applicationContext.xml、db.properties,web.xml,log4j.properties等)

web.xml

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>crm</display-name> <!-- cxf的前端控制器 --> <servlet> <description>Apache CXF Endpoint</description> <display-name>cxf</display-name> <servlet-name>cxf</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>cxf</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> <!-- spring配置文件位置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!-- spring核心监听器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>

db.properties

jdbc.driver=oracle.jdbc.driver.OracleDriver jdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:xe jdbc.user=scott jdbc.password=tigger

log4j.properties

### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.err log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### direct messages to file mylog.log ### log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=d:/mylog.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### set log levels - for more verbose logging change 'info' to 'debug' ### log4j.rootLogger=info, stdout

applicationContext.xml

<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 引入外部的属性配置文件 --> <context:property-placeholder location="classpath:db.properties"/> <!-- 连接池 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driver}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.user}"/> <property name="password" value="${jdbc.password}"/> </bean> <!-- spring来整合hibernate AnnotationsessionFactoryBean:spring提供的专门来整合hibernate注解 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <!-- 注入数据源 --> <property name="dataSource" ref="dataSource"/> <!-- hibernate一般属性 --> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true </prop> </props> </property> <!-- 映射的类 packagesToScan:扫描哪个包,会将脑门上带@Entity的类,注册为实体类 --> <property name="packagesToScan"> <list> <value>cn.aric.crm.domain</value> </list> </property> </bean> <!-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- 注解驱动 --> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- 开启spring的bean组件扫描(默认也会开启注解功能) --> <context:component-scan base-package="cn.aric.crm.service,cn.aric.crm.dao"/> <!-- 引入cxf配置 --> <import resource="applicationContext-cxf.xml"/> </beans>

4.2 新建实体类

@Entity @Table(name="t_customer",schema="scott") public class Customer { @Id @GeneratedValue(strategy=GenerationType.AUTO)//auto代表自动 private Integer id;//OID属性 private String name;//客户名称 private String address;//住所 private String telephone;//联系电话 private String decidedZoneId;//定区编号(客户和定区关联的字段) public Integer getId() { return id; } public String getName() { return name; } public String getAddress() { return address; } public String getTelephone() { return telephone; } public String getDecidedZoneId() { return decidedZoneId; } public void setId(Integer id) { this.id = id; } public void setName(String name) { this.name = name; } public void setAddress(String address) { this.address = address; } public void setTelephone(String telephone) { this.telephone = telephone; } public void setDecidedZoneId(String decidedZoneId) { this.decidedZoneId = decidedZoneId; } }

测试上面的配置,启动服务,自动建表:tomcat:run

4.3 引入CXF环境 ###

<properties> <cxf.version>3.1.9</cxf.version> </properties> <dependencies> <!-- CXF RS --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxrs</artifactId> <version>${cxf.version}</version> </dependency> <!-- CXF扩展提供者:提供了转换json的接口 --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-extension-providers</artifactId> <version>${cxf.version}</version> </dependency> <!-- CXF扩展提供者转换json需要默认的一个工具包 --> <dependency> <groupId>org.codehaus.jettison</groupId> <artifactId>jettison</artifactId> <version>1.3.8</version> </dependency> <!-- CXF的rs客户端 --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-client</artifactId> <version>${cxf.version}</version> </dependency> </dependencies>

4.4 Spring整合CXF-RS的服务

@Entity @Table(name="t_customer",schema="SCOTT") @XmlRootElement(name="customer") public class Customer { @Id //如果没有给主键策略,不管oid什么类型,都需要手动主键值 //但如果有主键策略,根据主键策略来走。 @GeneratedValue(strategy=GenerationType.AUTO)//auto代表自动 //--自动:根据OID的属性的类型来自动选择 //如果String类型,主键数据库不会自动生成,要么手动赋值(对于数据库来说手动主键),要么让hibernate的uuid赋值 //如果是Integer,Long,值自增长的,会自动创建一个序列,使用序列的值作为主键值(数据库提供的序列值--hibernate调用)。 private Integer id;//OID属性 private String name;//客户名称 private String address;//住所 private String telephone;//联系电话 private String decidedZoneId;//定区编号(客户和定区关联的字段)

4.4.1 编写SEI

@Path("/customerService")//具体服务的名字路径 @Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON}) @Consumes({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON}) public interface CustomerService { //提供三个暴露的方法 /** * * 说明:查询没有关联定区的客户的列表 * @return */ @Path("/customers")//某个方法的操作的资源 @GET @Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON}) public List<Customer> findCustomerListNoDecidedZoneId(); /** * * 说明:查询关联某个定区的客户的列表 * @return */ @Path("/customers/{decidedZoneId}")//某个方法的操作的资源 @GET @Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON}) @Consumes({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON}) public List<Customer> findCustomerListByDecidedZoneId(@PathParam("decidedZoneId")String decidedZoneId); /** * * 说明:批量更新定区编号,通过客户编号 * @param decidedZoneId:DQ001 * @param customerIds:用逗号分割编号:2,3 */ @Path("/customers/{decidedZoneId}/{customerIds}")//某个方法的操作的资源 @PUT @Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON}) @Consumes({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON}) public void updateDecidedZoneIdByIds(@PathParam("decidedZoneId")String decidedZoneId,@PathParam("customerIds")String customerIds); } //SEI:客户的业务实现类 //客户操作的业务层实现 Service("customeService") @Transactional public class CustomerServiceImpl implements CustomerService{ //注入dao @Autowired private GenericDAO<Customer, Integer> customerDAO; @Override public List<Customer> findCustomerListNoDecidedZoneId() { //条件构建 DetachedCriteria criteria =DetachedCriteria.forClass(Customer.class) .add(Restrictions.isNull("decidedZoneId")); //查询 return customerDAO.findByCriteria(criteria); } @Override public List<Customer> findCustomerListByDecidedZoneId(String decidedZoneId) { //条件构建 DetachedCriteria criteria =DetachedCriteria.forClass(Customer.class) .add(Restrictions.eq("decidedZoneId", decidedZoneId)); //查询 return customerDAO.findByCriteria(criteria); } @Override public void updateDecidedZoneIdByIds(String decidedZoneId, String customerIds) { //快照更新 //====先去掉指定定区的所有的关联(update) //查询出所有原来已经关的客户列表 DetachedCriteria criteria =DetachedCriteria.forClass(Customer.class) .add(Restrictions.eq("decidedZoneId", decidedZoneId)); List<Customer> customerList = customerDAO.findByCriteria(criteria); //快照 for (Customer customer : customerList) { customer.setDecidedZoneId(null); } //====关联需要关联指定定区的客户(update) if(!StringUtils.isEmpty(customerIds)){ String[] customerArray = customerIds.split(","); for (String customerId : customerArray) { Customer customer = customerDAO.findById(Customer.class, Integer.parseInt(customerId)); customer.setDecidedZoneId(decidedZoneId); } } //等待flush } }

4.4.2 编写DAO

4.4.3 配置web.xml(CXF的核心控制器)

<!-- cxf的前端控制器 --> <servlet> <description>Apache CXF Endpoint</description> <display-name>cxf</display-name> <servlet-name>cxf</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>cxf</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping>cxf配置:applicationContext-cxf.xml <?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:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:jaxrsclient="http://cxf.apache.org/jaxrs-client" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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 http://cxf.apache.org/jaxrs-client http://cxf.apache.org/schemas/jaxrs-client.xsd"> <!-- cxf服务servlet的初始化 --> <import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <!-- 配置REST服务 --> <!-- jaxrs:server:JAXRSServerFactoryBean+bean address:请求分发的具体服务地址 serviceClass:sei接口 --> <jaxrs:server id="customerWebService" address="/CustomerWS" > <jaxrs:serviceBeans> <ref bean="customerService" /> </jaxrs:serviceBeans> <!-- 输入日志拦截器 --> <jaxrs:inInterceptors> <ref bean="loggingInInterceptor"/> </jaxrs:inInterceptors> <!-- 输出日志拦截器 --> <jaxrs:outInterceptors> <ref bean="loggingOutInterceptor" /> </jaxrs:outInterceptors> </jaxrs:server> <!-- 输入日志拦截器 --> <bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean> <!-- 输出日志拦截器 --> <bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean> </beans>

4.4.4 测试

测试的访问路径: web上下文+cxf前端控制器+配置的服务路径+类上的具体的服务路径 web上下文+cxf前端控制器+配置的服务路径+类上的具体的服务路径+资源路径(方法上)

使用SoapUI—webservice的调试工具,Encoding改UTF-8。

5. BOS系统的CXF客户端

5.1.项目中引入CXF开发环境

引入Maven坐标(Pom.xml):

<cxf.version>3.1.9</cxf.version> <!-- CXF扩展提供者:提供了转换json的接口 --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-extension-providers</artifactId> <version>${cxf.version}</version> </dependency> <!-- CXF扩展提供者转换json需要默认的一个工具包 --> <dependency> <groupId>org.codehaus.jettison</groupId> <artifactId>jettison</artifactId> <version>1.3.8</version> </dependency> <!-- CXF的rs客户端 --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-client</artifactId> <version>${cxf.version}</version> </dependency>

5.2 CXF-RS的客户端开发

5.2.1 编写Domain

//dto @XmlRootElement(name="customer") public class Customer { private Integer id;//OID属性 private String name;//客户名称 private String residence;//住所 private String telephone;//联系电话 private String decidedZoneId;//定区编号(客户和定区关联的字段)

5.2.2 编写Jsp

5.2.3 后台代码

//列出没有关联定区的客户 @Action("decidedZone_listCustomerListNoDecidedZoneId") public String listCustomerListNoDecidedZoneId(){ //直接调用webservice接口 //基本服务连接 WebClient webClient = WebClient.create("http://localhost:8888/crm/services"); Collection<? extends Customer> collection = webClient .path("/crmService/customerService")//具体服务 .path("/customers")//资源路径 .accept(MediaType.APPLICATION_JSON)//客户端要接收的类型 .type(MediaType.APPLICATION_JSON)//发出去的数据类型,java对象会转换为该类型 .getCollection(Customer.class); //压入栈顶 pushToValuestackRoot(collection); //json数组 return JSON; //JSON在父类中配置常量 } //列出已经关联定区的客户 @Action("decidedZone_listCustomerListHasDecidedZoneId") public String listCustomerListHasDecidedZoneId(){ //直接调用webservice接口 //基本服务连接 WebClient webClient = WebClient.create("http://localhost:8888/crm/services"); Collection<? extends Customer> collection = webClient .path("/crmService/customerService")//具体服务 .path("/customers")//资源路径 .path("/"+model.getId()) .accept(MediaType.APPLICATION_JSON)//客户端要接收的类型 .type(MediaType.APPLICATION_JSON)//发出去的数据类型,java对象会转换为该类型 .getCollection(Customer.class); //压入栈顶 pushToValuestackRoot(collection); //json数组 return JSON;
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表