preface

Only the user ID is saved in the database, but the corresponding user name needs to be returned for the front-end display. There are many ways to do this, but this article uses custom serializers and custom annotations. For example, the database has user table, comment table data

# the user tableINSERT INTO `user`(`id`, `name`) VALUES ('1111'.'CodeHunter');
INSERT INTO `user`(`id`, `name`) VALUES ('2222'.'Test user 2'); # comments tableINSERT INTO `comment`(`id`, `content`, `user_id`) VALUES ('aaaaa'.'comments 1'.'1111');
INSERT INTO `comment`(`id`, `content`, `user_id`) VALUES ('bbbbb'.'comments 2'.'2222');
Copy the code

Returns to the front-end structure

@Data
public class Comment implements Serializable {

    private String id;

    private String content;
    / / user id
    private String userId;
    // If the comment id is aaaa, userName returns CodeHunter
    private String userName;
}
Copy the code

Train of thought

  • Custom serializer

    When serializing the userName field, get the userId value through reflection and custom annotations, and then get the corresponding userName

  • Custom annotations

    Applies to the userName field and points to the userId field

implementation

  • define@Usernameannotations
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.FIELD)
 public @interface Username {
     // A field pointing to the user ID
     String value(a);
 }
Copy the code
  • Return structure definition
 @Data
 public class Comment implements Serializable {
 
     private String id;
 
     private String content;
 
     private String userId;
 
     // Use custom serializer processing, even if the value is null
     @JsonSerialize(using = UsernameSerializer.class, nullsUsing = UsernameSerializer.class)
     @Username("userId")
     private String username;
 }
Copy the code
  • defineUsernameSerializerThe serializer
@Component
@Slf4j
public class UsernameSerializer extends JsonSerializer<String> {
    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        // Add hutool class dependencies
        // Serialize directly if there is a value
        if (StrUtil.isNotBlank(value)) {
            gen.writeString(value);
            return;
        }

        JsonStreamContext outputContext = gen.getOutputContext();
        // Get the name of the currently serialized field
        String currentName = outputContext.getCurrentName();
        // Gets the object to which the current serialized field belongs
        Object currentValue = outputContext.getCurrentValue();

        try {
            /* * * select * from @username; /* * * select * from @username; /* * * from @username
            Field usernameField = ReflectUtil.getField(currentValue.getClass(), currentName);
            Username annotation = usernameField.getAnnotation(Username.class);
            if (Objects.nonNull(annotation)) {
                String userIdFieldName = annotation.value();
                if (StrUtil.isNotBlank(userIdFieldName)) {
                    Object idValue = ReflectUtil.getFieldValue(currentValue, userIdFieldName);
                    if (Objects.nonNull(idValue)) {
                        // TODO:UserId -> userName; You can use Redis Hashvalue = idValue.toString(); }}}}catch (Exception exception) {
            log.info("Serialization username exception {}", exception.getMessage()); } gen.writeString(value); }}Copy the code

test

  • The test userName value is the userId value

  • Before processing

  • After processing (value value anduserIdConsistent)

At the end

If this article is helpful to you, please like 👍🏻 to support it. If there is any mistake or better suggestion, welcome to correct, thank you.