background

Spring has some special requirements when converting the response data to front-end JSON strings. For example, the time field in the database is of type Long, the conversion to JSON needs to be a time string, and some sensitive data information is hidden.

This article introduces a simple Jackson annotation that hides information about some fields, replacing properties in the target object with characters that have no real meaning.

Defining Jackson annotations

Use @jacksonAnnotationsInside to define an annotation class HideSensitiveInfo on fields and methods that contains both mask and length methods:

@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.METHOD}) @JacksonAnnotationsInside @JsonSerialize(using = HideSensitiveInfoSerializer.class) public @interface HideSensitiveInfo {/** ** mask data String why, the default is ** @return */ String mask() default "*"; * @return */ int count() default 5; }Copy the code

Define the serialized class for the annotation

Use the annotation fields or methods, serialization classes used HideSensitiveInfoSerializer definition, serialization class is a one-to-one relationship with annotations, annotations to define the basic configuration information, serialization class to obtain the corresponding attributes to complete the output of the JSON serialization process.

public class HideSensitiveInfoSerializer extends StdSerializer<String> implements ContextualSerializer { private String mask = "?" ; private int count = 1; / * * * constructor: must provide a default constructor, call the superclass constructor, and provide a T type * / public HideSensitiveInfoSerializer () {super (String. Class); } /** * the argument constructor, The first step you must call the default constructor * @ param mask * @ param count * / public HideSensitiveInfoSerializer (String mask, int count) {this (); this.mask = mask; this.count = count; } @Override public JsonSerializer<? > createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException { String mask = "?" ; int count = 1; HideSensitiveInfo anno = null; if(beanProperty ! = null) { anno = beanProperty.getAnnotation(HideSensitiveInfo.class); } if (anno ! =null ) { mask = anno.mask(); count = anno.count(); } return new HideSensitiveInfoSerializer(mask,count); } @Override public void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { String content = ""; for (int i=0; i<count; i++) { content += mask; } jsonGenerator.writeString(content); }}Copy the code

To serialize a field annotated @hidesensitiveInfo, simply use the mask characters to compose a string of specified length.

Java entities reference annotations

Define a Java entity with the @hidesensitiveInfo annotation for the data to be desensitized:

Data public class MyData { @HideSensitiveInfo(mask="-",count = 7) private String telephone; @HideSensitiveInfo(mask="*",count = 3) private String name; public MyData(String telephone,String name) { this.telephone = telephone; this.name = name; }}Copy the code

Test Controller class

@RestController
@RequestMapping("/test")
public class MyTestJson {

    @ResponseBody
    @RequestMapping("/hello")
    public MyData hello() {
        return new MyData("13220045018","10");
    }
}
Copy the code

Access this interface to get hidden information:

The revelation of

Java annotations are more flexible than classes in passing information. A single line of annotations allows you to set additional configuration information, bypassing class new and property setting actions. Annotations, however, cannot be used alone and must be bound to other classes that use them.