接上文JAX-WS:创建简单的webservice,JAX-WS对大部分复杂对象传递都能直接支持。在服务端传递了自定义的复杂对象Person:
public class Person implements Serializable {
private static final long serialVersionUID = 8336803120311071811L;
private String username;
private Date birthday;
private List<Address> addresses;
//getter/setter
我们来看看根据wsimport生产的客户端中Person的定义:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "person", propOrder = {
"addresses",
"birthday",
"username"
})
public class Person {
@XmlElement(nillable = true)
protected List<Address> addresses;
@XmlSchemaType(name = "dateTime")
protected XMLGregorianCalendar birthday;
protected String username;
//getter/setter
}
在生产的客户端代码中多了很多annotation声明,在前面也说了JAX-WS是一种基于xml传递的webservice,也就是需要将传递的参数转化为xml文档,而这其中转化的过程就是我们见到的客户端对象中各种annotation声明,其背后的技术也就是前面说的JAXB(Java Architecture for XML Binding)简单地说就是一种将JAVA对象和XML互相转换的技术。包含在包
javax.jws
javax.xml.bind下提供了一系列解组、编组已经运行时绑定的API
javax.xml.bind.annotation 定义将 Java 程序元素定制成XML模式映射的注释
javax.xml.bind.annotation.adapters XmlAdapter 及其规范定义的子类允许任意 Java 类与 JAXB 一起使用
----------------------------------------
主要的接口或类:
HandlerChain 将 Web Service 与外部定义的处理程序链关联。
Oneway 指示给定 @WebMethod 只有一条输入消息并且没有输出。
WebMethod 定制一个公开为 Web Service 操作的方法。
WebParam 定制单个参数到 Web Service 消息部分和 XML 元素的映射关系。
WebResult 定制返回值到 WSDL 部分和 XML 元素的映射关系。
WebService 将 Java 类标记为实现 Web Service,或者将 Java 接口标记为定义 Web Service 接口。
Element 这是一个元素标记接口。
Marshaller Marshaller 类负责管理将 Java 内容树序列化回 XML 数据的过程。
Unmarshaller Unmarshaller 类管理将 XML 数据反序列化为新创建的 Java 内容树的过程,并可在解组时有选择地验证 XML 数据。
UnmarshallerHandler 作为 SAX ContentHandler 实现的 Unmarshaller。
ValidationEvent此事件指示在执行解组操作期间验证传入的 XML 数据时、对 Java 内容树执行按需验证时或将 Java 内容树编组回 XML 数据时遇到问题。
DatatypeConverter可以使用 javaType 绑定声明来自定义 XML 模式数据类型到 Java 数据类型的绑定。
JAXBContext JAXBContext 类提供到 JAXB API 的客户端入口点。
XmlAdapter 修改 Java 类型以适应自定义编组
主要的Annotation
XmlAccessorOrder 控制类中字段和属性的排序。
XmlAccessorType 控制默认情况下是否对字段或 Javabean 属性进行系列化。
XmlAttribute 将 JavaBean 属性映射到 XML 属性。
XmlElement 将 JavaBean 属性映射到派生于属性名称的 XML 元素。
XmlElementWrapper 生成一个包装 XML 表示形式的包装器元素。
XmlList 用来将属性映射到列表简单类型。
XmlMimeType 关联控制属性 XML 表示形式的 MIME 类型。
XmlRootElement 将类或枚举类型映射到 XML 元素。
XmlTransient 阻止将 JavaBean 属性映射到 XML 表示形式。
XmlType 将类或枚举类型映射到 XML 模式类型。
XmlValue 支持将类映射到带有 simpleContent 的 XML 模式复杂类型或 XML 模式简单类型。
1、如何解码转码
JAXBContext是JAXB API 的客户端入口,从java到xml的互相转换对应Marshaller和Unmarshaller。一个简单的例子是
JAXBContext jaxbContext = JAXBContext.newInstance(claszz);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8");
marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://sws.org/sample");
marshaller.marshal(t, System.out);
marshaller.marshal(t, new File("c:\\t.xml"));
这里只是java转xml的例子。设置了格式化输出、encoding等属性、schema等信息,同时输出到控制台和指定文件路径
2、常用annotation
常用的annotation用来绑定转换运行过程中的各种属性,如绑定属性、绑定的顺序、格式化处理等。下面介绍一些常用
@XmlRootElement(name="",namespace="")
标注此类作为xml的一个root节点,常用在顶层类或枚举类型。以下注释一起使用: XmlType、XmlEnum、XmlAccessorType、 XmlAccessorOrder。作为生产xml的root节点,名称可通过name来指定,默认会为该类名
@XmlAccessorType(XmlAccessType.FIELD)
控制对JavaBean的访问方式,一般有PROPERTY(getter/setter)、FIELD,PUBLIC_MEMBER(public getter/setter,fileds)、NONE可用于包,顶层类。若用于包表示该包下所有的类都照此处理,顶层类也即如果该类有其他的实体也将照此处理
默认为@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
指定序列化javabean的顺序
@XmlElement
@XmlElement 注释可以与以下程序元素一起使用: JavaBean 属性 ,非 static、非 transient 字段 ,XmlElements 中的程序元素
@XmlElement(name = "firstName")
private String name;
private int age;
如果顶层类中标志了访问类型,如Filed。那么各个fileds的名称会被处理为xml中的节点,若按照上面的标注,此时节点名会是firstName
<firstName>nico</firstName>
<age>20</age>
@XmlTransient
@XmlTransient 注释对于解决 JavaBean 属性名称与字段名称之间的名称冲突,或者用于防止字段/属性的映射。
@XmlTransient
private String lastName;
则lastName不会被映射
@XmlList
@XmlList 来将属性映射到列表简单类型。比较两种序列方式:
List<String> data;
<foo><data>aaaa</data><data>bbbb</data></foo>
@XmlList
List<String> data;
<foo><data>aaaa bbbb</data></foo>
@XmlJavaTypeAdapter(class)
用来描述自定义的adapter,需要继承XmlAdapter,用来对自定义序列化的格式。如我们对时间的格式化输出
@XmlValue
支持将类映射到带有 simpleContent 的 XML 模式复杂类型或 XML 模式简单类型。 简单说就是可以指定格式
<msg name="name">robin</msg>
下面是一个Person的javabean,包含了一系列的声明:
@XmlRootElement(name = "per")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
public class Person {
@XmlElement(name = "firstName")
private String name;
@XmlTransient
private String lastName;
@XmlJavaTypeAdapter(value = DateXmlAdapter.class)
private Date birthDay;
@XmlList
private List<String> lang;
private List<KeyValue> msg;
//getter/setter
}
其中DateXmlAdapter如下:
public class DateXmlAdapter extends XmlAdapter<String, Date> {
@Override
public String marshal(Date v) throws Exception {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
return format.format(v);
}
@Override
public Date unmarshal(String v) throws Exception {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
return format.parse(v);
}
}
KeyValue:
@XmlAccessorType(XmlAccessType.FIELD)
public class KeyValue {
@XmlAttribute
private String name;
@XmlValue
private String value;
序列化结果为:
Person p = new Person();
p.setName("robin");
p.setLastName("yang");
p.setBirthDay(new Date());
List<String> lang = Arrays.asList(new String[] { "java", "javascript", "python" });
p.setLang(lang);
List<KeyValue> msg = new ArrayList<KeyValue>();
msg.add(new KeyValue("aa", "aaa-value"));
msg.add(new KeyValue("bbb", "bbb-value"));
p.setMsg(msg);
<per>
<birthDay>2012-11-17</birthDay>
<lang>java javascript python</lang>
<msg name="aa">aaa-value</msg>
<msg name="bbb">bbb-value</msg>
<firstName>robin</firstName>
</per>
3、JAX-WS传递Map
前面在说到可以传递复杂对象时并没有指定Map,是因为并不支持原生的Map传递。如果需要传递我们需要做一个简单的包装,同时需要利用到上面说的XmlJavaTypeAdapter来对bean到xml转换转换。下面的例子是传递Map实例:
@WebService
public interface JaxWsMapService {
@WebMethod
public WrapperMapResult getPersonMap();
}
WrapperMapResult 只是对Map的一个简单封装:
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class WrapperMapResult {
private String message;
private boolean success;
@XmlJavaTypeAdapter(value = MapAdapter.class)
private Map<String, Person> map;
其中最重要的是MapAdapter:
public class MapAdapter extends XmlAdapter<MapConvertor, Map<String, Person>> {
@Override
public Map<String, Person> unmarshal(MapConvertor convertor) throws Exception {
List<MapEntry> entries = convertor.getEntries();
if (entries != null && entries.size() > 0) {
Map<String, Person> map = new HashMap<String, Person>();
for (MapEntry mapEntry : entries) {
map.put(mapEntry.getKey(), mapEntry.getValue());
}
return map;
}
return null;
}
@Override
public MapConvertor marshal(Map<String, Person> map) throws Exception {
MapConvertor convertor = new MapConvertor();
for (Map.Entry<String, Person> entry : map.entrySet()) {
convertor.addEntry(new MapConvertor.MapEntry(entry));
}
return convertor;
}
}
这里声明了MapConvertor用来解析Map<String, Person>
@XmlType(name="MapConvertor")
@XmlAccessorType(XmlAccessType.FIELD)
public class MapConvertor {
private List<MapEntry> entries = new ArrayList<MapConvertor.MapEntry>();
public void addEntry(MapEntry entry) {
entries.add(entry);
}
public List<MapEntry> getEntries() {
return entries;
}
//结构依赖于需要Conver的Map,比如这里Map<String, Person>
public static class MapEntry {
private String key;
private Person value;
public MapEntry() {
}
public MapEntry(String key, Person person) {
this.key = key;
this.value = person;
}
public MapEntry(Map.Entry<String, Person> entry) {
this.key = entry.getKey();
this.value = entry.getValue();
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Person getValue() {
return value;
}
public void setValue(Person value) {
this.value = value;
}
}
}
其他的步骤按照wsimport生产客户端代码调用即可,这样就完成了JAX-WS中map的传递
分享到:
相关推荐
Apache CXF入门范例以及对传递ListMap类型的疑惑】中,可能会详细解释如何创建和调用一个使用CXF的Web服务,同时也可能讨论了在处理复杂数据类型如List<Map, Object>>时遇到的问题和解决方案。通常,CXF允许你通过...
- **更强大更简单的 JAX-WS**:提供了更高级别的 Web 服务支持。 #### 八、JDK 1.7 新特性 - **switch 中使用字符串**:允许在 switch 语句中使用字符串。 - **泛型实例化类型自动推断**:简化了泛型的使用。 - **...
基于Maxwell设计的经典280W 4025RPM高效率科尔摩根12极39槽TBM无框力矩电机:生产与学习双重应用案例,基于Maxwell设计的经典280W高转速科尔摩根TBM无框力矩电机:7615系列案例解析与应用实践,基于maxwwell设计的经典280W,4025RPM 内转子 科尔摩根 12极39槽 TBM无框力矩电机,7615系列。 该案例可用于生产,或者学习用,(157) ,maxwell设计; 280W; 4025RPM内转子; 科尔摩根; 12极39槽TBM无框力矩电机; 7615系列; 生产/学习用。,基于Maxwell设计,高功率280W 12极39槽TBM无框力矩电机:生产与学习双用途案例
基于碳交易的微网优化模型的Matlab设计与实现策略分析,基于碳交易的微网优化模型的Matlab设计与实现探讨,考虑碳交易的微网优化模型matlab ,考虑碳交易; 微网优化模型; MATLAB;,基于Matlab的碳交易微网优化模型研究
二级2025模拟试题(答案版)
OpenCV是一个功能强大的计算机视觉库,它提供了多种工具和算法来处理图像和视频数据。在C++中,OpenCV可以用于实现基础的人脸识别功能,包括从摄像头、图片和视频中识别人脸,以及通过PCA(主成分分析)提取图像轮廓。以下是对本资源大体的介绍: 1. 从摄像头中识别人脸:通过使用OpenCV的Haar特征分类器,我们可以实时从摄像头捕获的视频流中检测人脸。这个过程涉及到将视频帧转换为灰度图像,然后使用预训练的Haar级联分类器来识别人脸区域。 2. 从视频中识别出所有人脸和人眼:在视频流中,除了检测人脸,我们还可以进一步识别人眼。这通常涉及到使用额外的Haar级联分类器来定位人眼区域,从而实现对人脸特征的更细致分析。 3. 从图片中检测出人脸:对于静态图片,OpenCV同样能够检测人脸。通过加载图片,转换为灰度图,然后应用Haar级联分类器,我们可以在图片中标记出人脸的位置。 4. PCA提取图像轮廓:PCA是一种统计方法,用于分析和解释数据中的模式。在图像处理中,PCA可以用来提取图像的主要轮廓特征,这对于人脸识别技术中的面部特征提取尤
麻雀搜索算法(SSA)自适应t分布改进版:卓越性能与优化代码注释,适合深度学习。,自适应t分布改进麻雀搜索算法(TSSA)——卓越的学习样本,优化效果出众,麻雀搜索算法(SSA)改进——采用自适应t分布改进麻雀位置(TSSA),优化后明显要优于基础SSA(代码基本每一步都有注释,代码质量极高,非常适合学习) ,TSSA(自适应t分布麻雀位置算法);注释详尽;高质量代码;适合学习;算法改进结果优异;TSSA相比基础SSA。,自适应T分布优化麻雀搜索算法:代码详解与学习首选(TSSA改进版)
锂电池主动均衡Simulink仿真研究:多种均衡策略与电路架构的深度探讨,锂电池主动均衡与多种均衡策略的Simulink仿真研究:buckboost拓扑及多层次电路分析,锂电池主动均衡simulink仿真 四节电池 基于buckboost(升降压)拓扑 (还有传统电感均衡+开关电容均衡+双向反激均衡+双层准谐振均衡+环形均衡器+cuk+耦合电感)被动均衡电阻式均衡 、分层架构式均衡以及分层式电路均衡,多层次电路,充放电。 ,核心关键词: 锂电池; 主动均衡; Simulink仿真; 四节电池; BuckBoost拓扑; 传统电感均衡; 开关电容均衡; 双向反激均衡; 双层准谐振均衡; 环形均衡器; CUK均衡; 耦合电感均衡; 被动均衡; 电阻式均衡; 分层架构式均衡; 多层次电路; 充放电。,锂电池均衡策略研究:Simulink仿真下的多拓扑主动与被动均衡技术
S7-1500和分布式外围系统ET200MP模块数据
内置式永磁同步电机无位置传感器模型:基于滑膜观测器和MTPA技术的深度探究,内置式永磁同步电机基于滑膜观测器和MTPA的无位置传感器模型研究,基于滑膜观测器和MTPA的内置式永磁同步电机无位置传感器模型 ,基于滑膜观测器;MTPA;内置式永磁同步电机;无位置传感器模型,基于滑膜观测与MTPA算法的永磁同步电机无位置传感器模型
centos7操作系统下安装docker,及docker常用命令、在docker中运行nginx示例,包括 1.设置yum的仓库 2.安装 Docker Engine-Community 3.docker使用 4.查看docker进程是否启动成功 5.docker常用命令及nginx示例 6.常见问题
给曙光服务器安装windows2012r2时候找不到磁盘,问厂家工程师要的raid卡驱动,内含主流大多数品牌raid卡驱动
数学建模相关主题资源2
西门子四轴卧式加工中心后处理系统:828D至840D支持,四轴联动制造解决方案,图档处理与试看程序一应俱全。,西门子四轴卧加后处理系统:支持828D至840D系统,四轴联动高精度制造解决方案,西门子四轴卧加后处理,支持828D~840D系统,支持四轴联动,可制制,看清楚联系,可提供图档处理试看程序 ,核心关键词:西门子四轴卧加后处理; 828D~840D系统支持; 四轴联动; 制程; 联系; 图档处理试看程序。,西门子四轴卧加后处理程序,支持多种系统与四轴联动
MATLAB下基于列约束生成法CCG的两阶段鲁棒优化问题求解入门指南:算法验证与经典文献参考,MATLAB下基于列约束生成法CCG的两阶段鲁棒优化问题求解入门指南:算法验证与文献参考,MATLAB代码:基于列约束生成法CCG的两阶段问题求解 关键词:两阶段鲁棒 列约束生成法 CCG算法 参考文档:《Solving two-stage robust optimization problems using a column-and-constraint generation method》 仿真平台:MATLAB YALMIP+CPLEX 主要内容:代码构建了两阶段鲁棒优化模型,并用文档中的相对简单的算例,进行CCG算法的验证,此篇文献是CCG算法或者列约束生成算法的入门级文献,其经典程度不言而喻,几乎每个搞CCG的两阶段鲁棒的人都绕不过此篇文献 ,两阶段鲁棒;列约束生成法;CCG算法;MATLAB;YALMIP+CPLEX;入门级文献。,MATLAB代码实现:基于两阶段鲁棒与列约束生成法CCG的算法验证研究
“生热研究的全面解读:探究参数已配置的Comsol模型中的18650圆柱锂电池表现”,探究已配置参数的COMSOL模型下的锂电池生热现象:18650圆柱锂电池模拟分析,出一个18650圆柱锂电池comsol模型 参数已配置,生热研究 ,出模型; 18650圆柱锂电池; comsol模型; 参数配置; 生热研究,构建18650电池的COMSOL热研究模型
移动端多端运行的知识付费管理系统源码,TP6+Layui+MySQL后端支持,功能丰富,涵盖直播、点播、管理全功能及礼物互动,基于UniApp跨平台开发的移动端知识付费管理系统源码:多端互通、全功能齐备、后端采用TP6与PHP及Layui前端,搭载MySQL数据库与直播、点播、管理、礼物等功能的强大整合。,知识付费管理系统源码,移动端uniApp开发,app h5 小程序一套代码多端运行,后端php(tp6)+layui+MySQL,功能齐全,直播,点播,管理,礼物等等功能应有尽有 ,知识付费;管理系统源码;移动端uniApp开发;多端运行;后端php(tp6);layui;MySQL;直播点播;管理功能;礼物功能,知识付费管理平台:全功能多端运行系统源码(PHP+Layui+MySQL)
基于Python+Django+MySQL的个性化图书推荐系统:协同过滤推荐,智能部署,用户定制功能,基于Python+Django+MySQL的个性化图书推荐系统:协同过滤推荐,智能部署,用户定制功能,Python+Django+Mysql个性化图书推荐系统 图书在线推荐系统 基于用户、项目、内容的协同过滤推荐算法。 帮远程安装部署 一、项目简介 1、开发工具和实现技术 Python3.8,Django4,mysql8,navicat数据库管理工具,html页面,javascript脚本,jquery脚本,bootstrap前端框架,layer弹窗组件、webuploader文件上传组件等。 2、项目功能 前台用户包含:注册、登录、注销、浏览图书、搜索图书、信息修改、密码修改、兴趣喜好标签、图书评分、图书收藏、图书评论、热点推荐、个性化推荐图书等功能; 后台管理员包含:用户管理、图书管理、图书类型管理、评分管理、收藏管理、评论管理、兴趣喜好标签管理、权限管理等。 个性化推荐功能: 无论是否登录,在前台首页展示热点推荐(根据图书被收藏数量降序推荐)。 登录用户,在前台首页展示个性化推荐
STM32企业级锅炉控制器源码分享:真实项目经验,带注释完整源码助你快速掌握实战经验,STM32企业级锅炉控制器源码:真实项目经验,完整注释,助力初学者快速上手,stm32真实企业项目源码 项目要求与网上搜的那些开发板的例程完全不在一个级别,也不是那些凑合性质的项目可以比拟的。 项目是企业级产品的要求开发的,能够让初学者了解真实的企业项目是怎么样的,增加工作经验 企业真实项目网上稀缺,完整源码带注释,适合没有参与工作或者刚学stm32的增加工作经验, 这是一个锅炉的控制器,有流程图和程序协议的介绍。 ,stm32源码;企业级项目;工作经验;锅炉控制器;流程图;程序协议,基于STM32的真实企业级锅炉控制器项目源码
整车性能目标书:涵盖燃油车、混动车及纯电动车型的十六个性能模块目标定义模板与集成开发指南,整车性能目标书:涵盖燃油车、混动车及纯电动车型的十六个性能模块目标定义模板与集成开发指南,整车性能目标书,汽车性能目标书,十六个性能模块目标定义模板,包含燃油车、混动车型及纯电动车型。 对于整车性能的集成开发具有较高的参考价值 ,整车性能目标书;汽车性能目标书;性能模块目标定义模板;燃油车;混动车型;纯电动车型;集成开发;参考价值,《汽车性能模块化目标书:燃油车、混动车及纯电动车的集成开发参考》