spring mvc3 Jackson輸出null轉爲空串兩種解決方法

      之前因爲返回到iPhone客戶端和android客戶端的json格式中許多值是null值,界面去key顯示出來的值就爲null,很不友好。手機端開發者表示要把null轉爲“”暫時沒有辦法。

於是就交給了服務器端,在網上找了http://wuliaolll.iteye.com/blog/1868205這篇文章,我們採用的是springmvc3.0.5.release和spring3.0.5這個版本。對於文章上的方法試過幾次,改過幾次,都無效,初步認爲是springmvc或者spring的bug,如果有知道原因的請回復我,讓大家都瞭解瞭解。如果大家用http://wuliaolll.iteye.com/blog/1868205 這篇文章的方法無效,不放試試我的解決方法。

最後解決方案如下:


ObjectMappingCustomer.java

package javacommon.util;

import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializerProvider;

import java.io.IOException;

/**
 * Date: 13-11-13
 * Time: 上午9:01
 */
public class ObjectMappingCustomer extends ObjectMapper {

    public ObjectMappingCustomer() {
        super();
        // 空值處理爲空串
        this.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {

            @Override
            public void serialize(
                    Object value,
                    JsonGenerator jg,
                    SerializerProvider sp) throws IOException, JsonProcessingException {
                jg.writeString("");
            }
        });

    }
}

JsonUtil.java 這個類是我從項目抽出來的,方便直接使用. 後面我會貼出項目中用的類,方便借鑑運用

package com.test;

import java.io.IOException;

import javax.servlet.http.HttpServletResponse;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

public class JsonUtil {
    private static ObjectMappingCustomer objectMappingCustomer = new ObjectMappingCustomer();
    private static ObjectMapper objectMapper;

    /**
     * 把jackson null轉爲""串
     * @param response 
     * @param object  
     */
	@SuppressWarnings("unused")
	public static void WriteNullToString(HttpServletResponse response,Object object) {
    	response.setContentType("application/json");
        try {
        	if(false) {//如果爲true,表示允許返回的json爲null,具體值可以配置到配置文件然後讀取,以後要改就不用改源碼了
        		if (objectMapper == null) {
        			objectMapper = new ObjectMapper();
        		}
        		response.getWriter().write(objectMapper.writeValueAsString(object));
        	}else {
        		response.getWriter().write(objectMappingCustomer.writeValueAsString(object));
        	}
		} catch (JsonGenerationException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
    }
}
有了上面兩部就可以運用了,貼一個實際代碼出來參考.

運用到實際項目中的實現

MobileResult.java

package com.wallaw.portal.model;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javacommon.util.ObjectMappingCustomer;
import javacommon.util.PublicCode;
import javacommon.util.StringUtil;

import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

/**
 * Date: 13-4-26
 * Time: 下午1:56
 * 返回手機客戶端通用類
 */
public class MobileResult {

    private String resultCode;
    private String returnMsg;
    private Map resultObject;
    
    private static ObjectMappingCustomer objectMappingCustomer;
    private static ObjectMapper objectMapper;
    private static final Logger LOG = Logger.getLogger(MobileResult.class);
    public MobileResult() {
        resultObject = new HashMap();
    }

    public String getResultCode() {
        return resultCode;
    }

    public void setResultCode(String resultCode) {
        this.resultCode = resultCode;
    }

    public String getReturnMsg() {
        return returnMsg;
    }

    public void setReturnMsg(String returnMsg) {
        this.returnMsg = returnMsg;
    }

    public Map getResultObject() {
        return resultObject;
    }

    public void setResultObject(Map resultObject) {
        this.resultObject = resultObject;
    }
    
	public static void setObjectMappingCustomer(
			ObjectMappingCustomer objectMappingCustomer) {
		MobileResult.objectMappingCustomer = objectMappingCustomer;
	}

	public void WriteJsonToResponse(HttpServletResponse response) {
    	response.setContentType("application/json");
        try {
        	if(StringUtil.toBoolean(PublicCode.getCommConfigMap().get("enable.jsonnull"), false)) {
        		if (objectMapper == null) {
        			objectMapper = new ObjectMapper();
        		}
        		response.getWriter().write(objectMapper.writeValueAsString(this));
        	}else {
        		response.getWriter().write(objectMappingCustomer.writeValueAsString(this));
        	}
		} catch (JsonGenerationException e) {
			LOG.error("WriteJsonToResponse查詢失敗:", e);
		} catch (JsonMappingException e) {
			LOG.error("WriteJsonToResponse查詢失敗:", e);
		} catch (IOException e) {
			LOG.error("WriteJsonToResponse查詢失敗:", e);
		}
    }
}


貼一個controller,看了就應該明白上面的代碼
/*
 * Powered By [rapid-framework]
 * Web Site: http://www.rapid-framework.org.cn
 * Google Code: http://code.google.com/p/rapid-framework/
 * Since 2008 - 2013
 */


package com.wallaw.portal.controller;

import java.util.List;

import javacommon.base.BaseRestSpringController;
import javacommon.util.CollectionUtil;
import javacommon.util.Constants;

import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

import com.wallaw.portal.model.MobileResult;
import com.wallaw.portal.model.Test;
import com.wallaw.portal.service.ProductStatusManager;
import com.wallaw.portal.vo.query.ProductStatusQuery;

/**
 * @version 1.0
 * @since 1.0
 */

@Controller
@RequestMapping("/test")
public class TestController extends BaseRestSpringController<Test,java.lang.Integer>{
	
 	private ProductStatusManager productStatusManager;

 	public void setProductStatusManager(ProductStatusManager productStatusManager) {
		this.productStatusManager = productStatusManager;
	}
	   
	
	/*-----------------------------------------------------手機端接口--------------------------------------------------------------------*/
	
	/**
	 * 每日推薦列表
	 */
	@RequestMapping(value="mobile/list")//去除了@ResponseBody
	public void list(ModelMap model,ProductStatusQuery productStatusquery, HttpServletResponse response){
		MobileResult mobileResult = new MobileResult();
		mobileResult.setResultCode(Constants.FAILURE_CODE);
		mobileResult.setReturnMsg(Constants.FAILURE);
		//查金融推薦產品
		List productList = productStatusManager.getProductListWithRecommend(productStatusquery);
		//計算總數
		int count = CollectionUtil.isEmpty(productList)?0:productList.size();
		if(count!=0){
			mobileResult.setResultCode(Constants.SUCCESS_CODE);
			mobileResult.setReturnMsg(Constants.SUCCESS);
			mobileResult.getResultObject().put("productList", productList);
			mobileResult.getResultObject().put("count", count);
		}
		mobileResult.WriteJsonToResponse(response);//利用response.getWriter().write(String)把json返回給手機端
	}
	
}

返回結果如下圖:

網上沒有找到相關的實現,自己實現之後就寫下來了,希望對大家有用。

發佈了13 篇原創文章 · 獲贊 1 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章