Springboot通过Converter和JsonDeserializer自定义web入参

1、背景

在WEB应用中可能存在简化入参的情况,比如:LoginInfo对象

@AllArgsConstructor
@NoArgsConstructor
@Data
public class LoginInfo implements Serializable {
    private String username;
    private String password;    
    private Dept dept;
}

在前端传入的时候Dept采用自定义字符串的方式传入,比如:dept="1:开发部",用冒号分隔,第一个字段是id,第二个字段是名称。

通过这种方式传入又分为表单提交和json提交两种方式。

在Springboot中分别以自定义实现Converter接口以及JsonDeserializer接口两种方式。

2、表单方式支持

实现Converter接口,并注册。

@Configuration(proxyBeanMethods = false)
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new Converter<String, Dept>() {
            @Override
            public Dept convert(String source) {
                if(!StringUtils.isEmpty(source)){
                    String[] split = source.split(":");
                    Dept dept = new Dept();
                    dept.setId(split[0]);
                    dept.setDeptName(split[1]);
                    return dept;
                }
                return null;
            }
        });
    }
}

接收参数时:

    @ResponseBody
    @PostMapping("/login2")
    public LoginInfo login2(LoginInfo loginInfo){
        System.out.println(loginInfo);
        return loginInfo;
    }

前端使用正常表单提交,只是dept字段是一个"1:开发部"这样的字符串。

当Springboot遇到Dept需要解析时,发现对应的值是字符串,就会调用自定义注册的转换器。

3、使用Json方式

实现JsonDeserializer接口

public class DeptDeserializer extends JsonDeserializer<Dept> {
    @Override
    public Dept deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        String text = p.getText();
        if (!StringUtils.isEmpty(text)) {
            String[] split = text.split(":");
            Dept dept = new Dept();
            dept.setId(split[0]);
            dept.setDeptName(split[1]);
            return dept;
        }
        return null;
    }
}

LoginInfo需要重新标注

@AllArgsConstructor
@NoArgsConstructor
@Data
public class LoginInfo implements Serializable {
    private String username;
    private String password;
    @JsonDeserialize(using = DeptDeserializer.class)
    private Dept dept;
}

接收参数时:

    @ResponseBody
    @PostMapping("/login3")
    public LoginInfo login3(@RequestBody LoginInfo loginInfo){
        System.out.println(loginInfo);
        return loginInfo;
    }

前端传参:

{
    "username": "测试",
    "password": "123",
    "dept": "1:开发部"
}
原文地址:https://www.cnblogs.com/asker009/p/14396601.html