WebService
是用于多个独立项目之间的资源的传递
我们现在主要使用CXF这个WebService
CXF WebService开发主要分为二种
1.JAX-WS
2.JAX-RS
这里主要推荐JAX-RS,因为ws只支持xml是基于方法的
但是Rs不仅支持XML也支持Json 是基于资源的(就是通过路径直接访问)
(ws没怎么用过主要还是用了Rs
ws的运行流程是 创建好客户端工厂后调用服务端的方法进行运算的)
Rs用的时候先与spring整合
先导入依赖,
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.0.1</version>
</dependency>
dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-client</artifactId>
<version>3.0.1</version>
</dependency>
<!-- CXF的json转换器,拓展json -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-extension-providers</artifactId>
<version>3.0.1</version>
</dependency>
<!-- 转换json的工具包,被cxf-rt-rs-extension-providers包依赖 -->
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<version>1.3.7</version>
</dependency>
CXF需要在web.xml中配置过滤器 因为要先指向CXFServlet里面可能有一些增强,但是最终都会指向ApplicationContext-cxf.xml中(Struts2也是一样,里面有调度器,但是终会执行到action中,底层代码,有空研究)
<servlet>
<servlet-name>CXFService</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFService</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
3.在applicationContext-cxf.xml中配置
主要配置的是serviceBeans执行的位置指向userServiceImpl,
另外二个只是打印过程的配置不写也可以 ,要指向几个实现类就配置几个(配置多个是配置多个jaxrs:server)
<jaxrs:server id="userService" address="/userService">
<jaxrs:serviceBeans>
<bean class="cn.itcast.cxf.service.UserServiceImpl" />
</jaxrs:serviceBeans>
<jaxrs:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
</jaxrs:inInterceptors>
<jaxrs:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
</jaxrs:outInterceptors>
</jaxrs:server>
4.上面的配置文件执行的是UserServiceImpl,但是我们的方法是写在这个实现类的接口上(因为继承的原因,所以注解也会被继承)
userService接口中方法的配置
@Path("/promotion/{id}") //这个是地址的配置访问这个方法的时候只要访问这个路径就可以了,因为RS是基于资源的获取
//注意因为这里是@pathParam来获取传递的资源 所以我们调用这个方法的时候使用/Promotion/1 来传递1的id
@GET //因为这个是查询的方法所以是get POST增 PUT改 DELETE删
@Consumes({ "application/xml", "application/json" }) //这个是参数的类型
@Produces({ "application/xml", "application/json" }) //这个是返回值的类型
Promotion findByid(@PathParam("id")Integer id); //因为上面定义的是{id} 所以这里是PathParam("id")
//如果我们使用的是@QueryParam("id") 上面path就直接写成("/Promotion") 但是页面访问的时候写成为(/Promotion?id=1)
userService中直接继承重写方法,调用Spring data Jpa 进行查询
@Override
public Promotion findByid(Integer id) {
return promotionRepository.findOne(id);
}
创建客户端
客户端要获取我们在服务端查出来的数据只需要使用WebClient
1.新增
Response responsePost = WebClient.create("http://localhost:9800/cxf_rs_spring/services/userService")
.path("/user")// path可以省略,因为可以将uri的路径写到create下
.type(MediaType.APPLICATION_XML)// type表示参数(传递xml格式的参数)
.post(user); //user是要新增的值记得传过去
System.out.println("新增:" + responsePost.getStatus());
System.out.println("************************************************");
2.修改
Response responsePut = WebClient.create("http://localhost:9800/cxf_rs_spring/services/userService")
.path("/user")// path可以省略,因为可以将uri的路径写到create下
.type(MediaType.APPLICATION_XML)// type表示参数(传递xml格式的参数)
.put(user); //user是要修改的值记得传过去
System.out.println("修改:" + responsePut.getStatus());
System.out.println("************************************************");
3删除
Response responseDelete = WebClient.create("http://localhost:9800/cxf_rs_spring/services/userService")
.path("/user/2")// path可以省略,因为可以将uri的路径写到create下
.type(MediaType.APPLICATION_XML)// type表示参数(传递xml格式的参数)
.delete();
System.out.println("删除:" + responseDelete.getStatus());
System.out.println("************************************************");
4.查询所有 返回的是集合get的方法也需要修改
Collection<? extends User> collection = WebClient
.create("http://localhost:9800/cxf_rs_spring/services/userService").path("/user")// path可以省略,因为可以将uri的路径写到create下
.accept(MediaType.APPLICATION_XML)// 对应方法的返回值(传递XML数据格式,传递JSON的数据格式)
.getCollection(User.class);
System.out.println(collection);
5.使用id查询 path方法查询 get里面放的是要返回的类型
User userValue = WebClient.create("http://localhost:9800/cxf_rs_spring/services/userService").path("/user/1/张三")// path可以省略,因为可以将uri的路径写到create下
.type(MediaType.APPLICATION_XML)// type表示参数(传递xml格式的参数)
.accept(MediaType.APPLICATION_XML) // accept表示方法的返回值(传递xml格式的参数)
.get(User.class); //这里表示要返回的值如果是String就是 String.class
System.out.println(userValue);
System.out.println("************************************************");
6.使用id查询 query方法查询 get里面放的是要返回的类型
User userValue2 = WebClient
.create("http://localhost:9800/cxf_rs_spring/services/userService/user/query?id=2&name=李四")
// .path("/user/2/李四")// 因为是@QueryParam传递参数,不能是使用path
.type(MediaType.APPLICATION_XML)// type表示参数(传递xml格式的参数)
.accept(MediaType.APPLICATION_XML) // accept表示方法的返回值(传递xml格式的参数)
.get(User.class);
System.out.println(userValue2);
System.out.println("************************************************");
注意!!!!:像我们的PUT和POST请求都是传递过去的是一个Bean类,但是Bean类无法转换为XML格式去传递,所以我们要在这些类上加上注解
@XmlRootElement(name="promotion")
(注意如果这个bean类有属性是其他bean类,那其他bean类也要加上注解)
注意上面都是xml传递的,我们一般使用json传递数据 ,使用json只需要将xml的后缀改成json
query方法查询时候,在客户端这个调用这个方法的时候不允许在path里面拼参数,只可以在create里面写完