JAX-WS JAX-RS JAXM&SAAJ(废弃)
JAX-WS 规范
java api xml-based webservices 早期基于soap的jiava的web服务JAX-RPC (已经被取代),
采用标准得SOAP协议传输 属于w3c标准 SOAP协议基于http的应用层协议 soap协议传输时xml数据
xml是webservice的跨平台的基础,可扩展标记语言,描述数据
*** 服务端入门演示 : ***
服务端依赖
<dependencies> <!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-frontend-jaxws -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-features-logging</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
创建服务端 接口
import javax.jws.WebService;
/**
* 提供天气的服务
*/
@WebService //表明当前是一个webservice 的服务
public interface Weatherservice {
//根据城市获取天气信息
String getWeatherByCityName(String name);
}
实现服务端服务
public class WeatherserviceImpl implements Weatherservice {
@Override
public String getWeatherByCityName(String name) {
//模拟服务 我们这里就写死了
if("北京".equals(name)){
return "北京多云" ;
}else if("上海".equals(name)){
return "上海晴天" ;
}else if("深圳".equals(name)){
return "深圳暴雨" ;
}else{
return "未知";
}
}
}
对服务端启动 (这里发动) 服务开启后不能停
package com.itheima.test;
import com.itheima.service.WeatherserviceImpl;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
/*
开启服务不能使用单元测试
服务是需要一直开启的
*/
public class WebserviceServerTest {
public static void main(String[] args) {
//1.创建发布的服务的对象
JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean();
//2设置服务地址
factoryBean.setAddress("http://localhost:12345/weahter");
//3 设置服务的对象
factoryBean.setServiceBean(new WeatherserviceImpl());
//the last 发布服务
factoryBean.create();
//进行使用 在浏览器中输入 http://localhost:12345/weahter?wsdl + 说明信息 说明书是给虚拟机看的
//不加说明信息会出现错误
}
}
*** 客户端入门演示 : ***
引入客户端依赖
<dependencies> <!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-frontend-jaxws -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-features-logging</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
//1. 我们靠说明书 创建代码
//我们要测试 谁 测试代码是什么
/*那我们如何创建 代码呢 我们使用jdk 找到我们的jdk的安装目录
在jdk bin目录下找到 wsimport.exe
通过cmd 输入 wsimport 命令
wsimport [options] <WSDL_URI>
-s 指定放置生成的源文件的位置
进入我们的main java 目录下 进行当前cmd
wsimport -s . http://localhost:12345/weahter?wsdl 回车//生成到当前目录 .
*/
生成代码后 测试客户端和服务端连接
package com.itheima.client.test;
import com.itheima.service.Weatherservice;
import org.apache.cxf.jaxws.JaxWsClientFactoryBean;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.junit.Test;
public class jaxms_client01Test {
@Test //服务器端可以使用测试
public void test(){
//1. 我们靠说明书 创建代码
//我们要测试 谁 测试代码是什么
/*那我们如何创建 代码呢 我们使用jdk 找到我们的jdk的安装目录
在jdk bin目录下找到 wsimport.exe
通过cmd 输入 wsimport 命令
wsimport [options] <WSDL_URI>
-s <directory> 指定放置生成的源文件的位置
进入我们的main java 目录下 进行当前cmd
wsimport -s . http://localhost:12345/weahter?wsdl 回车//生成到当前目录 .
*/
//1 创建客户端的代理工厂Bean
JaxWsProxyFactoryBean proxy = new JaxWsProxyFactoryBean();
//2.设置说明书的地址
proxy.setAddress("http://localhost:12345/weahter?wsdl");
//3.设置客户端需要使用的服务端口类字节码
proxy.setServiceClass(Weatherservice.class);
//4.使用proxy创建服务接口的代理对象 使用Object接收
Object object = proxy.create();
//5.如果object是service接口的代理实现类我们就可以强转成service接口
Weatherservice weatherservice = null ;
if(object instanceof Weatherservice){
weatherservice = (Weatherservice)object;
}
//6.执行service中的方法
String str = weatherservice.getWeatherByCityName("北京");
System.out.println(str);
}
}
mevan web工程中spring和JAX-WS整合使用 (使用tomcat接口)
首先导入服务端依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.4.RELEASE</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-frontend-jaxws -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-features-logging</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.4.RELEASE</version>
</dependency>
</dependencies>
服务端接口 实现类 使用前面的天气
因为是web工程 所有我们需要在web.xml中配置 jaxws的核心控制器
<?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">
<!-- 利用监听器 配合配置文件 创建ioc容器 控制反转 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-cxf-server.xml</param-value>
</context-param>
<!-- CXF框架的核心控制器:CXFServlet -->
<servlet>
<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>/ws/*</url-pattern> <!-- 这里不能使用/* 不是所有地址都需要启动服务 -->
</servlet-mapping>
</web-app>
配置xml 文件 applicationContext-cxf-server.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:cxf="http://cxf.apache.org/core"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
">
<jaxws:server address="/weather"> <!-- 使用域名 http://localhost:12345/weahter -->
<jaxws:serviceBean>
<bean class="com.itheima.service.WeatherServiceImpl" /> <!-- 设置此处提供服务 -->
</jaxws:serviceBean>
</jaxws:server>
</beans>
<!-- 此处已经创建了 对象 JaxWsServerFactoryBean jaxWsServerFactoryBean = new JaxWsServerFactoryBean()
地址使用tomcat的
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
-->
http://localhost:8080/ws/weather 启动就好
客户端
导入坐标依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.4.RELEASE</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-frontend-jaxws -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-features-logging</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
applicationContext-cxf-client.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:cxf="http://cxf.apache.org/core"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<jaxws:client id="client"
address="http://localhost:8080/ws/weather?wsdl"
serviceClass="com.itheima.service.Weatherservice"></jaxws:client>
</beans>
test 测试
package com.itheima.test;
import com.itheima.service.Weatherservice;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class JaxwsClientTest {
@Test
public void test() { //创建代码
//读取配置文件创建容器 classpath:applicationContext-cxf-client.xml
ApplicationContext context =
new ClassPathXmlApplicationContext("classpath:applicationContext-cxf-client.xml");
//根据bean的id获取对象
//3.执行方法
Weatherservice weatherservice =(Weatherservice)context.getBean("client");
String str = weatherservice.getWeatherByCityName("北京");
System.out.println(str);
}
}
JAX-RS 规范 (现在比较火) 此案例为2个模块工程
JAX-RS 针对REST风格制定的一套web服务规范
REST是一种软件架构模式 只是一种风格,rest服务采用了HTTP传输协议
入门案例
引入坐标依赖 服务端 和 客户端 共同依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<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-transports-http-jetty</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-client</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-extension-providers</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<version>1.3.7</version>
</dependency>
</dependencies>
service接口
package com.itheima.service;
import com.itheima.domain.User;
import javax.ws.rs.*;
import java.util.List;
@Path("/userService") //访问这个接口的路径要求
@Produces("*/*") //生产 可以生产的类型 可以返还任何数据
public interface IUserService {
@POST //请求i方式
@Path("/user")
@Consumes({ "application/xml", "application/json" }) //消费 可以消费的类型 就是可以接收的2种数据类型
public void saveUser(User user);
@PUT
@Path("/user")
@Consumes({ "application/xml", "application/json" })
public void updateUser(User user);
@GET
@Path("/user")
@Produces({ "application/xml", "application/json" })
public List<User> findAllUsers();
@GET
@Path("/user/{id}")
@Consumes("application/xml")
@Produces({ "application/xml", "application/json" })
public User finUserById(@PathParam("id") Integer id);
@DELETE
@Path("/user/{id}")
@Consumes({"application/xml", "application/json"})
public void deleteUser(@PathParam("id") Integer id);
}
启动服务的spvm
package com.itheima.test;
import com.itheima.service.IUserService;
import com.itheima.service.UserServiceImpl;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
public class JaxrsserverTest {
public static void main(String[] args) {
//创建jaxrs服务对工厂对象
JAXRSServerFactoryBean jaxrsServerFactoryBean = new JAXRSServerFactoryBean();
//设置服务地址
jaxrsServerFactoryBean.setAddress("http://localhost:54321");
//设置提供服务的类
jaxrsServerFactoryBean.setServiceBean(new UserServiceImpl());
//设置日志输入和输出的两个拦截器 //不设置也行
jaxrsServerFactoryBean.getInInterceptors().add(new LoggingInInterceptor());
jaxrsServerFactoryBean.getOutInterceptors().add(new LoggingOutInterceptor());
//the last 启动服务
jaxrsServerFactoryBean.create();
}
}
客户端的使用
public class jaxrsClientTest {
/*
注意 它和jaxws的区别是 它使用的restful 的url
*/
@Test //测试保存方法
public void test() {
//使用WebClient创建访问地址 http://localhost:12345
// /userService 使用谁的方法
// /user 使用什么方法
// .type(MediaType.APPLICATION_JSON)
// MediaType.APPLICATION_XML指定传输数据格式 json 和 xml 可以
// .post (user)请求方式 传入参数
//参数不能是对象 不能是序列化的
User user = new User();
user.setId(1);
user.setUsername("小明");
user.setCity("北京");
Object post = WebClient.create("http://localhost:54321/userService/user").type(MediaType.APPLICATION_JSON).post(user);
System.out.println("post-" + post);
}
@Test
public void test02(){
WebClient.create("http://localhost:54321/userService/user/1").type(MediaType.APPLICATION_JSON).delete();
}
}
JAX-RS 和spring 整合
引入共同坐标依赖
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-client</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-extension-providers</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<version>1.3.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
web.xml applicationContext-cxf-rs.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>webservice_05jaxrs_spring</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-cxf-rs.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- CXF的核心控制器 -->
<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>/rs/*</url-pattern>
</servlet-mapping>
</web-app>
java内部 使用 service03的 com代码
配置文件
<?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:cxf="http://cxf.apache.org/core"
xmlns:jaxws="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.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.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 id="userService" address="/userService"> <!-- 这里配置了路径 那么 注解配置了 就重复了 -->
<jaxrs:serviceBeans>
<bean class="com.itheima.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>
</beans>
test 模拟客户端
//服务测试类
public class JaxrsspriingTest {
@Test
public void test(){
//创建客户端
// User user = WebClient.create("http://localhost:8080/rs/userService/user/1").accept(MediaType.APPLICATION_JSON).get(User.class);
// User user1 = WebClient.create("http://localhost:8080/rs/userService/user/1").type(MediaType.APPLICATION_JSON).get(User.class
// System.out.println(user);
User[] user = WebClient.create("http://localhost:8080/rs/userService/user").type(MediaType.APPLICATION_XML).get(User[].class);
System.out.println(Arrays.toString(user));
}
}