一个上市公司竟然无法解决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('\"', """); filterMap.put('&', "&"); filterMap.put('<', "<"); filterMap.put('>', ">"); filterMap.put('\'', "'"); filterMap.put('\\', "\"); } /** * 在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; }