fastjson html转义,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格式返回参数转换类

*

*

* @author songxiaotong

* @version [版本号, 2016年10月14日]

* @see [相关类/方法]

* @since [产品/模块版本]

*/

public class JsonConverter extends FastJsonHttpMessageConverter

{

/**

* 日志记录器

**/

private static final Logger LOGGER = LogManager.getLogger(JsonConverter.class);

/**

* 重写writeInternal方法,在返回内容前首先进行HTML字符转义

*

* @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特殊字符转义

String result = convertJson(text);

// 输出转义后的文本

out.write(result.getBytes(super.getCharset()));

}

/**

* JSON参数转义

*

* @param json

* @return

* @see [类、类#方法、类#成员]

*/

private String convertJson(String json)

{

try

{

// 判断是否是JSON对象

if (json.startsWith("{"))

{

// 将参数转换成JSONObject

JSONObject jsonObj = JSONObject.fromObject(json);

// 处理参数

JSONObject myobj = jsonObj(jsonObj);

return myobj.toString();

}

// 判断是否是JSON数组

else if (json.startsWith("["))

{

// 将参数转换成JSONArray

JSONArray jsonArray = JSONArray.fromObject(json);

//处理参数

JSONArray array = parseArray(jsonArray);

return array.toString();

}

else

{

return json;

}

}

catch (JSONException e)

{

LOGGER.error("Json数据解析处理失败!");

return "{}";

}

}

/**

* JSON参数Map(对象)转义

*

* @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));

}

// 判断是否是对象结构

else if (obj instanceof Map)

{

// 处理参数

json.put(key, jsonObj((JSONObject)obj));

}

else if (obj instanceof String)

{

// 处理参数

json.put(key, convertStr((String)obj));

}

}

return json;

}

/**

* JSON参数List(数组)转义

*

* @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);

// 判断是否是数据结构

if (obj instanceof List)

{

// 处理数组对象

parseArray((JSONArray)obj);

}

// 判断是否是对象结构

else if (obj instanceof Map)

{

// 处理参数

jsonObj((JSONObject)obj);

}

// 判断是否是String结构

else if (obj instanceof String)

{

jsonArray.set(i, convertStr((String)obj));

}

}

return jsonArray;

}

/**

* HTML脚本转义

*

* @param str

* @return

* @see [类、类#方法、类#成员]

*/

private String convertStr(String str)

{

// TODO &、、"、'、(、)、%、+、\

return str.replace("&", "&")

.replace("

.replace(">", ">")

.replace("\"", """)

.replace("'", "'")

.replace("(", "(")

.replace(")", ")")

.replace("%", "%")

.replace("+", "+")

.replace("\\", "\");

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值