Socket 服务端:提供服务的一段开启服务
web Service 规范:Jax-ws soap协议,JaxM&SAAJ . jax-rs
JSON.parseobject(json返回值,对象名.class):根据对象转出对象
对接web Service:作为客户端连接服务器端接口配置
怎样查看接口地址:IP+端口号+cxfServlet过滤器中的筛选条件+applicationContext-ws.xml配置文件中的
/export 然后在后面写上
?wsdl
<jaxws:server address="/export">
<jaxws:serviceBean >
<ref bean="epService" />
</jaxws:serviceBean>
</jaxws:server>
1.导坐标 :在父工程的pom.xml中导入
<!-- cxf坐标的引入 start-->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
</dependency>
<!-- cxf end -->
2.创建一个子模块对接:
2.1:在子模块中 的 找到想要自动生成的接口文件路径。cmd进入命令提示符 然后输入
Wsimport -s . 路径名
3.创建配置文件 一般设置在web中
classpath:applicationContext-ws.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"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
">
<!-- 配置客户端对象 -->
<jaxws:client id="exportClient" address="http://localhost:8080/jk_export/ws/export?wsdl(ps:这里写接口地址)" serviceClass="cn.itcast.export.webservice.IEpService(接口路径)"/>//设置接口路径 在web中的pom.xml 中 添加子模块 在把接口路径写上就可以了。 如下图
</beans>
/*写完后在applicationContext.xml中引入文件 <import resource="classpath:applicationContext-ws.xml"/>*/
//设置接口路径 在web中的pom.xml 中。
4.
4.1在Action中写对接代码
案例:这是一个保运项目,拿到对方的接口,及指导需要传什么数据时,开始封装数据成JSON给接口,,,,,
如果保运后想要修改自己的内容,则可以根据返回内容来获取服务器闯过来的数据,进行封装保存即可
exportServiceimpl
:货运单
exportProductServiceimpl
:货物表
// TODO Auto-generated method stub
// 出口报运单对象
Export export = exportServiceimpl.get(model.getId());
/** 接口文件需要的数据类型,,,一个map存储保运数据 map里面有还有一个list集合存储货物的
* {
exportId:"",
state:"",
remark:"",
products:[
{
exportProductId:"",
tax:""
},
{
exportProductId:"",
tax:""
}
]
}
*
*/
HashMap exportMap = new HashMap();
exportMap.put("exportId", export.getId()); //把保运的ID传过去
// 下面的属性都是为了海关保存mysql数据库时用,并不影响当前系统逻辑
exportMap.put("boxNums", export.getBoxNums());
exportMap.put("destinationPort", export.getDestinationPort());
exportMap.put("customerContract", export.getCustomerContract());
ArrayList list = new ArrayList();
Set<ExportProduct> exportProducts = export.getExportProducts(); //通过保运查到货物数据
for (ExportProduct exportProduct : exportProducts) { //循环报运单中所有的货物,封装map数据
HashMap epMap = new HashMap();
epMap.put("exportProductId", exportProduct.getId());
// 下面的属性都是为了海关保存mysql数据库时用,并不影响当前系统逻辑
epMap.put("cnumber", exportProduct.getCnumber());
epMap.put("price", exportProduct.getPrice());
list.add(epMap);
}
exportMap.put("products", list); //封装出口报运货物集合到出口报运map中
String jsonString = JSON.toJSONString(exportMap);
System.out.println(jsonString);
String exportE = epService.exportE(jsonString);
//JSON.parseObject 根据对象转出对象
HashMap returnMap = JSON.parseObject(exportE,HashMap.class);
// 根据返回内容更新本地报运单
Export exportDb = exportServiceimpl.get(returnMap.get("exportId").toString());
exportDb.setState(Integer.parseInt( returnMap.get("state").toString()));
exportDb.setRemark(returnMap.get("remark").toString());
exportServiceimpl.saveOrUpdate(exportDb); //修改数据后保存数据库
List<HashMap> returnList = JSON.parseArray(returnMap.get("products").toString(), HashMap.class);
for (HashMap hashMap : returnList) {
// 根据海关返回的货物id查询当前系统的货物对象,进行tax赋值
ExportProduct epDb = exportProductServiceimpl.get(hashMap.get("exportProductId").toString());
epDb.setTax(Double.parseDouble( hashMap.get("tax").toString()));
exportProductServiceimpl.saveOrUpdate(epDb);
}
return "alist";//这里直接返回到保运管理界面即可
4.2 在上面代码中,我们可以看到,由于接口文件的货运单及货物数据类型 (就是名字不一样)和我们本地的数据类型不匹配,因此需要使用map来进行封装数据,为了解决这种方法我们还可以使用注解的方式来使属性名相同
@JSONField
(
name
=
"接口对应的属性名"
),
这个写在domain里面,,,比如说接口服务器,和我们的客户端力度ID属性名,不同,又不想使用map进行封装的话,就可以在我们本地类的属性名中的与之对应的属性写上@JSONField(name="id")
ps:这个注解是有缺点的,由于改变了json传数据时的属性名,有可能会造成自己原先通过json传送的数据失效,破坏业务代码,一般建议不要使用
案例:下面的类中货运单的ID 和其货物表的属性名不同 就可以直接写上与之对应的接口ID名 货物表属性名
@Id
@Column(name="EXPORT_PRODUCT_ID")
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid",strategy="uuid")
@JSONField(name="exportProductId")
private String id;
@ManyToOne
@JoinColumn(name="EXPORT_ID")
private Export export; //报运货物和报运的关系,多对一
这样我们在action中就可以简化代码程序了
exportServiceimpl
:货运单
exportProductServiceimpl
:货物表
@Action(value="exportAction_exportE",results={@Result(name="alist",type="redirectAction",location="exportAction_list")})
public String exportE() throws Exception {
Export export = exportServiceimpl.get(model.getId());//客户端数据库查询货运单数据
String jsonString = JSON.toJSONString(export);//通过JSON传走
String exportE = epService.exportE(jsonString);//调用服务器接口里的方法
//更具返回值exportE 通过JSON.parseObject(exportE, 对象名.class); 拿到服务器返回的数据 Export parseObject = JSON.parseObject(exportE, Export.class);
//通过返回值的ID查到返回的数据
Export export2 = exportServiceimpl.get(parseObject.getId());
//封装传过来的数据
export2.setState(parseObject.getState());
export2.setRemark(parseObject.getRemark());
//调用保存方法 保存货运单
exportServiceimpl.saveOrUpdate(export2);
//通过服务器返回值查找货物表的数据 返回一个set集合
Set<ExportProduct> exportProducts = parseObject.getExportProducts();
for (ExportProduct exportProduct : exportProducts) {
//循环, 通过ID查找的货物表的数据,并封装
ExportProduct exportProduct2 = exportProductServiceimpl.get(exportProduct.getId());
//调用保存方法 保存货物表
exportProductServiceimpl.saveOrUpdate(exportProduct2);
}
return "alist";
}