`
yuelong
  • 浏览: 33088 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

xml文件流与javabean之间的通用转换(上)

    博客分类:
  • Java
阅读更多

最近在做通讯方面的一些东西,移动端与服务器之间的通讯采用HttpUrlConnection以xml文件流的方式进行通讯。xml文件解析后,通常要给对应的数据模型(javabean)赋值,从而进行一些列的验证,入库,日志操作等。

 

1、通过HttpUrlConnection获取输入流,解码后生成xml文件字符串

2、使用dom4j解析此字符串生成Document对象

3、对Document对象递归遍历收集节点名称和节点值,并根据节点名称拼接set方法,用以和javabean反射后得到的set方法做匹配

 

具体代码如下:

 

1、模拟客户端发送xml数据流至服务器 Client.java

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.net.URLDecoder;

public class Client {
	
	private static final String POST = "http://localhost:8080/mobileCharge/charge/chargeAction!getMpay.action";
	
	public static void main(String[] args){
		sendXml();
	}
	
	public static String createXml() {
		String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<mpay>"
				+ "<methodName>getMpay</methodName>" + "<params>" + "<param>"
				+ "<type>1</type>" + "<terminalid>91300021</terminalid>"
				+ "<money>100.00</money>" + "<csn>02570001</csn>"
				+ "<password>1f3259007db02194cd134f18513dd00e</password>"
				+ "</param>" + "</params>" + "</mpay>";
		return xml;
	}
	
	
	public static void sendXml(){
		try {
			URL url = new URL(POST);
			//根据Url地址打开一个连接
			URLConnection urlConnection = url.openConnection();
			HttpURLConnection httpUrlConnection = (HttpURLConnection)urlConnection;
			//允许输出流
			httpUrlConnection.setDoOutput(true);
			//允许写入流
			httpUrlConnection.setDoInput(true);
			//post方式提交不可以使用缓存
			httpUrlConnection.setUseCaches(false);
			//请求类型
			httpUrlConnection.setRequestProperty("Content-Type", "text/html");
			httpUrlConnection.setRequestMethod("POST");
			//设置连接、读取超时
			httpUrlConnection.setConnectTimeout(30000);
			httpUrlConnection.setReadTimeout(30000);
			httpUrlConnection.connect();
			//使用缓冲流将xml字符串发送给服务器
			BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(httpUrlConnection.getOutputStream()));
			writer.write(URLEncoder.encode(createXml(),"UTF-8"));
			writer.flush();
			writer.close();
			writer = null;
			//关闭连接
			httpUrlConnection.disconnect();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

 

2、服务端获取到此输入流后转换为字符串,这个很简单,贴出主要代码即可

public String getXmlText(){
		//使用的是struts2 ,获取request很方便 O(∩_∩)O~
		HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(StrutsStatics.HTTP_REQUEST);
		String xmlText=null;
		try{
			//同样使用缓冲流
			BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
			StringBuffer sb = new StringBuffer();
			String lines;
			while((lines = reader.readLine())!=null){
				sb.append(lines);
			}
			//客户端使用了UTF-8编码,这里使用同样使用UTF-8解码
			xmlText = URLDecoder.decode(sb.toString(),"UTF-8");
			reader.close();
			reader = null;
		}catch(Exception e){
			e.printStackTrace();
		}
		return xmlText;
		
	}

 

 一下就是xmlText与javabean之间的转换了,今天只写了上部分 xml - javabean  改天再写下部分 javabean - xml

 

3、xmlText -  javabean 的转换

 

/**
	 * 根据xml文件流对xmlModel赋值
	 * @param xmlText
	 * @param xmlModel
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static synchronized Object parseXml4Bean(String xmlText,Object xmlModel){
		try {
			//解析字符串生成docment对象
			Document xmlDoc = DocumentHelper.parseText(xmlText);
			//获取根节点
			Element element = xmlDoc.getRootElement();
			List<Map<String,String>> propsList = new ArrayList<Map<String,String>>();
			//解析xml中的节点名称和节点值,详细见下面parseXml
			propsList = parseXml(element, propsList);
			if(propsList.size()==0){
				return null;
			}
			//获取Method对象数组
			Method[] methods = xmlModel.getClass().getDeclaredMethods();
			for(int i=0;i<propsList.size();i++){
				for(int j=0;j<methods.length;j++){
					Method m = methods[j];
					if(propsList.get(i).containsKey(m.getName())){
						try {
							//执行set方法,将xml中的textNode值赋予Model中
							m.invoke(xmlModel, new Object[]{propsList.get(i).get(m.getName())});
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
			}
			
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		return xmlModel;
	}

 

 4、子方法 ,用以解析xml,拼接set方法匹配与Method数组

/**
	 * 获取xml文件中叶结点名称和节点值
	 * @param element
	 * @param propsList
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private static List<Map<String,String>> parseXml(Element element,List<Map<String,String>> propsList){
		if(element.isTextOnly()){
			HashMap<String,String> map = new HashMap<String,String>();
			String key = element.getName();
			key = METHOD_SET+key.substring(0,1).toUpperCase().concat(key.substring(1,key.length()));
			map.put(key,element.getTextTrim());
			propsList.add(map);
		}else{
			List<Element> tmpList = element.elements();
			for(Element e : tmpList){
				parseXml(e, propsList);
			}
		}
		return propsList;
	}

 

 

 5、java bean

package com.eptok.business.charge;

public class ChargeXmlModel {
	private String methodName;
	private String type;
	private String terminalid;
	private String money;
	private String csn;
	private String password;

	public String getMethodName() {
		return methodName;
	}

	public void setMethodName(String methodName) {
		this.methodName = methodName;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getTerminalid() {
		return terminalid;
	}

	public void setTerminalid(String terminalid) {
		this.terminalid = terminalid;
	}

	public String getMoney() {
		return money;
	}

	public void setMoney(String money) {
		this.money = money;
	}

	public String getCsn() {
		return csn;
	}

	public void setCsn(String csn) {
		this.csn = csn;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
}

 

6、测试调用   。。。。

 附件中有dom4j的jar ,可以下载

7
0
分享到:
评论
7 楼 zhuxinyu 2011-09-28  
我还想到了castor,也是非常给力的东西。
6 楼 yuelong 2011-09-26  
macrotea 写道
当看到这个标题的时候,我就想到jax

嗯。 要改!
5 楼 macrotea 2011-09-25  
当看到这个标题的时候,我就想到jax
4 楼 yuelong 2011-09-25  
myten 写道
新版本已经不繁琐了。我贴代码给你?
出错了的话给我留言



好的,有空我试一下
3 楼 myten 2011-09-23  
新版本已经不繁琐了。我贴代码给你?
package main;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import demo.model.Person;

public class Main {

	/**
	 * @param args
	 * @throws JAXBException 
	 * @throws FileNotFoundException 
	 */
	public static void main(String[] args) throws JAXBException, FileNotFoundException {
		JAXBContext ctx=JAXBContext.newInstance(Person.class);
		toXML(ctx);
		fromXML(ctx);
		
	}
	public static void toXML(JAXBContext ctx) throws JAXBException, FileNotFoundException{
		Marshaller ms=ctx.createMarshaller();
		FileOutputStream fo=new FileOutputStream(new File("src/Person.xml"));
		Person p=new Person();
		//"Jack","12";
		p.age="ss";
		ms.marshal(p, fo);
	}
	public static void fromXML(JAXBContext ctx) throws FileNotFoundException, JAXBException{
		FileReader fo=new FileReader(new File("src/Person.xml"));
		Unmarshaller ums= ctx.createUnmarshaller();
		Person p=(Person) ums.unmarshal(fo);
		System.out.println(p.username);
	}

}



package demo.model;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Person {
	
	public Person() {
		super();
	}
	public Person(String username, String age) {
		super();
		this.username = username;
		this.age = age;
	}
	@XmlAttribute
	public String username;
	public String age;
	
}


出错了的话给我留言
2 楼 yuelong 2011-09-23  
@myten
     刚才去了解了一下jaxb ,其使用确实很简单。 但对于xml文件格式要求比较繁琐,与xsd或dtd约束 。
     对于比较牛的服务端来说,可以采用。 像俺这公司,没办法要求对方发送格式化的xml报文,但在jaxb的一个帖子里面,了解了一下xstream,这个似乎可行。
    还是需要再改进一下的。 感谢你
1 楼 myten 2011-09-23  
楼主您辛苦了。如果您是要JavaBean和XMl互转传输,建议你看看JAXB,Java本身就已经支持了,没必要自己拼接字符串自己解析字符串

相关推荐

    excel表格数据转换成javaBean

    通过XML配置文件,把大量的Excel表格数据转换成javaBean对象,具有通用行。使用方法简单,而且可以根据自己需要添加不通配置。

    基于Java的两个通用安全模块的设计与实现.zip

    JSP文件在运行时会被其编译器转换成更原始的Servlet代码。JSP编译器可以把JSP文件编译成用Java代码写的Servlet,然后再由Java编译器来编译成能快速执行的二进制机器码,也可以直接编译成二进制码。

    Java2核心技术.part5

    12.2.3随机存取文件流 12.2.4文本流 12.2.5字符集 12.2.6文本输出 12.2.7文本输入 12.3 ZIP文件流 12.4流的使用 12.4.1分隔符输出 12.4.2字符串记号处理器和带分隔符的文本 12.4.3读取带...

    Java2核心技术.part3

    12.2.3随机存取文件流 12.2.4文本流 12.2.5字符集 12.2.6文本输出 12.2.7文本输入 12.3 ZIP文件流 12.4流的使用 12.4.1分隔符输出 12.4.2字符串记号处理器和带分隔符的文本 12.4.3读取带...

    Java2核心技术.part1

    12.2.3随机存取文件流 12.2.4文本流 12.2.5字符集 12.2.6文本输出 12.2.7文本输入 12.3 ZIP文件流 12.4流的使用 12.4.1分隔符输出 12.4.2字符串记号处理器和带分隔符的文本 12.4.3读取带允隔符的...

    Java2核心技术.part6

    12.2.3随机存取文件流 12.2.4文本流 12.2.5字符集 12.2.6文本输出 12.2.7文本输入 12.3 ZIP文件流 12.4流的使用 12.4.1分隔符输出 12.4.2字符串记号处理器和带分隔符的文本 12.4.3读取带...

    Java2核心技术.part4

    12.2.3随机存取文件流 12.2.4文本流 12.2.5字符集 12.2.6文本输出 12.2.7文本输入 12.3 ZIP文件流 12.4流的使用 12.4.1分隔符输出 12.4.2字符串记号处理器和带分隔符的文本 12.4.3读取带...

    Java2核心技术.part2

    12.2.3随机存取文件流 12.2.4文本流 12.2.5字符集 12.2.6文本输出 12.2.7文本输入 12.3 ZIP文件流 12.4流的使用 12.4.1分隔符输出 12.4.2字符串记号处理器和带分隔符的文本 12.4.3读取带...

    JAVA上百实例源码以及开源项目

     Java数据压缩与传输实例,可以学习一下实例化套按字、得到文件输入流、压缩输入流、文件输出流、实例化缓冲区、写入数据到文件、关闭输入流、关闭套接字关闭输出流、输出错误信息等Java编程小技巧。 Java数组倒置...

    jsp servlet 入门学习资料-新手一看就懂

    5.5 如何将一个普通的JSP文件转换为一个XML 文档 5.6 JSP1.1的DTD文件 第6章 JSP基础实例 6.1 第一个JSP程序—HelloWorld! 6.2 注释的使用 6.3 脚本元素 6.3.1 声明 6.3.2 表达式 6.3.3 脚本代码 6.4 page...

    jsp从入门到高级编程

    5.5 如何将一个普通的JSP文件转换为一个XML 文档 5.6 JSP1.1的DTD文件 第6章 JSP基础实例 6.1 第一个JSP程序—HelloWorld! 6.2 注释的使用 6.3 脚本元素 6.3.1 声明 6.3.2 表达式 6.3.3 脚本代码 6.4 page...

    JSP高级教程

    5.5 如何将一个普通的JSP文件转换为一个XML 文档 5.6 JSP1.1的DTD文件 第6章 JSP基础实例 6.1 第一个JSP程序—HelloWorld! 6.2 注释的使用 6.3 脚本元素 6.3.1 声明 6.3.2 表达式 6.3.3 脚本代码 6.4 page...

    java 面试题 总结

    重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,...

    JAVA上百实例源码以及开源项目源代码

     Java数据压缩与传输实例,可以学习一下实例化套按字、得到文件输入流、压缩输入流、文件输出流、实例化缓冲区、写入数据到文件、关闭输入流、关闭套接字关闭输出流、输出错误信息等Java编程小技巧。 Java数组倒置...

    Android插件

    每个Module 生成的iml 文件,但是我们每次add,commit 都会不小心把它们添加上去,而gitignore 就是解决这种痛点的,如果你不想提交的文件,就可以在创建项目的时候将这个文件中添加即可,将一些通用的东西屏蔽掉。...

    JAVA WEB典型模块与项目实战大全

    20.5 多学两招——其他操作xml文件组件  20.6 小结  第21章 用户维护功能(struts 2.x+ibatis)  21.1 用户维护功能  21.2 关于用户维护基础知识——ibatis框架  21.3 用户维护系统具体实现  21.4 小结...

    JSP高级编程

    5.5 如何将一个普通的JSP文件转换为一个XML 文档 5.6 JSP1.1的DTD文件 第6章 JSP基础实例 6.1 第一个JSP程序—HelloWorld! 6.2 注释的使用 6.3 脚本元素 6.3.1 声明 6.3.2 表达式 6.3.3 脚本代码 ...

    Struts2 in action中文版

    5.4.2 在String和Circle之间转换 102 5.4.3 配置框架使用自定义转换器 103 5.5 小结 106 第三部分 构建视图——标签和结果 第6章 构建视图——标签 108 6.1 入门 108 6.1.1 ActionContext和OGNL 109 6.1.2 虚拟对象...

    Spring.3.x企业应用开发实战(完整版).part2

    1.5.4 通用类型转换系统和属性格式化系统 1.5.5 数据访问层新增OXM功能 1.5.6 Web层的增强 1.5.7 其他 1.6 Spring对Java版本的要求 1.7 如何获取Spring 1.8 小结 第2章 快速入门 2.1 实例功能概述 2.1.1 比Hello ...

Global site tag (gtag.js) - Google Analytics