首先创建一个 SSM 的项目,我这里用的是一个开源的框架 jeesite1.2.7。大家也可以了解下这个框架。
在项目pom.xml中的 dependencies标签内加入一下代码,添加后下载依赖即可。
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-rt-frontend-jaxrsartifactId>
<version>3.0.16version>
dependency>
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-rt-rs-clientartifactId>
<version>3.0.16version>
dependency>
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-rt-rs-service-descriptionartifactId>
<version>3.0.16version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrsgroupId>
<artifactId>jackson-jaxrs-json-providerartifactId>
<version>2.2.3version>
dependency>
在WEB-INF文件夹下的web.xml中加入一下代码。这作用是拦截/webService/* 的所有请求
<servlet>
<servlet-name>cxfServletservlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>cxfServletservlet-name>
<url-pattern>/webService/*url-pattern>
servlet-mapping>
在resources文件夹下创建log4j.properties文件,添加一下代码。其中log4j.logger.org.apache.cxf=INFO这句代码是打印cxf-jaxrs请求和相应的信息。
# Output pattern : date [thread] priority category - message FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7
log4j.rootLogger=WARN, Console, RollingFile
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d %-5p [%c{5}] - %m%n
#RollingFile
log4j.appender.RollingFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.RollingFile.File=../logs/jeesite/jeesite.log
log4j.appender.RollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.RollingFile.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
#log4j.logger.java.sql=DEBUG
#Springframework level
#log4j.logger.org.springframework=ERROR
#Hibernate level
#log4j.logger.org.hibernate=ERROR
#log4j.logger.org.hibernate.cache.ehcache.AbstractEhcacheRegionFactory=ERROR
#log4j.logger.org.hibernate.search.impl.ConfigContext=ERROR
#log4j.logger.net.sf.ehcache.config.CacheConfiguration=ERROR
#Project defalult level
#log4j.logger.org.activiti.engine.impl.persistence=DEBUG
#log4j.logger.org.apache.shiro=DEBUG
log4j.logger.com.thinkgem.jeesite=DEBUG
log4j.logger.com.thinkgem.jeesite.common.security.shiro=WARN
log4j.logger.com.thinkgem.jeesite.common.utils.JedisUtils=WARN
log4j.logger.com.thinkgem.jeesite.modules.sys.web.LoginController=WARN
log4j.logger.com.thinkgem.jeesite.modules.oa.dao.OaNotifyDao.findCount=WARN
#项目log信息输出
log4j.logger.com.project=DEBUG
#打印 WebService cxf-jaxrs 的请求日志
log4j.logger.org.apache.cxf=INFO
创建一下代码接口。
import com.project.modules.mdm.entity.MdmMaterial;
import com.project.modules.ws.common.MdmRequestData;
import com.project.modules.ws.common.MdmResponseData;
import org.apache.cxf.jaxrs.model.wadl.Description;
import org.apache.cxf.jaxrs.model.wadl.DocTarget;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
/**
* 同步数据 WebService
*
* 增:POST
* 删:DELETE
* 改:PUT
* 查:GET
*
* @author YJH
* @date 2019-05-27
*/
@Description(value = "数据同步WebService", target = DocTarget.RESOURCE)
@Produces({MediaType.APPLICATION_JSON})
@Consumes({MediaType.APPLICATION_JSON})
public interface WsSyncDataService {
/**
* 保存主数据-物料信息
*
* @param requestData MdmRequestData
* @return MdmResponseData
*/
@POST
@Path("/saveMdmMaterialInfo")
@Description(value = "保存主数据-物料信息(POST请求,携带请求体)", target = DocTarget.METHOD)
MdmResponseData saveMdmMaterialInfo(MdmRequestData<MdmMaterial> requestData);
}
MdmRequestData类代码
import java.util.List;
/**
* 主数据接口请求 RequestData
*
* @author YJH
* @date 2019-05-29
*/
public class MdmRequestData<T> {
private String packId;
private String packageId;
private String mdmNameEn;
private List<T> list;
public MdmRequestData() {
}
public String getPackId() {
return packId;
}
public void setPackId(String packId) {
this.packId = packId;
}
public String getPackageId() {
return packageId;
}
public void setPackageId(String packageId) {
this.packageId = packageId;
}
public String getMdmNameEn() {
return mdmNameEn;
}
public void setMdmNameEn(String mdmNameEn) {
this.mdmNameEn = mdmNameEn;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
}
MdmResponseData类代码
import java.util.HashMap;
import java.util.Map;
/**
* 主数据接口返回 ResponseData
*
* @author YJH
* @date 2019-05-29
*/
public class MdmResponseData extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
/**
* 标志,成功“1”,失败“0”。
*/
private static final String RESULT = "result";
/**
* 请求返回信息,返回成功或错误信息
*/
private static final String MSG = "msg";
public MdmResponseData() {
put(RESULT, 1);
put(MSG, "success");
}
public static MdmResponseData error() {
return error(0, "未知异常,请联系管理员");
}
public static MdmResponseData error(String msg) {
return error(0, msg);
}
public static MdmResponseData error(int result, String msg) {
MdmResponseData data = new MdmResponseData();
data.put(RESULT, result);
data.put(MSG, msg);
return data;
}
public static MdmResponseData ok(String msg) {
MdmResponseData data = new MdmResponseData();
data.put(MSG, msg);
return data;
}
@SuppressWarnings("unchecked")
public static MdmResponseData ok(Map<String, Object> map) {
MdmResponseData data = new MdmResponseData();
data.putAll(map);
return data;
}
public static MdmResponseData ok() {
return new MdmResponseData();
}
@Override
public MdmResponseData put(String key, Object value) {
super.put(key, value);
return this;
}
}
MdmMaterial实体类代码。这个类命名太不规范了,请大家忽略 !
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.Lists;
import com.thinkgem.jeesite.common.persistence.DataEntity;
import org.hibernate.validator.constraints.Length;
import java.util.List;
/**
* 生产材料档案Entity
*
* @author xp
* @version 2019-05-28
*/
public class MdmMaterial extends DataEntity<MdmMaterial> {
private static final long serialVersionUID = 1L;
public static final String TableName = "mdm_material"; //表名
@JsonProperty(value = "CODE")
private String CODE; // 物料编码
@JsonProperty(value = "NAME")
private String NAME; // 物料名称
@JsonProperty(value = "MAT_TYPE")
private String MAT_TYPE; // 物料类型
@JsonProperty(value = "MAT_BASE_UOM")
private String MAT_BASE_UOM; // 物料基地计量单位
@JsonProperty(value = "MAT_INDUSTRY")
private String MAT_INDUSTRY; // 物料业
@JsonProperty(value = "MAT_APPLY_PLANT")
private String MAT_APPLY_PLANT; // 物料生产商
@JsonProperty(value = "MAT_DESC")
private String MAT_DESC; // 物料信息描述
@JsonProperty(value = "MAT_DETAIL_DESC")
private String MAT_DETAIL_DESC; // 物料信息具体描述
@JsonProperty(value = "MAT_PRODUCT_GROUP")
private String MAT_PRODUCT_GROUP; // 物料生产组
@JsonProperty(value = "MAT_WEIGHT_UNIT")
private String MAT_WEIGHT_UNIT; // 物料单位
@JsonProperty(value = "MAT_GROUP_CODE")
private String MAT_GROUP_CODE; // 物料组编码
@JsonProperty(value = "MAT_NORMAL_PROJ_GROUP")
private String MAT_NORMAL_PROJ_GROUP; // 物料标准项目组
@JsonProperty(value = "MAT_OVER_FACTORY_STATUS")
private String MAT_OVER_FACTORY_STATUS; // 物料在厂状态
@JsonProperty(value = "MAT_PROC_STRATEGY")
private String MAT_PROC_STRATEGY; // 物料代理商
@JsonProperty(value = "MAT_STANDARD")
private String MAT_STANDARD; // 物料标准化
@JsonProperty(value = "MAT_DATA_PROVIDER")
private String MAT_DATA_PROVIDER; // 物料数据供应商
@JsonProperty(value = "MAT_OLD_NUM")
private String MAT_OLD_NUM; // 物料排序号
private String assignee; // assignee
private String assigneemc; // assigneemc
private String createdt; // createdt
private String createId; // create_id
private String createName; // create_name
private String deptid; // deptid
private String fkid; // fkid
private String lcid; // lcid
private String mdmNameCn; // mdm_name_cn
private String organization; // organization
private String packid; // packid
private String states; // states
private String szhj; // szhj
private String szhjmc; // szhjmc
private String unit; // unit
private String updatedt; // updatedt
private String updateId; // update_id
private String updateName; // update_name
// 子表列表
@JsonProperty(value = "MDM_MATERIAL_ATTRIBUTE")
private List<MdmMaterialAttribute> MDM_MATERIAL_ATTRIBUTE = Lists.newArrayList();
public MdmMaterial() {
super();
}
public MdmMaterial(String id) {
super(id);
}
public String getCODE() {
return CODE;
}
public void setCODE(String CODE) {
this.CODE = CODE;
}
public String getNAME() {
return NAME;
}
public void setNAME(String NAME) {
this.NAME = NAME;
}
public String getMAT_TYPE() {
return MAT_TYPE;
}
public void setMAT_TYPE(String MAT_TYPE) {
this.MAT_TYPE = MAT_TYPE;
}
public String getMAT_BASE_UOM() {
return MAT_BASE_UOM;
}
public void setMAT_BASE_UOM(String MAT_BASE_UOM) {
this.MAT_BASE_UOM = MAT_BASE_UOM;
}
public String getMAT_INDUSTRY() {
return MAT_INDUSTRY;
}
public void setMAT_INDUSTRY(String MAT_INDUSTRY) {
this.MAT_INDUSTRY = MAT_INDUSTRY;
}
public String getMAT_APPLY_PLANT() {
return MAT_APPLY_PLANT;
}
public void setMAT_APPLY_PLANT(String MAT_APPLY_PLANT) {
this.MAT_APPLY_PLANT = MAT_APPLY_PLANT;
}
public String getMAT_DESC() {
return MAT_DESC;
}
public void setMAT_DESC(String MAT_DESC) {
this.MAT_DESC = MAT_DESC;
}
public String getMAT_DETAIL_DESC() {
return MAT_DETAIL_DESC;
}
public void setMAT_DETAIL_DESC(String MAT_DETAIL_DESC) {
this.MAT_DETAIL_DESC = MAT_DETAIL_DESC;
}
public String getMAT_PRODUCT_GROUP() {
return MAT_PRODUCT_GROUP;
}
public void setMAT_PRODUCT_GROUP(String MAT_PRODUCT_GROUP) {
this.MAT_PRODUCT_GROUP = MAT_PRODUCT_GROUP;
}
public String getMAT_WEIGHT_UNIT() {
return MAT_WEIGHT_UNIT;
}
public void setMAT_WEIGHT_UNIT(String MAT_WEIGHT_UNIT) {
this.MAT_WEIGHT_UNIT = MAT_WEIGHT_UNIT;
}
public String getMAT_GROUP_CODE() {
return MAT_GROUP_CODE;
}
public void setMAT_GROUP_CODE(String MAT_GROUP_CODE) {
this.MAT_GROUP_CODE = MAT_GROUP_CODE;
}
public String getMAT_NORMAL_PROJ_GROUP() {
return MAT_NORMAL_PROJ_GROUP;
}
public void setMAT_NORMAL_PROJ_GROUP(String MAT_NORMAL_PROJ_GROUP) {
this.MAT_NORMAL_PROJ_GROUP = MAT_NORMAL_PROJ_GROUP;
}
public String getMAT_OVER_FACTORY_STATUS() {
return MAT_OVER_FACTORY_STATUS;
}
public void setMAT_OVER_FACTORY_STATUS(String MAT_OVER_FACTORY_STATUS) {
this.MAT_OVER_FACTORY_STATUS = MAT_OVER_FACTORY_STATUS;
}
public String getMAT_PROC_STRATEGY() {
return MAT_PROC_STRATEGY;
}
public void setMAT_PROC_STRATEGY(String MAT_PROC_STRATEGY) {
this.MAT_PROC_STRATEGY = MAT_PROC_STRATEGY;
}
public String getMAT_STANDARD() {
return MAT_STANDARD;
}
public void setMAT_STANDARD(String MAT_STANDARD) {
this.MAT_STANDARD = MAT_STANDARD;
}
public String getMAT_DATA_PROVIDER() {
return MAT_DATA_PROVIDER;
}
public void setMAT_DATA_PROVIDER(String MAT_DATA_PROVIDER) {
this.MAT_DATA_PROVIDER = MAT_DATA_PROVIDER;
}
public String getMAT_OLD_NUM() {
return MAT_OLD_NUM;
}
public void setMAT_OLD_NUM(String MAT_OLD_NUM) {
this.MAT_OLD_NUM = MAT_OLD_NUM;
}
@Length(min = 0, max = 32, message = "assignee长度必须介于 0 和 32 之间")
public String getAssignee() {
return assignee;
}
public void setAssignee(String assignee) {
this.assignee = assignee;
}
@Length(min = 0, max = 240, message = "assigneemc长度必须介于 0 和 240 之间")
public String getAssigneemc() {
return assigneemc;
}
public void setAssigneemc(String assigneemc) {
this.assigneemc = assigneemc;
}
@Length(min = 0, max = 128, message = "createdt长度必须介于 0 和 128 之间")
public String getCreatedt() {
return createdt;
}
public void setCreatedt(String createdt) {
this.createdt = createdt;
}
@Length(min = 0, max = 32, message = "create_id长度必须介于 0 和 32 之间")
public String getCreateId() {
return createId;
}
public void setCreateId(String createId) {
this.createId = createId;
}
@Length(min = 0, max = 128, message = "create_name长度必须介于 0 和 128 之间")
public String getCreateName() {
return createName;
}
public void setCreateName(String createName) {
this.createName = createName;
}
@Length(min = 0, max = 128, message = "deptid长度必须介于 0 和 128 之间")
public String getDeptid() {
return deptid;
}
public void setDeptid(String deptid) {
this.deptid = deptid;
}
@Length(min = 0, max = 32, message = "fkid长度必须介于 0 和 32 之间")
public String getFkid() {
return fkid;
}
public void setFkid(String fkid) {
this.fkid = fkid;
}
@Length(min = 0, max = 100, message = "lcid长度必须介于 0 和 100 之间")
public String getLcid() {
return lcid;
}
public void setLcid(String lcid) {
this.lcid = lcid;
}
@Length(min = 0, max = 128, message = "mdm_name_cn长度必须介于 0 和 128 之间")
public String getMdmNameCn() {
return mdmNameCn;
}
public void setMdmNameCn(String mdmNameCn) {
this.mdmNameCn = mdmNameCn;
}
@Length(min = 0, max = 128, message = "organization长度必须介于 0 和 128 之间")
public String getOrganization() {
return organization;
}
public void setOrganization(String organization) {
this.organization = organization;
}
@Length(min = 0, max = 32, message = "packid长度必须介于 0 和 32 之间")
public String getPackid() {
return packid;
}
public void setPackid(String packid) {
this.packid = packid;
}
@Length(min = 0, max = 32, message = "states长度必须介于 0 和 32 之间")
public String getStates() {
return states;
}
public void setStates(String states) {
this.states = states;
}
@Length(min = 0, max = 100, message = "szhj长度必须介于 0 和 100 之间")
public String getSzhj() {
return szhj;
}
public void setSzhj(String szhj) {
this.szhj = szhj;
}
@Length(min = 0, max = 200, message = "szhjmc长度必须介于 0 和 200 之间")
public String getSzhjmc() {
return szhjmc;
}
public void setSzhjmc(String szhjmc) {
this.szhjmc = szhjmc;
}
@Length(min = 0, max = 32, message = "unit长度必须介于 0 和 32 之间")
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
@Length(min = 0, max = 128, message = "updatedt长度必须介于 0 和 128 之间")
public String getUpdatedt() {
return updatedt;
}
public void setUpdatedt(String updatedt) {
this.updatedt = updatedt;
}
@Length(min = 0, max = 32, message = "update_id长度必须介于 0 和 32 之间")
public String getUpdateId() {
return updateId;
}
public void setUpdateId(String updateId) {
this.updateId = updateId;
}
@Length(min = 0, max = 128, message = "update_name长度必须介于 0 和 128 之间")
public String getUpdateName() {
return updateName;
}
public void setUpdateName(String updateName) {
this.updateName = updateName;
}
public List<MdmMaterialAttribute> getMDM_MATERIAL_ATTRIBUTE() {
return MDM_MATERIAL_ATTRIBUTE;
}
public void setMDM_MATERIAL_ATTRIBUTE(List<MdmMaterialAttribute> MDM_MATERIAL_ATTRIBUTE) {
this.MDM_MATERIAL_ATTRIBUTE = MDM_MATERIAL_ATTRIBUTE;
}
}
实现上一步创建的接口创建WsSyncDataServiceImpl类
import com.fasterxml.jackson.core.type.TypeReference;
import com.project.modules.mdm.entity.MdmMaterial;
import com.project.modules.mdm.entity.MdmMaterialAttribute;
import com.project.modules.mdm.service.MdmMaterialService;
import com.project.modules.ws.common.MdmRequestData;
import com.project.modules.ws.common.MdmResponseData;
import com.project.modules.ws.service.WsSyncDataService;
import com.thinkgem.jeesite.common.mapper.JsonMapper;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
/**
* WebService 同步数据 Service
*
* @author YJH
* @date 2019-05-27
*/
@Component("wsSyncDataServiceImpl")
@Transactional(readOnly = true)
public class WsSyncDataServiceImpl implements WsSyncDataService {
@Autowired
private MdmMaterialService mdmMaterialService;
/**
* 保存主数据-物料信息
*
* @param requestData MdmRequestData
* @return MdmResponseData
*/
@Transactional
@Override
public MdmResponseData saveMdmMaterialInfo(MdmRequestData<MdmMaterial> requestData) {
try {
String tableName = requestData.getMdmNameEn();
if (tableName.equalsIgnoreCase(MdmMaterial.TableName)) {
mdmMaterialSave(requestData);
}
return MdmResponseData.ok();
} catch (Exception e) {
e.printStackTrace();
return MdmResponseData.error();
}
}
/**
* 物料保存
*
* @param requestData MdmRequestData
*/
private void mdmMaterialSave(MdmRequestData<MdmMaterial> requestData) {
List<MdmMaterial> mapList = new ArrayList<>();
CollectionUtils.addAll(mapList, requestData.getList().toArray());
List<MdmMaterial> list = JsonMapper.getInstance().convertValue(mapList, new TypeReference<List<MdmMaterial>>() {
});
for (MdmMaterial material : list) {
List<MdmMaterialAttribute> mdmMaterialAttributeList = material.getMDM_MATERIAL_ATTRIBUTE();
for (MdmMaterialAttribute attribute : mdmMaterialAttri mdmMaterialService.save(material);
}
}
}
import com.fasterxml.jackson.databind.DeserializationFeature;
/**
* 解析 cxf-jaxrs 的提供者
*
* @author YJH
* @date 2019-05-27
*/
public class JacksonJaxbJsonProvider extends com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider {
public JacksonJaxbJsonProvider() {
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
}
/**
* WebService 登录认证异常
*
* @author YJH
* @date 2019-05-27
*/
public class WsAuthenticateException extends Exception {
public WsAuthenticateException(String message) {
super(message);
}
}
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
/**
* WebService 统一异常处理
* 参考:
* https://blog.csdn.net/forlinkext/article/details/78115640
* https://blog.csdn.net/love_hanyu/article/details/84352763
*
* @author YJH
* @date 2019-05-27
*/
public class WsExceptionMapper implements ExceptionMapper<Exception> {
@Override
public Response toResponse(Exception e) {
String type = "application/json;charset=UTF-8";
if (e instanceof WsAuthenticateException) {
MdmResponseData responseData = MdmResponseData.error(e.getMessage());
return Response.status(Response.Status.BAD_REQUEST).entity(responseData).type(type).build();
} else {
MdmResponseData responseData = MdmResponseData.error("未知错误,请稍后重试");
return Response.status(Response.Status.BAD_REQUEST).entity(responseData).type(type).build();
}
}
}
import com.thinkgem.jeesite.common.utils.StringUtils;
import org.apache.cxf.configuration.security.AuthorizationPolicy;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
/**
* WebService 登录认证拦截器
* 参考:
* https://blog.csdn.net/u014695188/article/details/51731116 *
*
* @author YJH
* @date 2019-05-27
*/
public class AuthenticateInterceptor extends AbstractPhaseInterceptor {
public static final String userName = "username";
public static final String password = "password";
public AuthenticateInterceptor() {
this(Phase.PRE_PROTOCOL);
//this(Phase.PRE_INVOKE);
}
public AuthenticateInterceptor(String phase) {
super(phase);
System.out.println("CheckUserInterceptor(String phase)");
}
@Override
public void handleMessage(Message message) throws Fault {
try {
AuthorizationPolicy authorizationPolicy = (AuthorizationPolicy) message.get("org.apache.cxf.configuration.security.AuthorizationPolicy");
String userName = authorizationPolicy.getUserName();
String password = authorizationPolicy.getPassword();
if (StringUtils.isBlank(userName) || StringUtils.isBlank(password)) {
throw new Fault(new WsAuthenticateException("账号和密码都不能为空"));
}
if (!AuthenticateInterceptor.userName.equals(userName) || !AuthenticateInterceptor.password.equals(password)) {
throw new Fault(new WsAuthenticateException("账号或密码校验失败"));
}
} catch (Exception e) {
throw new Fault(new WsAuthenticateException("账号和密码都不能为空"));
}
}
@Override
public void handleFault(Message message) {
}
}
以上就完成了服务端的kbd>java代码编写
在resources文件夹下创建spring-context-cxf-jaxrs.xml。
这里要注意由于我用的是jeesite框架,可以把这个spring配置文件直接引用,如果不是用这个框架需要手动引用这个文件
<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:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd"
default-lazy-init="true">
<description>cxf-jaxrs Configurationdescription>
<context:property-placeholder ignore-unresolvable="true" location="classpath:jeesite.properties"/>
<bean id="jacksonJaxbJsonProvider" class="com.project.modules.ws.common.JacksonJaxbJsonProvider"/>
<bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
<bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
<bean id="wsAuthenticateInterceptor" class="com.project.modules.ws.common.AuthenticateInterceptor"/>
<bean id="wsExceptionMapper" class="com.project.modules.ws.common.WsExceptionMapper"/>
<jaxrs:server address="/wsSyncDataService">
<jaxrs:serviceBeans>
<ref bean="wsSyncDataServiceImpl"/>
jaxrs:serviceBeans>
<jaxrs:providers>
<ref bean="jacksonJaxbJsonProvider"/>
<ref bean="wsExceptionMapper"/>
jaxrs:providers>
<jaxrs:inInterceptors>
<ref bean="loggingInInterceptor"/>
<ref bean="wsAuthenticateInterceptor"/>
jaxrs:inInterceptors>
<jaxrs:outInterceptors>
<ref bean="loggingOutInterceptor"/>
jaxrs:outInterceptors>
jaxrs:server>
在测试包下创建测试类
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.project.modules.ws.common.AuthenticateInterceptor;
import com.project.modules.ws.common.JacksonJaxbJsonProvider;
import com.project.modules.ws.common.MdmRequestData;
import com.project.modules.ws.common.MdmResponseData;
import com.thinkgem.jeesite.common.mapper.JsonMapper;
import com.thinkgem.jeesite.common.utils.StreamUtils;
import org.apache.cxf.jaxrs.client.ClientConfiguration;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.transport.Conduit;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.junit.Test;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* 测试同步数据 WebService
*/
public class testWsSyncDataService {
private String baseUrl = "http://localhost:8080/znzyc/webService/wsSyncDataService";
@Test
public void testSaveMdmInfo() {
//假数据
MdmRequestData<MdmRequestData> requestData = (MdmRequestData<MdmRequestData>) JsonMapper.fromJsonString("{\"packId\":\"a323c1b379d74ed897264f2f4a479d2b\",\"packageId\":\"dd9189c10b06471fb1d3f658fb4349e8\",\"mdmNameEn\":\"MDM_MATERIAL\",\"list\":[{\"MDM_MATERIAL_ATTRIBUTE\":[{\"MAT_ATTR_NAME\":\"011102:1配件名称*\",\"MAT_ATTR_VALUE\":\"螺栓\",\"MAT_CODE\":\"10090315\"},{\"MAT_ATTR_NAME\":\"011102:2规格型号/配件号/图号*\",\"MAT_ATTR_VALUE\":\"00925441-0819\",\"MAT_CODE\":\"10090315\"},{\"MAT_ATTR_NAME\":\"011102:3主机名称*\",\"MAT_ATTR_VALUE\":\"采煤机\",\"MAT_CODE\":\"10090315\"},{\"MAT_ATTR_NAME\":\"011102:4主机型号*\",\"MAT_ATTR_VALUE\":\"6LS05\",\"MAT_CODE\":\"10090315\"},{\"MAT_ATTR_NAME\":\"011102:5国产/进口*\",\"MAT_ATTR_VALUE\":\"进口\",\"MAT_CODE\":\"10090315\"}],\"MAT_WEIGHT_UNIT\":\"KG\",\"MAT_INDUSTRY\":\"K\",\"MAT_PRODUCT_GROUP\":\"WZ\",\"MAT_NORMAL_PROJ_GROUP\":\"NORM\",\"NAME\":\"\",\"MAT_PROC_STRATEGY\":\"001\",\"MAT_TYPE\":\"Z100\",\"MAT_DESC\":\"螺栓\\\\00925441-0819\\\\采煤机\\\\6LS05\\\\进口\",\"MAT_DATA_PROVIDER\":\"\",\"CODE\":\"10090315\",\"MAT_GROUP_CODE\":\"011102\",\"MAT_OLD_NUM\":\"44412011J021716\",\"MAT_APPLY_PLANT\":\"SD00\",\"MAT_DETAIL_DESC\":\"螺栓\\\\00925441-0819\\\\采煤机\\\\6LS05\\\\进口\",\"MAT_OVER_FACTORY_STATUS\":\"\",\"MAT_BASE_UOM\":\"PC\",\"MAT_STANDARD\":\"\"},{\"MDM_MATERIAL_ATTRIBUTE\":[{\"MAT_ATTR_NAME\":\"011102:1配件名称*\",\"MAT_ATTR_VALUE\":\"胶管总成\",\"MAT_CODE\":\"10069869\"},{\"MAT_ATTR_NAME\":\"011102:2规格型号/配件号/图号*\",\"MAT_ATTR_VALUE\":\"S 217277 00\",\"MAT_CODE\":\"10069869\"},{\"MAT_ATTR_NAME\":\"011102:3主机名称*\",\"MAT_ATTR_VALUE\":\"采煤机\",\"MAT_CODE\":\"10069869\"},{\"MAT_ATTR_NAME\":\"011102:4主机型号*\",\"MAT_ATTR_VALUE\":\"SL500\",\"MAT_CODE\":\"10069869\"},{\"MAT_ATTR_NAME\":\"011102:5国产/进口*\",\"MAT_ATTR_VALUE\":\"进口\",\"MAT_CODE\":\"10069869\"}],\"MAT_WEIGHT_UNIT\":\"KG\",\"MAT_INDUSTRY\":\"K\",\"MAT_PRODUCT_GROUP\":\"WZ\",\"MAT_NORMAL_PROJ_GROUP\":\"NORM\",\"NAME\":\"\",\"MAT_PROC_STRATEGY\":\"001\",\"MAT_TYPE\":\"Z100\",\"MAT_DESC\":\"胶管总成\\\\S 217277 00\\\\采煤机\\\\SL500\\\\进口\",\"MAT_DATA_PROVIDER\":\"\",\"CODE\":\"10069869\",\"MAT_GROUP_CODE\":\"011102\",\"MAT_OLD_NUM\":\"44412011J060033\",\"MAT_APPLY_PLANT\":\"SD00\",\"MAT_DETAIL_DESC\":\"胶管总成\\\\S 217277 00\\\\采煤机\\\\SL500\\\\进口\",\"MAT_OVER_FACTORY_STATUS\":\"\",\"MAT_BASE_UOM\":\"PC\",\"MAT_STANDARD\":\"\"}]}", MdmRequestData.class);
WebClient webClient = createWebClient("/saveMdmMaterialInfo");
Response response = webClient.post(requestData);
String jsonStr = StreamUtils.InputStreamTOString((InputStream) response.getEntity());
System.out.println(jsonStr);
MdmResponseData responseData = (MdmResponseData) JsonMapper.fromJsonString(jsonStr, MdmResponseData.class);
System.out.println(responseData.toString());
webClient.close();
}
/**
* 创建一个客户端
*
* @param path 路径
* @return WebClient
*/
private WebClient createWebClient(String path) {
return createWebClient(path, 0);
}
/**
* 创建一个客户端
*
* @param path 路径
* @param timeOut 超时时间,单位毫秒。0表示不限制
* @return WebClient
*/
private WebClient createWebClient(String path, long timeOut) {
WebClient webClient = WebClient.create(baseUrl, getProviderList(), AuthenticateInterceptor.USER_NAME, AuthenticateInterceptor.PASSWORD, null)
.path(path)
.type(MediaType.APPLICATION_JSON) //指定请求的数据格式为 JSON
.accept(MediaType.APPLICATION_JSON); //指定响应的数据格式为 JSON;
ClientConfiguration config = WebClient.getConfig(webClient);
Conduit conduit = config.getConduit();
HTTPClientPolicy client = ((HTTPConduit) conduit).getClient();
//指定时间量(以毫秒为单位),消费者在超时前等待响应。 0是无限的。
client.setReceiveTimeout(timeOut);
//指定时间量(以毫秒为单位),消费者将在超时之前尝试建立连接。 0是无限的。
client.setConnectionTimeout(timeOut);
return webClient;
}
/**
* 添加 JSON 转换提供者
*
* @return List
private List<Object> getProviderList() {
List<Object> providerList = new ArrayList<Object>();
JacksonJaxbJsonProvider jsonProvider = new JacksonJaxbJsonProvider();
//使用 jackson 发生 UnrecognizedPropertyException 异常
//参考:https://yunix.iteye.com/blog/2043909
jsonProvider.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
providerList.add(jsonProvider);
return providerList;
}
}
执行testSaveMdmInfo()方法Tomcat控制台输出
请求输出
在浏览器中输入你所发布的service的地址后面加上?_wadl就会生成xml描述
到此已经完结
https://www.cnblogs.com/huangcongcong/p/4761732.html
https://blog.csdn.net/u014695188/article/details/51731116
https://blog.csdn.net/wk52525/article/details/79113978
https://blog.csdn.net/XiaopinOo/article/details/76851310
https://blog.csdn.net/u013313550/article/details/53409735
https://blog.csdn.net/forlinkext/article/details/78115640
https://blog.csdn.net/love_hanyu/article/details/84352763
https://blog.csdn.net/u014695188/article/details/51731116
http://www.doc88.com/p-9032352995964.html
https://blog.csdn.net/qq_36504446/article/details/79116027
https://www.cnblogs.com/sumingk/p/7243924.html
https://www.bilibili.com/video/av37531805