xml和javaBean实现互转

最近遇到了调用接口需要xml报文传递,用传统最简单的方式就是我们string手动拼接报文传递,这样调用问题解决了,返回的数据问题没有得到解决,因为返回的也是xml报文,需要对其做一些转换操作,既然转换,直接在传递时通过简单的方式将报文序列化为指定编码格式的xml,然后返回时再互转就可以,这样第一代码结构清晰,第二这种行为看起来貌似也比较优雅。

我有看过利用dom4j和实现xml和json之间的转换,最终执行时,采用注解+实体的方式来实现效果比较乐观点。

pom依赖:

        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>

 建立对应的实体,这个实体需要和对应的xml来映射。由于我们可能会用到同一个请求头,所以可以吧请求头作为一个公共的实体,其他对应实体继承父类就好,比如有如下报文:

<?xml version="1.0" encoding="GB2312" standalone="yes" ?> 
<TX> 
  <REQUEST_SN></REQUEST_SN> 
  <CUST_ID></CUST_ID> 
  <USER_ID></USER_ID> 
  <PASSWORD></PASSWORD> 
  <TX_CODE></TX_CODE> 
  <LANGUAGE></LANGUAGE> 
  <TX_INFO> 
  </TX_INFO> 
</TX 

其父类:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(propOrder = { "requestSn","custId", "userId", "password","txCode","language" })
public class RequestHeaderBean{

	@XmlElement(name = "REQUEST_SN", required = true)
	private String requestSn;
	@XmlElement(name = "CUST_ID", required = true)
	private String custId;
	@XmlElement(name = "USER_ID", required = true)
	private String userId;
	@XmlElement(name = "PASSWORD", required = true)
	private String password;
	@XmlElement(name = "TX_CODE", required = true)
	private String txCode;
	@XmlElement(name = "LANGUAGE", required = true)
	private String language;
	
	//get set略
}

 这里说明一下,父类是根据众多xml提取出来的,此例只是用来做个简单样例,这里会用到几个注解,简单介绍几个:

XmlAccessorType  
默认规则: 
默认情况下,如果包中不存在 @XmlAccessorType,那么假定使用以下包级别注释。 
@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) 
默认情况下,如果类中不存在 @XmlAccessorType,并且没有任何超类是使用 @XmlAccessorType 注释的,则假定在类中使用以下默认注释: 
@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) 
可能值: 
FIELD:    JAXB 绑定类中的每个非静态、非瞬态字段将会自动绑定到 XML,除非由 XmlTransient 注释。 
NONE:     所有字段或属性都不能绑定到 XML,除非使用一些 JAXB 注释专门对它们进行注释。 
PROPERTY: JAXB 绑定类中的每个获取方法/设置方法对将会自动绑定到 XML,除非由 XmlTransient 注释。 
PUBLIC_MEMBER:每个公共获取方法/设置方法对和每个公共字段将会自动绑定到 XML,除非由 XmlTransient 注释。

@XmlRootElement:根节点

@XmlElement:该属性作为xml的element,且可以增加属性(name="NewElementName"),那么生成的xml串的elment的标签是NewElementName

@XmlType:该注解通过属性propOrder来设置文件各个属性的输出属性,值为bean的属性值。

看子类

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="TX")
public class RequestSelectCode extends RequestHeaderBean implements Serializable {

    @XmlElement(name = "TX_INFO" , required = false)
    private String txInfo;

   
    //get set 略
}

这里需要注意的是,@XmlRootElement,只在子类中声明就可以了,父类中不需要声明,否则在xml转对应实体时会有异常,说白了,就是此注解在一个报文组成中只能出现一次。

然后就上一个xml和实体互转的工具类

public class JaxbUtil {

	/**
	 * JavaBean转换成xml
	 * 
	 * @param obj
	 * @param encoding
	 * @return
	 */
	public static String convertToXml(Object obj, String encoding) {
		String result = null;
		try {
			JAXBContext context = JAXBContext.newInstance(obj.getClass());
			Marshaller marshaller = context.createMarshaller();
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);

			StringWriter writer = new StringWriter();
			marshaller.marshal(obj, writer);
			result = writer.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return result;
	}

	/**
	 * xml转换成JavaBean
	 * 
	 * @param xml
	 * @param c
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T converyToJavaBean(String xml, Class<T> c) {
		T t = null;
		try {
			JAXBContext context = JAXBContext.newInstance(c);
			Unmarshaller unmarshaller = context.createUnmarshaller();
			t = (T) unmarshaller.unmarshal(new StringReader(xml));
		} catch (Exception e) {
			e.printStackTrace();
		}

		return t;
	}
}

2019-07-25更新:

说一下这个java实体的定义,这个东东定义起来,如果xml比较简短,敲一下也就敲一下了,如果xml的嵌套关系比较多,比较复杂的时候,我们要怎么办?还傻乎乎那么写吗?当然可以,但效率也太低了好吧,今天记录一下如何根据已有xml生成java实体类。

也比较简单,首先,你需要将xml转换为xsd文件,这个转换有在在线地址:

Free Online XSD/XML Schema Generator - FreeFormatter.com

在你转换完之后,copy到一个.xsd的文件内就可以,然后在当前文件下,使用cmd进入,按以下命令行执行文件就可以:

xjc  –d  java 类的存放路径  –p  类的包名  xsd文件名

示例:

xjc -encoding UTF-8 test.xsd

// 附xjc命令介绍:
  -nv                :  不对输入模式执行严格验证
  -extension         :  允许供应商扩展 - 不严格遵循
                        JAXB 规范中的兼容性规则和应用程序 E.2
  -b <file/dir>      :  指定外部绑定文件 (每个 <file> 必须具有自己的 -b)
                        如果指定目录, 则将搜索 **/*.xjb
  -d <dir>           :  生成的文件将放入此目录中
  -p <pkg>           :  指定目标程序包
  -httpproxy <proxy> :  设置 HTTP/HTTPS 代理。格式为 [user[:password]@]proxyHost:proxyPort
  -httpproxyfile <f> :  作用与 -httpproxy 类似, 但在文件中采用参数来保护口令
  -classpath <arg>   :  指定查找用户类文件的位置
  -catalog <file>    :  指定用于解析外部实体引用的目录文件
                        支持 TR9401, XCatalog 和 OASIS XML 目录格式。
  -readOnly          :  生成的文件将处于只读模式
  -npa               :  禁止生成程序包级别注释 (**/package-info.java)
  -no-header         :  禁止生成带有时间戳的文件头
  -target (2.0|2.1)  :  行为与 XJC 2.0 或 2.1 类似, 用于生成不使用任何 2.2 功能的代码。
  -encoding <encoding> :  为生成的源文件指定字符编码
  -enableIntrospection :  用于正确生成布尔型 getter/setter 以启用 Bean 自测 apis
  -contentForWildcard  :  为具有多个 xs:any 派生元素的类型生成内容属性
  -xmlschema         :  采用 W3C XML 模式处理输入 (默认值)
  -relaxng           :  采用 RELAX NG 处理输入 (实验性的, 不支持)
  -relaxng-compact   :  采用 RELAX NG 简洁语法处理输入 (实验性的, 不支持)
  -dtd               :  采用 XML DTD 处理输入 (实验性的, 不支持)
  -wsdl              :  采用 WSDL 处理输入并编译其中的模式 (实验性的, 不支持)
  -verbose           :  特别详细
  -quiet             :  隐藏编译器输出
  -help              :  显示此帮助消息
  -version           :  显示版本信息
  -fullversion       :  显示完整的版本信息


扩展:
  -Xinject-code      :  inject specified Java code fragments into the generated code
  -Xlocator          :  enable source location support for generated code
  -Xsync-methods     :  generate accessor methods with the 'synchronized' keyword
  -mark-generated    :  mark the generated code as @javax.annotation.Generated
  -episode <FILE>    :  generate the episode file for separate compilation
  -Xpropertyaccessors :  Use XmlAccessType PROPERTY instead of FIELD for generated classes

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值