Servelt處理複雜的json數據(日期)

可能會遇到這樣一個問題,咱們將數據以json字符串的形式傳給頁面的時候,有可能數據格式中包含比較複雜的格式,如:日期,這樣,在頁面中解析json數據的時候,不方便進行處理(也不是不能處理),因此,咱們但願將複雜的格式,以某種簡單的方式傳給頁面。java

1.須要相關的jar包

  1. commons-beanutils-1.8.0.jar
  2. commons-collections-3.2.1.jar
  3. commons-lang-2.4.jar
  4. commons-logging-1.1.1.jar
  5. ezmorph-1.0.6.jar
  6. json-lib-2.2.3-jdk15.jar
  7. 將這些jar包複製到項目中的WEB-INF->lib目錄下

2.不採用任何措施,數據的結果

  1. 新建一個dto,裏面建立一個User類,以用於測試
public class User {
	
	private int id;
	private String name;
	private Date date;

	public User(int id, String name, Date date) {
		super();
		this.id = id;
		this.name = name;
		this.date = date;
	}

在User類中,假設咱們有一個Date類型的日期數據。ajax

  1. 在servlet中,咱們建立幾個uesr對象,而後將數據轉換成json字符串
User u1 = new User(1,"sucan",new Date());
			User u2 = new User(2,"ximi",new Date());
			User u3 = new User(3,"sc",new Date());
			
			List<User> list = new ArrayList<User>();
			list.add(u1);
			list.add(u2);
			list.add(u3);
			
			JSONArray arr = JSONArray.fromObject(list);
			String user = arr.toString();
			PrintWriter pw = response.getWriter();
			pw.println(user);
			pw.flush();
			pw.close();
  1. 而後,將數據發送給頁面。jsp頁面中經過ajax回調接收
$(function(){
			$.ajax({
				method:"get",
				url:"JsonServlet",
				data:null,
				success:function(msg){
					var data = JSON.parse(msg);
					console.info(data);
				},
				error:function(){
					alert("數據請求錯誤!");
				}
			});
		});
  1. 咱們看下通過解析後的json字符串是什麼樣的格式(下面是在servlet中輸出的結果)
[{"date":{"date":26,"day":1,"hours":18,"minutes":58,"month":11,"seconds":35,"time":1482749915563,"timezoneOffset":-480,"year":116},"id":1,"name":"sucan"},{"date":{"date":26,"day":1,"hours":18,"minutes":58,"month":11,"seconds":35,"time":1482749915563,"timezoneOffset":-480,"year":116},"id":2,"name":"ximi"},{"date":{"date":26,"day":1,"hours":18,"minutes":58,"month":11,"seconds":35,"time":1482749915563,"timezoneOffset":-480,"year":116},"id":3,"name":"sc"}]

能夠看到,日期格式很複雜,這樣,咱們頁面取值的時候,可能就會變得很複雜,因而,咱們但願將日期,以一種簡單的方式傳給jsp頁面(如:XXXX-XX-XX的形式)。json

3.通過配置處理以後的json數據,結果

  1. 在上面咱們使用JSONArray.fromObject(list)的時候,其實咱們還有這個方法的另一種重載形式,裏面包含兩個參數,一個是咱們須要處理的內容,另一個就是咱們的JsonConfig對象;
JsonConfig config = new JsonConfig();
JSONArray arr = JSONArray.fromObject(list, config);
  1. 接下來咱們調用config的config.registerJsonValueProcessor(propertyType, jsonValueProcessor)方法來對咱們的Date類進行轉換,這個函數有兩個參數,第一個參數,表明咱們須要轉換的類,後面是一個待實現的接口。在這裏,咱們須要轉換Date類,顯然第一個參數是java.util.Date.class
config.registerJsonValueProcessor(java.util.Date.class, jsonValueProcessor);

如今關鍵是第二個參數,因此咱們要實現jsonValueProcessor接口;jsp

  1. 建立一個jsonValueProcessor接口的實現類
public class jsonValueProcessorImpl implements JsonValueProcessor {

	public Object processArrayValue(Object arg0, JsonConfig arg1) {
		// TODO Auto-generated method stub
		return null;
	}

	public Object processObjectValue(String arg0, Object arg1, JsonConfig arg2) {
		// TODO Auto-generated method stub
		return null;
	}
}

能夠看到,這個接口包含兩個未實現的方法,下面咱們就是要寫這兩個方法。 arg0:表示鍵類型; arg1:表示往json格式中傳的value值; arg2:默認配置對象函數

  1. 下面咱們重寫兩個方法中的第二個
public Object processObjectValue(String key, Object value, JsonConfig arg2) {
		if(value instanceof java.util.Date){
			Date d = (Date)value;
			return new SimpleDateFormat(pattern).format(d);
		}
		return null;
	}

其中,pattern是咱們默認給的格式,也能夠在構造器中動態設置測試

String pattern = "yyyy-MM-dd";
	
	public jsonValueProcessorImpl(){
		
	}
	
	public jsonValueProcessorImpl(String pattern){
		this.pattern = pattern;
	}

最後,咱們在servlet中new jsonValueProcessorImpl()實現類this

config.registerJsonValueProcessor(java.util.Date.class, new jsonValueProcessorImpl());
  1. 看下效果
Object
date:"2016-12-26"
id:1
name:"sucan"
__proto__:Object
1:Object
date:"2016-12-26"
id:2
name:"ximi"
__proto__:Object
2:Object
date:"2016-12-26"
id:3
name:"sc"

咱們能夠看到,咱們的日期已經變成了咱們設置好的格式,而且是一個字符串形式。這樣咱們取值便方便了不少。url

4.若是咱們整個集合所有是Date對象又會怎麼樣?

  1. servlet中
Date u1 = new Date();
			Date u2 = new Date();
			Date u3 = new Date();
			List list = new ArrayList();
			list.add(u1);
			list.add(u2);
			list.add(u3);
  1. 看下此次的取值狀況
[null, null, null]
0:null
1:null
2:null

爲何頁面取值全是null呢?由於如今對象中除了Date對象不包含任何其餘數據,默認會執行,咱們上面所說未實現方法的第一個方法,因而,咱們爲了更好的兼容性,咱們將在第二個方法中所寫的代碼,最好仍是在第一個方法中重寫一次。爲了不重複寫代碼,咱們能夠將代碼封裝成一個方法,而後在實現類的方法中分別調用這個方法code

public Object processArrayValue(Object value, JsonConfig arg1) {
		return hanlder(value);
	}

	public Object processObjectValue(String key, Object value, JsonConfig arg2) {
		return hanlder(value);
	}
	
	public String hanlder(Object value){
		if(value instanceof java.util.Date){
			Date d = (Date)value;
			return new SimpleDateFormat(pattern).format(d);
		}
		return null;
	}
  1. 下面咱們再來看下效果
["2016-12-26", "2016-12-26", "2016-12-26"]
相關文章
相關標籤/搜索