栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringMVC:参数处理RequestBodyAdvice和返回结果处理ResponseBodyAdvice

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringMVC:参数处理RequestBodyAdvice和返回结果处理ResponseBodyAdvice

目录

背景

使用场景

接口说明

RequestBodyAdvice

ResponseBodyAdvice

示例

场景说明:参数转换

自定义注解

User实体对象

接口返回对象

自定义RequestBodyAdvice参数处理器

自定义ResponseBodyAdvice返回值处理器

controller接口

测试

注意事项


RequestBodyAdvice

        在执行Controller接口之前,如果Controller参数是被@RequestBody修饰,可以对该参数进行一些特殊处理,比如参数解密,参数转换等。

ResponseBodyAdvice

        执行完Controller接口之后,在response返回给客户端之前,如果Controller方法被@ResponseBody修饰,此时可以对response返回的数据做一些特殊处理,比如返回值加密,构造统一返回对象,返回值转换等。

背景

在SpringBoot项目中,很多时候都需要对Controller层请求参数和响应结果做一些公共操作,这时就可以使用RequestBodyAdvice和ResponseBodyAdvice。

使用场景

对接口参数进行前后空格的过滤;

参数转换,比如字段关联字典:将字典显示值转换为保存值;

解密一些关键性字段;

返回参数统一处理;

身份证等特殊字符统一转换为*;

接口说明

RequestBodyAdvice
public interface RequestBodyAdvice {

    
    boolean supports(MethodParameter methodParameter, Type targetType,
                     Class> converterType);

    
    HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter,
                                    Type targetType, Class> converterType) throws IOException;

    
    Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter,
                         Type targetType, Class> converterType);

    
    @Nullable
    Object handleEmptyBody(@Nullable Object body, HttpInputMessage inputMessage, MethodParameter parameter,
                           Type targetType, Class> converterType);


}

ResponseBodyAdvice
public interface ResponseBodyAdvice {

    
    boolean supports(MethodParameter returnType, Class> converterType);

    
    @Nullable
    T beforeBodyWrite(@Nullable T body, MethodParameter returnType, MediaType selectedContentType,
                      Class> selectedConverterType,
                      ServerHttpRequest request, ServerHttpResponse response);

}

示例

场景说明:参数转换

        自定义一个注解@TransParam,现在需要将Controller接口中,@TransParam注解修饰的参数进行参数转换。

        转换关系:controller入参:男->0,女->1,其他值->2;

        转换关系:controller出参:0->男1,1->女1,其他值->中性

自定义注解

注解可应用于

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TransParam {
}

User实体对象

User对象中sex字段被@TransParam修饰。

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {
    private String name;

    @TransParam 
    private int sex;
}

接口返回对象
@Data
@AllArgsConstructor
public class ResponseResult {
    private int code;
    private Object content;

    public static ResponseResult fail(Object content) {
        return new ResponseResult(HttpStatus.FOUND.value(), content);
    }

    public static ResponseResult success(Object content) {
        return new ResponseResult(HttpStatus.OK.value(), content);
    }
}

自定义RequestBodyAdvice参数处理器

作用:将@TransParam修饰的字段值,进行转换:男->0,女->1,其他值->2;

主要会用到supports和beforeBodyRead两个方法:

supports判断是否对当前接口进行参数转换;

beforeBodyRead执行具体的转换逻辑。

@ControllerAdvice
public class MyRequestBodyAdvice implements RequestBodyAdvice {
    @Override
    public boolean supports(MethodParameter methodParameter, Type targetType, Class> converterType) {
        return true;
    }

    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class> converterType) throws IOException {
        if (inputMessage.getBody().available()<=0) {
            return inputMessage;
        }

        // 获取前端入参jsonobj
        byte[] requestBodyByte=new byte[inputMessage.getBody().available()];
        inputMessage.getBody().read(requestBodyByte);
        String requestData = new String(requestBodyByte, StandardCharsets.UTF_8);
        JSONObject jsonobj = JSON.parseObject(requestData);

        // 参数转换,将@TransParam修饰的字段,男->0,女->1,其他值->2;
        jsonobj = transParams(jsonobj, targetType);

        // 使用解密后的数据,构造新的读取流
        return getNewInputStream(jsonobj, inputMessage);
    }

    private JSONObject transParams(JSONObject jsonobj, Type targetType) {

        try {
            Class clazz = Class.forName(targetType.getTypeName());
            // 获取接口参数类的所有属性
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                String fieldName = field.getName();
                // 如果属性被@TransParam修饰,则执行转换
                if (field.getAnnotation(TransParam.class) != null) {
                    String value = jsonobj.getString(fieldName);
                    if (value.equals("男")) {
                        jsonobj.put(fieldName, 0);
                    } else if (value.equals("女")) {
                        jsonobj.put(fieldName, 1);
                    } else {
                        jsonobj.put(fieldName, 2);
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return jsonobj;
    }

    private HttpInputMessage getNewInputStream(JSONObject jsonobj, HttpInputMessage inputMessage) {
        byte[] newRequestByte = jsonobj.toJSONString().getBytes();
        InputStream rawInputStream = new ByteArrayInputStream(newRequestByte);
        return new HttpInputMessage() {
            @Override
            public HttpHeaders getHeaders() {
                return inputMessage.getHeaders();
            }

            @Override
            public InputStream getBody() {
                return rawInputStream;
            }
        };
    }

    @Override
    public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class> converterType) {
        return body;
    }

    @Override
    public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class> converterType) {
        return body;
    }
}

自定义ResponseBodyAdvice返回值处理器

作用

        1、将@TransParam修饰的字段值,进行转换:0->男1,1->女1,其他值->中性;

        2、将返回值统一封装成ResponseResult对象返回给前端。

主要会用到supports和beforeBodyWrite两个方法:

supports判断是否对当前返回值进行值转换;

beforeBodyWrite执行具体的转换逻辑。

@ControllerAdvice
public class MyResponseBodyAdvice implements ResponseBodyAdvice {
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        JSONObject jsonObject = null;
        try {
            Class clazz = Class.forName(returnType.getParameterType().getName());
            // 获取返回值对象类的所有属性
            Field[] fields = clazz.getDeclaredFields();
            jsonObject = JSONObject.parseObject(JSONObject.toJSONString(body));
            for (Field field : fields) {
                String fieldName = field.getName();
                // 如果字段被@TransParam修饰,则进行数据转换:0->男1,1->女1,其他值->中性
                if (field.getAnnotation(TransParam.class) != null) {
                    String value = jsonObject.getString(fieldName);
                    if (value.equals("0")) {
                        jsonObject.put(fieldName, "男1");
                    } else if (value.equals("1")) {
                        jsonObject.put(fieldName, "女1");
                    } else {
                        jsonObject.put(fieldName, "中性");
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        // 将返回结果封装成ResponseResult对象统一返回。
        return ResponseResult.success(jsonObject);
    }
}

controller接口
@ResponseBody
    @PostMapping("/test")
    public User test(@RequestBody User user) {
        String result = "姓名:" + user.getName() + "; 性别编号:" + user.getSex();
        System.out.println(result);
        return user;
    }

测试

注意事项

自定义的处理对象类上必须得加上@ControllerAdvice注解;

RequestBodyAdvice作用范围为@RequestBody修饰的参数;

ResponseBodyAdvice作用范围为@ResponseBodyAdvice修饰的方法。

以上内容为个人学习理解,如有问题,欢迎在评论区指出。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/980971.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号