Spring MVC Jackson 格式序列化

    一个上市公司竟然无法解决html尖角号的问题,我也是很无奈,自己实现了一个html过滤器。

    解决问题:修改@ResponseBody返回值。

    1.ExampleEntity类,首先定义模型,使用@JsonSerialize注解指定序列化类,@JsonIgnore注解序列化忽略,@JsonFormat注解格式化时间格式。

package com.jc.bus.example.entity;

import java.util.Date;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.jc.bus.example.serializer.ExampleSerializer;


@JsonSerialize(using = ExampleSerializer.class)
public class ExampleEntity {

	private String username;
	
	@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
	private Date date;

	@JsonIgnore
	private int age;
	
	private Double money;
	
	private List<String> ls;
	
	public Double getMoney() {
		return money;
	}

	public void setMoney(Double money) {
		this.money = money;
	}

	public List<String> getLs() {
		return ls;
	}

	public void setLs(List<String> ls) {
		this.ls = ls;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}
}

    2.ExampleSerializer序列化主类,也就是实体类注解指定序列化实现类,继承了JsonSerializer接口,实现其方法既可以。

package com.jc.bus.example.serializer;

import java.io.IOException;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.jc.bus.example.entity.ExampleEntity;
import com.jc.spring.extend.JacksonSerializerUtil;


public class ExampleSerializer extends JsonSerializer<ExampleEntity> {

	@Override
	public void serialize(ExampleEntity value, JsonGenerator gen,
			SerializerProvider serializers) throws IOException,
			JsonProcessingException {
		// TODO Auto-generated method stub
		gen.writeStartObject();
		JacksonSerializerUtil.writeParm(gen, value);
		gen.writeEndObject();
	}
	
}

     3.JacksonSerializerUtil工具类,这里我本想实现一个通用模型,但是最后并没有写完,这里实现了基本类型的通用方法,已经满足日常的需求了。

package com.jc.spring.extend;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import com.fasterxml.jackson.core.JsonGenerator;

public class JacksonSerializerUtil {
	//com.fasterxml.jackson.annotation.JsonIgnore;
	/**
	 * Jackson序列话参数写入标准实现
	 * @param gen
	 * @param value
	 */
	public static void writeParm(JsonGenerator gen, Object value){
		Class<? extends Object> classTemp = value.getClass();
		Field[] fields = classTemp.getDeclaredFields();
		try {
			for (int i=0; i<fields.length; i++){
				Field field = fields[i];
				field.setAccessible(true);
				if(field.isAnnotationPresent(com.fasterxml.jackson.annotation.JsonIgnore.class)){
					continue;
				}
				//字段类型
				Class<?> type = field.getType();
				String fieldName = field.getName();
				PropertyDescriptor pd=new PropertyDescriptor(fieldName,classTemp);
				Method method = pd.getReadMethod();
				Object obj = method.invoke(value);
				//判断是否是null,给出默认值
				boolean flag = obj==null;
				
				if (flag){
					gen.writeStringField(fieldName, "");
					continue;
				}
				
				if (type == String.class){
					gen.writeStringField(fieldName, HtmlFilter.doHtmlFilter((String)obj));
				}else if (type==Long.class){
					gen.writeNumberField(fieldName, (Long)obj);
				}else if (type==Integer.class){
					gen.writeNumberField(fieldName, (Integer)obj);
				}else if (type==Short.class){
					gen.writeNumberField(fieldName, (Short)obj);
				}else if (type==Float.class){
					gen.writeNumberField(fieldName, (Float)obj);
				}else if (type==Double.class){
					gen.writeNumberField(fieldName, (Double)obj);
				}else if (type==BigDecimal.class){
					gen.writeNumberField(fieldName, (BigDecimal)obj);
				}else if (type==byte[].class){
					gen.writeBinaryField(fieldName, (byte[])obj);
				}else if (type==Date.class){
					if (field.isAnnotationPresent(com.fasterxml.jackson.annotation.JsonFormat.class)){
						com.fasterxml.jackson.annotation.JsonFormat jf = field.getAnnotation(com.fasterxml.jackson.annotation.JsonFormat.class);
						String pattern = jf.pattern();
						DateFormat df = new SimpleDateFormat(pattern);
						gen.writeStringField(fieldName, df.format((Date)obj));
					}else{
						DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
						gen.writeStringField(fieldName, df.format((Date)obj));
					}
				}else if (type==List.class){
					gen.writeArrayFieldStart(fieldName);
					List list = (List)obj;
					for (Object element : list){
						writeBaseType(gen, element);
					}
					gen.writeEndArray();
				}
				
			}
				
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static void writeBaseType(JsonGenerator gen, Object field){
		try {
			boolean flag = field==null;
			//字段类型
			if (flag){
				return ;
			}
			if (field instanceof String){
				gen.writeString(HtmlFilter.doHtmlFilter((String)field));
			}else if (field instanceof Long){
				gen.writeNumber((Long)field);
			}else if (field instanceof Integer){
				gen.writeNumber((Integer)field);
			}else if (field instanceof Short){
				gen.writeNumber((Short)field);
			}else if (field instanceof Float){
				gen.writeNumber((Float)field);
			}else if (field instanceof Double){
				gen.writeNumber((Double)field);
			}else if (field instanceof BigDecimal){
				gen.writeNumber((BigDecimal)field);
			}else if (field instanceof byte[]){
				gen.writeBinary((byte[])field);
			}else if (field instanceof Date){
				DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				gen.writeString(df.format((Date)field));
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
}

 4.HtmlFilter转换工具类,修改html特殊字符。

package com.jc.spring.extend;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.aspectj.lang.annotation.Aspect;

@Aspect
public class HtmlFilter {
	
	private static Map<Character, String> filterMap = new HashMap<Character, String>();
	static {
		filterMap.put('\"', "&quot;");
		filterMap.put('&', "&amp;");
		filterMap.put('<', "&lt;");
		filterMap.put('>', "&gt;");
		filterMap.put('\'', "&apos;");
		filterMap.put('\\', "&#92;");
	}
	
	/**
	 * 在get*方法体里调用,自动转换字符
	 * @param parm
	 * @return
	 */
	public static String doHtmlFilter (String parm){
		//最终返回参数
		StringBuilder reString = new StringBuilder("");
		
		char[] chars = parm.toCharArray();
		
		for (int i=0; i<chars.length; i++){
			Character c = chars[i];
			Set<Entry<Character, String>> entry = filterMap.entrySet();
			boolean bflag = true;
			for (Entry<Character, String> filterEntry : entry){
				Character convertChar = filterEntry.getKey();
				if (c.equals(convertChar)){
					reString.append(filterEntry.getValue());
					bflag = false;
					break;
				}
			}
			if (bflag){
				reString.append(c);
			}
		}
		return reString.toString();
	}
	
}

 5.这里需要注意一定要把jackson注入。

    @Bean
    public JacksonAnnotationIntrospector jacksonAnnotationIntrospector() {
        return new JacksonAnnotationIntrospector();
    }
    
    @Bean(name = "objectMapper")
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        mapper.configure(SerializationFeature.INDENT_OUTPUT, false);
        
        mapper.setAnnotationIntrospector(jacksonAnnotationIntrospector());
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

        return mapper;
    }

 

猜你喜欢

转载自aa80303857.iteye.com/blog/2407756