- webService 主要有jax-ws和jax-rs 两种规范
- apache cxf是基于这两种规范的webservice框架
- jaxB 通过注解实现配置java对象到xml的转换
一.Jax-ws 规范
1. springboot + cxf 实现
目录结构
bean:封装请求参数和返回结果
jaxBAdapter:转换特殊字段
service: 接口和实现
config: 接口发布
代码
<!--webservice cxf start-->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.4.1</version>
</dependency>
<!--webservice cxf end-->
package com.horizon.ws;
import com.horizon.ws.service.UserWebService;
import org.apache.cxf.Bus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.xml.ws.Endpoint;
/**
*@Description webservice 服务配置
*@Author haojw
*@Date 2021-10-28 11:10:05
*/
@Configuration
public class WebServiceConfig {
@Autowired
private Bus bus;
@Autowired
private UserWebService userWebService;
/**
* 此方法被注释后:wsdl访问地址为http://127.0.0.1:8080/services/user?wsdl
* 去掉注释后:wsdl访问地址为:http://127.0.0.1:8080/WebService/UserWebService?wsdl
*/
@Bean
public ServletRegistrationBean webServiceDispatcherServlet(){
return new ServletRegistrationBean(new CXFServlet(),"/WebService/*");
}
@Bean
public Endpoint endpointUserService() {
EndpointImpl endpoint = new EndpointImpl(bus, userWebService);
endpoint.publish("/UserWebService");//接口发布在 http://127.0.0.1:8080/springboot-basic/WebService/UserWebService?wsdl 目录下
return endpoint;
}
}
package com.horizon.ws.service;
import com.horizon.ws.bean.*;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import java.util.List;
/**
* webservice user接口
* 不加@WebResult@WebParam注解默认外层标签为arg0和return
* @author haojw
* @since 2021/12/28 12:00
*/
@WebService(serviceName = "UserWebService",targetNamespace="http://user.ws.horizon.com",endpointInterface = "com.horizon.ws.service.UserWebService")
public interface UserWebService {
/**
* 返回字符串
* @param id
* @return java.lang.String
* @author haojw
* @since 2021/12/29 14:05
*/
@WebMethod
public @WebResult(name = "userName") String getUserName(@WebParam(name = "userId") String id) ;
/**
* 返回一个对象
* @param userParm
* @return com.horizon.ws.bean.UserRes
* @author haojw
* @since 2021/12/29 14:05
*/
@WebMethod
public @WebResult(name = "user") UserRes getUserInfo(@WebParam(name = "user") UserParm userParm);
/**
* 返回一个list
* @param userParm
* @return java.util.List<com.horizon.ws.bean.UserRes>
* @author haojw
* @since 2021/12/29 14:05
*/
@WebMethod
public @WebResult(name = "user") List<UserRes> getUserList(@WebParam(name = "user") UserParm userParm);
/**
* 返回一个封装泛型的对象,不支持
* @param userParm
* @return java.util.List<com.horizon.ws.bean.UserRes>
* @author haojw
* @since 2021/12/29 14:05
*/
@WebMethod
public @WebResult(name = "msg") MessageResT<List<UserRes>> getUserListResT(@WebParam(name = "user") UserParm userParm);
/**
* 返回一个复杂对象
* @param userParm
* @return java.util.List<com.horizon.ws.bean.UserRes>
* @author haojw
* @since 2021/12/29 14:05
*/
@WebMethod
public @WebResult(name = "msg")
MessageRes getUserListRes(@WebParam(name = "user") UserParm userParm);
/**
* 保存,返回一个对象
* @param userParm
* @return java.util.List<com.horizon.ws.bean.UserRes>
* @author haojw
* @since 2021/12/29 14:05
*/
@WebMethod
public @WebResult(name = "user") UserRes receiveUser(@WebParam(name = "user") UserParm userParm);
}
package com.horizon.ws.service;
import com.horizon.business.user.entity.User;
import com.horizon.business.user.service.UserService;
import com.horizon.common.message.MessageCodeEnum;
import com.horizon.ws.bean.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
*@Description ws接口服务实现
*@Author haojw
*@Date 2021-10-28 11:10:05
*/
@Service
public class UserWebServiceImpl implements UserWebService {
@Autowired
protected UserService userService;
/**
* 返回字符串
* @param id
* @return java.lang.String
* @author haojw
* @since 2021/12/29 14:05
*/
@Override
public String getUserName(String id) {
User user = userService.selectUser(id);
//封装返回结果
UserRes userRes = new UserRes();
BeanUtils.copyProperties(user,userRes);
return userRes.getName();
}
/**
* 返回一个对象
* @param userParm
* @return com.horizon.ws.bean.UserRes
* @author haojw
* @since 2021/12/29 14:05
*/
@Override
public UserRes getUserInfo(UserParm userParm) {
User user = new User();
BeanUtils.copyProperties(userParm,user);
user = userService.selectUser(user.getId());
//封装返回结果
UserRes userRes = new UserRes();
BeanUtils.copyProperties(user,userRes);
return userRes;
}
/**
* 返回一个list
* @param userParm
* @return java.util.List<com.horizon.ws.bean.UserRes>
* @author haojw
* @since 2021/12/29 14:05
*/
@Override
public List<UserRes> getUserList(UserParm userParm) {
User user = new User();
BeanUtils.copyProperties(userParm,user);
List<User> list = userService.selectUserList(user);
//封装返回结果
List<UserRes> resList = new ArrayList<UserRes>();
for(User entity : list){
UserRes res = new UserRes();
BeanUtils.copyProperties(entity,res);
resList.add(res);
}
return resList;
}
/**
* 返回一个封装泛型的对象,不支持
* @param userParm
* @return java.util.List<com.horizon.ws.bean.UserRes>
* @author haojw
* @since 2021/12/29 14:05
*/
@Override
public MessageResT<List<UserRes>> getUserListResT(UserParm userParm) {
User user = new User();
BeanUtils.copyProperties(userParm,user);
List<User> list = userService.selectUserList(user);
//封装返回结果
List<UserRes> resList = new ArrayList<UserRes>();
for(User entity : list){
UserRes res = new UserRes();
BeanUtils.copyProperties(entity,res);
resList.add(res);
}
return new MessageResT<List<UserRes>>(MessageCodeEnum.OK,resList);
}
/**
* 返回一个封装的复杂对象
* @param userParm
* @return java.util.List<com.horizon.ws.bean.UserRes>
* @author haojw
* @since 2021/12/29 14:05
*/
@Override
public MessageRes getUserListRes(UserParm userParm) {
User user = new User();
BeanUtils.copyProperties(userParm,user);
List<User> list = userService.selectUserList(user);
//封装返回结果
List<UserRes> resList = new ArrayList<UserRes>();
for(User entity : list){
UserRes res = new UserRes();
BeanUtils.copyProperties(entity,res);
resList.add(res);
}
return new MessageRes(MessageCodeEnum.OK,resList);
}
/**
* 保存,返回一个对象
* @param userParm
* @return java.util.List<com.horizon.ws.bean.UserRes>
* @author haojw
* @since 2021/12/29 14:05
*/
@Override
public UserRes receiveUser(UserParm userParm) {
User user = new User();
BeanUtils.copyProperties(userParm,user);
userService.saveUser(user);
//封装返回结果
UserRes userRes = new UserRes();
BeanUtils.copyProperties(user,userRes);
return userRes;
}
}
package com.horizon.ws.JaxBAdapter;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
*
* JAXB @XmlJavaTypeAdapter(DateAdapter.class)注解适配器
* 实现字段类型转换
* @author haojw
* @since 2021/12/29 13:23
*/
public class DateAdapter extends XmlAdapter<String, Date> {
private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public String marshal(Date v) throws Exception {
synchronized (dateFormat) {
return dateFormat.format(v);
}
}
@Override
public Date unmarshal(String v) throws Exception {
synchronized (dateFormat) {
return dateFormat.parse(v);
}
}
}
package com.horizon.ws.bean;
import com.horizon.ws.JaxBAdapter.DateAdapter;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.Date;
/**
* 接口返回信息
*
* @author haojw
*/
@Data
/*
* JaxB根注解,使用其它注解必须有的
*/
@XmlRootElement
/*
* XmlAccessType.FIELD:映射这个类中的所有字段到XML
* XmlAccessType.PROPERTY:映射这个类中的属性(get/set方法)到XML
* XmlAccessType.PUBLIC_MEMBER:将这个类中的所有public的field或property同时映射到XML(默认)
* XmlAccessType.NONE:不映射
*/
@XmlAccessorType(XmlAccessType.FIELD)
public class UserRes {
/*
* 映射注解,name可以指定节点名称
*/
@XmlElement(name="ID")
private String id;
private String name;
private int no;
/*
* 适配器注解,实现日期格式及类型转换
*/
@XmlJavaTypeAdapter(DateAdapter.class)
private Date createDate;
}
package com.horizon.ws.bean;
import lombok.Data;
/**
* 接口请求信息
*
* @author haojw
*/
@Data
public class UserParm {
private String id;
private String name;
}
package com.horizon.ws.bean;
import com.horizon.common.message.MessageCodeEnum;
import lombok.Data;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
/**
* 接口返回信息
*
* @author haojw
*/
@Data
public class MessageResT<T> implements Serializable {
private static final long serialVersionUID = 7192766535561421181L;
private String msg;
private T data;
private Integer code;
public MessageResT(MessageCodeEnum errorCode, T data ) {
this.code = errorCode.getCode();
this.data = data;
this.msg = errorCode.getMessage();
}
}
package com.horizon.ws.bean;
import com.horizon.common.message.MessageCodeEnum;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 接口返回信息
*
* @author haojw
*/
@Data
public class MessageRes implements Serializable {
private static final long serialVersionUID = 7192766535561421181L;
private String msg;
private List<UserRes> data;
private Integer code;
public MessageRes(MessageCodeEnum errorCode, List<UserRes> data) {
this.code = errorCode.getCode();
this.data = data;
this.msg = errorCode.getMessage();
}
}
业务代码userService和user省略
2.spring web + jdk 实现
参考:https://www.jianshu.com/p/94addb458778
主要是发布方式不同
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.2.10</version>
</dependency>
web-inf 下建一个sun-jaxws.xml 文件用来发布接口
<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
<endpoint name="receiveMessageService" implementation="com.horizon.ws.ReceiveMessageServiceImpl" url-pattern="/webservice/receiveMessageService" >
</endpoint>
</endpoints>
web.xml 文件添加监听启动
<listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet>
<servlet-name>jaxws</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jaxws</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>