JAVA IO——对象序列化解析及项目实战

       对象一经创建,如果程序需要就一直存在,直到程序终止。java的对象序列化将那些实现了Sserializable接口的对象转换成一个字节序列,并能通过该序列还原出原来的对象,且跨平台。也就是说,从Windows上序列化一个对象到Linux上反序列化,仍能准确获得该对象。

       对象序列化加入到java中主要为了支持两种特性:远程方法调用RMI和JavaBean,。调用远程的对象就像调用本机的一样,当向远程对象发送消息是,需要通过对象序列化来传输参数和返回值。其次JavaBean在使用时需要保存bean状态信息,以便后期恢复,保存Bean信息也通过对象序列化实现。

      在java IO包中创建了序列化接口Serializable,与IO相关的序列化实现都源自于该接口。

一、最原始的对象序列化过程: 

      这里是对一个Worm对象,使用对象IO流进行初始化,调用writeObject方法将对象序列化成字节打印,进行读取。

public class Worm implements Serializable {
	private static Random ran=new Random(47);
	private DATA[] d={
			new DATA(ran.nextInt(10)),
			new DATA(ran.nextInt(10)),
			new DATA(ran.nextInt(10))
	};
	private Worm next;
	private char c;

	public Worm(int i,char x) {
		System.out.println("worn 构造器:"+i);
		c=x;
		if(--i>0)
		{
			next=new Worm(i, (char)(x+1));
		}
	}
	public Worm()
	{
		System.out.println("default 构造器");
	}

	public String toString() {
		StringBuilder result=new StringBuilder(":"); //组织输出结果
		result.append(c);
		result.append("(");
		for (DATA data : d)
			result.append(data);
		result.append(")");
			
		if(next!=null)
			result.append(next);
		return result.toString() ;
	}
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		Worm w=new Worm(6,'a');
		System.out.println("w="+w);
		ObjectOutputStream out=new ObjectOutputStream(
				new FileOutputStream("Worm.out"));
		out.writeObject( "Worm store\n");   //writeObject方法,开始将对象序列化成字节
		out.writeObject(w);
		out.close();
		
		ObjectInputStream in=new ObjectInputStream(
				new FileInputStream("Worm.out"));
		String s=(String)in.readObject();
		Worm w2=(Worm)in.readObject();
		System.out.println(s+"w2="+w2);
	}
输出:

worn 构造器:2    worn 构造器:1

w=:a(853):b(119):c(802):d(788):e(199):f(881)

Worm store

w2=:a(853):b(119):c(802):d(788):e(199):f(881)

二、java web 对象序列化

       除了java底层使用序列化进行对象状态的保存和其他特性的支持之外,对于java web 项目而言,页面间传值也大多将对象序列化之后传输,这样的好处主要是序列化之后方便与JS结合获值赋值,同时传输序列化对象一般都比传普通更高效。但java web中的应用一般很少调用底层方法实现,而是通过第三方提供的jar,例如flexjson.jar/jackson等序列化工具包实现对象序列化。(引入jackson-core-asl-1.9.13.jar、jackson-mapper-asl-1.9.13.jar)

public class JacksonStream{
	public static void main(String[] args) throws IOException {
		try {
			JsonFactory jfactory = new JsonFactory();

			/*
			 *将json文件写入本地 
			 */
			JsonGenerator jGenerator = jfactory.createJsonGenerator(new File(
					"c:\\user.json"), JsonEncoding.UTF8);
			jGenerator.writeStartObject(); // {

			jGenerator.writeStringField("name", "mkyong"); // "name" : "mkyong"
			jGenerator.writeNumberField("age", 29); // 文件类型

			jGenerator.writeFieldName("messages"); // "messages" :
			jGenerator.writeStartArray(); // [ 数组类型

			jGenerator.writeString("msg 1"); // "msg 1"
			jGenerator.writeString("msg 2"); // "msg 2"
			jGenerator.writeString("msg 3"); // "msg 3"
			jGenerator.writeEndArray(); // ]
			jGenerator.writeEndObject(); // }

			jGenerator.close();

		} catch (JsonGenerationException e) {
			e.printStackTrace();
		}
	}
}

输出:{"name":"mkyong","age":29,"messages":["msg 1","msg 2","msg 3"]}

解析json:

public class JacksonStreamExample {
   public static void main(String[] args) { 
     try { 
	JsonFactory jfactory = new JsonFactory(); 
	/**读取json文件**/
	JsonParser jParser = jfactory.createJsonParser(new File("c:\\user.json"));
 
	while (jParser.nextToken() != JsonToken.END_OBJECT) { 
		String fieldname = jParser.getCurrentName();
		if ("name".equals(fieldname)) {		  
                  //当前结点为name 
		  jParser.nextToken();
		  System.out.println(jParser.getText()); // 输出 mkyong 
		}
 
		if ("age".equals(fieldname)) { 
		  // 当前结点为age 
                  // move to next, which is "name"'s value
		  jParser.nextToken();
		  System.out.println(jParser.getIntValue()); // display 29 
		} 
		if ("messages".equals(fieldname)) {
 		  jParser.nextToken(); 
		  while (jParser.nextToken() != JsonToken.END_ARRAY) { 
                     // display msg1, msg2, msg3
		     System.out.println(jParser.getText()); 
 		  } 
		}
	  }
	  jParser.close(); 
     } catch (JsonGenerationException e) { 
	  e.printStackTrace(); 
     }

另外,除了将对象序列化成json字符串,还可以序列化成字节(如一)、XML文件(详见序列化和反序列化)和其他文件格式,具体选择根据业务跟在哪层进行数据传输相关。

三、ITOO 项目序列化应用

      在ITOO中序列化也是采用上述jackon jar ,将对象序列化成json字符串。下面是封装的工具类。

public class JacksonJsonUntil {

	// 定义日志工具
	private static final Logger logger = Logger
			.getLogger(JacksonJsonUntil.class);
	public JsonGenerator jsonGenerator = null;
	public ObjectMapper objectMapper = null;

	/**
	 * 将对象转换为json字符串
	 * 
	 * @param response
	 *            向前台传递数据时的格式
	 * @param obj
	 *            需要转换的对象(可以为list)
	 * @throws Exception
	 *             异常处理
	 */
	public void beanToJson(HttpServletResponse response, Object obj) {
		response.setContentType("application/json;charset=UTF-8");
		objectMapper = new ObjectMapper();
		try {
			String json = objectMapper.writeValueAsString(obj);
			PrintWriter out = response.getWriter();
			out.write(json);
		} catch (Exception e) {
			logger.error("对象转Json失败!!!");
			e.printStackTrace();
		}
	}

	/**
	 * 将对象转换为json字符串(专门用于json跨域问题)
	 * 
	 * @param response
	 *            向前台传递数据时的格式
	 * @param obj
	 *            需要转换的对象(可以为list)
	 * @throws Exception
	 *             异常处理
	 */
	public void beanToUrlJson(HttpServletRequest request,
			HttpServletResponse response, Object obj) {
		response.setContentType("text/plain");
		objectMapper = new ObjectMapper();
		String callbackFunName = request.getParameter("callbackparam");// 得到js函数名称
		try {
			String json = objectMapper.writeValueAsString(obj);
			PrintWriter out = response.getWriter();
			out.write(callbackFunName + "(" + json + ")");
			logger.info("对象转Json(专用于解决json跨域问题):" + callbackFunName + "("
					+ json + ")");
		} catch (IOException e) {
			logger.error("对象转Json失败!!!");
			e.printStackTrace();
		}
	}
}
    抽丝剥茧,里头的内容一点点付出水面。

你可能感兴趣的:(JAVA IO——对象序列化解析及项目实战)