SpringMVC通過FastJsonHttpMessageConverter解決XSS攻擊

@Bean
    public HttpMessageConverters customConverters() {
        FastJsonConfig cfg = new FastJsonConfig();
        cfg.setCharset(Charset.forName("UTF-8"));
        cfg.setDateFormat("yyyy-MM-dd HH:mm:ss");
        JsonHttpMsgConverter jsonHttpMsgConverter = new JsonHttpMsgConverter();
        jsonHttpMsgConverter.setFastJsonConfig(cfg);
        return new HttpMessageConverters(jsonHttpMsgConverter);
    }
package com.util.json;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.converter.HttpMessageNotWritableException;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;

/**
 * JSON格式返回參數(shù)轉(zhuǎn)換類
 * <功能詳細(xì)描述>
 * 
 * @author  songxiaotong
 * @version  [版本號, 2016年10月14日]
 * @see  [相關(guān)類/方法]
 * @since  [產(chǎn)品/模塊版本]
 */
public class JsonConverter extends FastJsonHttpMessageConverter
{
    /**
     * 日志記錄器
     **/
    private static final Logger LOGGER = LogManager.getLogger(JsonConverter.class);
    
    /** 
     * 重寫writeInternal方法,在返回內(nèi)容前首先進(jìn)行HTML字符轉(zhuǎn)義
     * <功能詳細(xì)描述>
     * @param object
     * @param outputMessage
     * @throws IOException
     * @throws HttpMessageNotWritableException
     * @see [類、類#方法、類#成員]
     */
    @Override
    protected void writeInternal(Object object, HttpOutputMessage outputMessage)
        throws IOException, HttpMessageNotWritableException
    {
        // 獲取輸出流
        OutputStream out = outputMessage.getBody();
        
        // 獲取要輸出的文本
        String text = JSON.toJSONString(object, super.getFeatures());
        
        // 對文本做HTML特殊字符轉(zhuǎn)義
        String result = convertJson(text);
        
        // 輸出轉(zhuǎn)義后的文本
        out.write(result.getBytes(super.getCharset()));
    }
    
    /** 
     * JSON參數(shù)轉(zhuǎn)義
     * <功能詳細(xì)描述>
     * @param json
     * @return
     * @see [類、類#方法、類#成員]
     */
    private String convertJson(String json)
    {
        try
        {
            // 判斷是否是JSON對象
            if (json.startsWith("{"))
            {
                // 將參數(shù)轉(zhuǎn)換成JSONObject
                JSONObject jsonObj = JSONObject.fromObject(json);
                // 處理參數(shù)
                JSONObject myobj = jsonObj(jsonObj);
                return myobj.toString();
            }
            // 判斷是否是JSON數(shù)組
            else if (json.startsWith("["))
            {
                // 將參數(shù)轉(zhuǎn)換成JSONArray
                JSONArray jsonArray = JSONArray.fromObject(json);
                //處理參數(shù)
                JSONArray array = parseArray(jsonArray);
                return array.toString();
            }
            else
            {
                return json;
            }
        }
        catch (JSONException e)
        {
            LOGGER.error("Json數(shù)據(jù)解析處理失??!");
            return "{}";
        }
    }
    
    /** 
     * JSON參數(shù)Map(對象)轉(zhuǎn)義
     * <功能詳細(xì)描述>
     * @param json
     * @return
     * @see [類、類#方法、類#成員]
     */
    @SuppressWarnings("rawtypes")
    private JSONObject jsonObj(JSONObject json)
    {
        
        for (Iterator iter = json.keys(); iter.hasNext();)
        {
            // 獲取對象的key
            String key = (String)iter.next();
            // 獲取對象的值
            Object obj = json.get(key);
            
            // 判斷對象類型
            if (obj instanceof List)
            {
                json.put(key, parseArray((JSONArray)obj));
                
            }
            // 判斷是否是對象結(jié)構(gòu)
            else if (obj instanceof Map)
            {
                // 處理參數(shù)
                json.put(key, jsonObj((JSONObject)obj));
            }
            else if (obj instanceof String)
            {
                // 處理參數(shù)
                json.put(key, convertStr((String)obj));
            }
            
        }
        return json;
    }
    
    /** 
     * JSON參數(shù)List(數(shù)組)轉(zhuǎn)義
     * <功能詳細(xì)描述>
     * @param json
     * @return
     * @see [類、類#方法、類#成員]
     */
    private JSONArray parseArray(JSONArray jsonArray)
    {
        // 判空
        if (null == jsonArray || jsonArray.isEmpty() || jsonArray.size() == 0)
        {
            return jsonArray;
        }
        // 
        for (int i = 0, l = jsonArray.size(); i < l; i++)
        {
            Object obj = jsonArray.get(i);
            
            // 判斷是否是數(shù)據(jù)結(jié)構(gòu)
            if (obj instanceof List)
            {
                // 處理數(shù)組對象
                parseArray((JSONArray)obj);
            }
            // 判斷是否是對象結(jié)構(gòu)
            else if (obj instanceof Map)
            {
                // 處理參數(shù)
                jsonObj((JSONObject)obj);
            }
            // 判斷是否是String結(jié)構(gòu)
            else if (obj instanceof String)
            {
                jsonArray.set(i, convertStr((String)obj));
            }
        }
        
        return jsonArray;
    }
    
    /** 
     * HTML腳本轉(zhuǎn)義
     * <功能詳細(xì)描述>
     * @param str
     * @return
     * @see [類、類#方法、類#成員]
     */
    private String convertStr(String str)
    {
        // TODO &、<、>、"、'、(、)、%、+、\
        return str.replace("&", "&")
            .replace("<", "<")
            .replace(">", ">")
            .replace("\"", """)
            .replace("'", "&#x27;")
            .replace("(", "(")
            .replace(")", ")")
            .replace("%", "%")
            .replace("+", "+")
            .replace("\\", "\");
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容