精华内容
下载资源
问答
  • SpringBoot自定义PageData封装实体类接受前台参数 参考转载自博客:https://blog.csdn.net/qq_41035779/article/details/86014095 定义一个实体类PageData ```java /** * */ package com.ssm.util; import ...

    SpringBoot自定义PageData封装实体类接受前台参数

    参考转载自博客:https://blog.csdn.net/qq_41035779/article/details/86014095

    定义一个实体类PageData

    
    ```java
    /**
     * 
     */
    package com.ssm.util;
     
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;
     
    import javax.servlet.http.HttpServletRequest;
     
    /**
     *  @description
     *
     * @author Gaogzh
     *
     * @date 2018-4-14
     */
    public class PageData extends HashMap implements Map {
    	private static final long serialVersionUID = 1L;
    	Map map = null;
    	HttpServletRequest request;
    	public PageData(HttpServletRequest request){
    		this.request = request;
    		Map properties = request.getParameterMap();
    		Map returnMap = new HashMap(); 
    		Iterator entries = properties.entrySet().iterator(); 
    		Map.Entry entry; 
    		String name = "";  
    		String value = "";  
    		while (entries.hasNext()) {
    			entry = (Map.Entry) entries.next(); 
    			name = (String) entry.getKey(); 
    			Object valueObj = entry.getValue(); 
    			if(null == valueObj){ 
    				value = ""; 
    			}else if(valueObj instanceof String[]){ 
    				String[] values = (String[])valueObj;
    				for(int i=0;i<values.length;i++){ 
    					 value = values[i] + ",";
    				}
    				value = value.substring(0, value.length()-1); 
    			}else{
    				value = valueObj.toString(); 
    			}
    			returnMap.put(name, value); 
    		}
    		map = returnMap;
    	}
    	
    	public PageData() {
    		map = new HashMap();
    	}
    	
    	@Override
    	public Object get(Object key) {
    		Object obj = null;
    		if(map.get(key) instanceof Object[]) {
    			Object[] arr = (Object[])map.get(key);
    			obj = request == null ? arr:(request.getParameter((String)key) == null ? arr:arr[0]);
    		} else {
    			obj = map.get(key);
    		}
    		return obj;
    	}
    	
    	public String getString(Object key) {
    		return (String)get(key);
    	}
    	public Number getNumber(Object key)
    	{
    		return (Number)get(key);
    	}
    	@SuppressWarnings("unchecked")
    	@Override
    	public Object put(Object key, Object value) {
    		return map.put(key, value);
    	}
    	
    	@Override
    	public Object remove(Object key) {
    		return map.remove(key);
    	}
    	public void clear() {
    		map.clear();
    	}
    	public boolean containsKey(Object key) {
    		// TODO Auto-generated method stub
    		return map.containsKey(key);
    	}
    	public boolean containsValue(Object value) {
    		// TODO Auto-generated method stub
    		return map.containsValue(value);
    	}
    	public Set entrySet() {
    		// TODO Auto-generated method stub
    		return map.entrySet();
    	}
    	public boolean isEmpty() {
    		// TODO Auto-generated method stub
    		return map.isEmpty();
    	}
    	public Set keySet() {
    		// TODO Auto-generated method stub
    		return map.keySet();
    	}
    	@SuppressWarnings("unchecked")
    	public void putAll(Map t) {
    		// TODO Auto-generated method stub
    		map.putAll(t);
    	}
    	public int size() {
    		// TODO Auto-generated method stub
    		return map.size();
    	}
    	public Collection values() {
    		// TODO Auto-generated method stub
    		return map.values();
    	}
    }
    
    
    
    
    
    展开全文
  • type=“application/json”)Java后端接受参数从传统角度来讲有两种方法,一是使用Map或者JSONObject,带上@RequestBody注解,可接收任意类型任意数量的传递参数,二是在后端定义一个接收实体也就是Java对象只能接收...

    一、自定义参数解析器需求产生背景

    建议了解,也会介绍它是做什么用的

    首先在post请求中(content-type=“application/json”)Java后端接受参数从传统角度来讲有两种方法,一是使用Map或者JSONObject,带上@RequestBody注解,可接收任意类型任意数量的传递参数,二是在后端定义一个接收实体也就是Java对象只能接收定义好的参数与参数类型。在后端只需要一个或两个非实体类型参数时,传统方式无疑需要去获取对应的参数,先转换成对应的类型,再设置入具体的类,非常的不友好,故想得出一个能让POST请求与GET请求参数接收一样友好方便的解决方案。

    二、准备工作

    通过翻阅资料发现,@RequestBody是通过参数解析器工作的,于是便想自定义一个完美的参数解析器用于以上情况的参数解析。

    首先新建一个注解类用于解析器判断是否进行自定义解析,并定义一些辅助解析参数

    package com.caohua.api.ptom.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.PARAMETER)
    public @interface JsonArg {
    
        public String value() default "";// 需解析参数名
    
        public String type() default "";// 参数类型(填bean为实体参数)
    
    }
    

    第二步:新建解析处理类

    package com.caohua.api.ptom.annotation.handle;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import com.caohua.api.ptom.annotation.JsonArg;
    import org.apache.commons.io.IOUtils;
    import org.apache.commons.lang.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.core.MethodParameter;
    import org.springframework.web.bind.support.WebDataBinderFactory;
    import org.springframework.web.context.request.NativeWebRequest;
    import org.springframework.web.method.support.HandlerMethodArgumentResolver;
    import org.springframework.web.method.support.ModelAndViewContainer;
    
    import javax.servlet.http.HttpServletRequest;
    import java.io.IOException;
    
    public class JsonArgumentResolver implements HandlerMethodArgumentResolver {
    
        private static final String JSONBODYATTRIBUTE = "JSON_REQUEST_BODY";
    
        final static Logger log = LoggerFactory.getLogger(JsonArgumentResolver.class);
    
        @Override
        public boolean supportsParameter(MethodParameter parameter) {
        	// 判断是否使用JsonArg注解,也就是,是否使用此解析器解析参数
            return parameter.hasParameterAnnotation(JsonArg.class);
        }
    
        @Override
        public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
            String body = getRequestBody(webRequest);// 获取body内容(形如{})
            // 获取注解设置的属性值
            String arg = parameter.getParameterAnnotation(JsonArg.class).value();
            String type = parameter.getParameterAnnotation(JsonArg.class).type();
            if (StringUtils.isEmpty(arg)) {
                arg = parameter.getParameterName();// body取值参数名未指定,使用默认参数名称
            }
            Object val = null;
            try {
                JSONObject obj = JSON.parseObject(body);
                if (type.equals("bean")) {// 解析实体参数,自动对应参数名称和类型注入实体其他丢弃
                    val = obj.toJavaObject(parameter.getParameterType());
                } else { // 解析非实体参数
                    val = obj.getObject(arg, parameter.getParameterType());
                }
            } catch (Exception e) {
                log.error("JsonArgumentResolver,参数解析错误,msg:{},body:{}", e.getMessage(), body);
            }
            return val;
        }
    
        private String getRequestBody(NativeWebRequest webRequest){
            HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
            String jsonBody = (String) webRequest.getAttribute(JSONBODYATTRIBUTE, NativeWebRequest.SCOPE_REQUEST);
            if (jsonBody == null) {
                try {
                    jsonBody = IOUtils.toString(servletRequest.getInputStream());
                    webRequest.setAttribute(JSONBODYATTRIBUTE, jsonBody, NativeWebRequest.SCOPE_REQUEST);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return jsonBody;
        }
    
    }
    

    第三步将参数解析器放入容器(也可以说是加入所有参数解析器集合中)

    此处有两种方法,首先声明亲自实验过使用spring提供的webMvcConfig系列的类去配置自定义参数解析器是无效的,原因是在接收到请求时,参数解析器的执行机制是遍历解析器集合,第一个符合条件的解析器被执行循环终止,显而易见对于我们需求场景中的请求方式肯定是有默认解析器去处理的,而提供的配置类把自定义解析器加入到了集合后方,肯定是永远不会执行的,那就意味着我们必须将自定义的参数解析器放到解析器集合的前面,最好是第一位,这样才能保证我们的解析器会被执行,这里提供两种可行的配置方式,具体实现原理请自行跟源码了解,只有认真了解过的事情才会记忆深刻。

    1、配置类形式

    package com.caohua.launcher.config;
    
    import com.caohua.api.ptom.annotation.handle.JsonArgumentResolver;
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.stereotype.Component;
    import org.springframework.web.method.support.HandlerMethodArgumentResolver;
    import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
    
    import java.util.ArrayList;
    import java.util.List;
    
    @Component
    public class ArgumentResolverConfig implements BeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    //        System.out.println("-------------------------------" + beanName);
            if(beanName.contains("RequestMappingHandlerAdapter")) {
                //对RequestMappingHandlerAdapter进行修改
                RequestMappingHandlerAdapter adapter = (RequestMappingHandlerAdapter) bean;
                List<HandlerMethodArgumentResolver> argumentResolvers = adapter.getArgumentResolvers();
                //添加自定义参数处理器
                argumentResolvers = addArgumentResolvers(argumentResolvers);
                adapter.setArgumentResolvers(argumentResolvers);
            }
            return bean;
        }
    
        private List<HandlerMethodArgumentResolver> addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
            List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();
            //将自定义的添加到最前面
            resolvers.add(new JsonArgumentResolver());// 添加参数解析器
            //将原本的添加后面
            resolvers.addAll(argumentResolvers);
            return resolvers;
        }
    }
    

    2、配置文件形式

    <mvc:annotation-driven>
        <mvc:argument-resolvers>
            <bean class="resolver.MyResolver"/>
        </mvc:argument-resolvers>
    </mvc:annotation-driven>
    

    这里本人使用的是第一种方式,感觉能在类里面体现出来并且不需要频繁更改的东西就不要去依赖配置文件

    展开全文
  • 作者 |无敌码农责编 | ...在工作中写过 Java 程序的朋友都知道,目前使用 Java 开发服务最主流的方式就是通过 Spring MVC 定义一个 Controller 层接口,并将接口请求或返回参数分别定义在一个 Java 实体类中,这样 ...

    baca0a066278213504073cd169152401.gif

    ea5fbd7dff8031cb106626595fa1d2c5.png

    作者 | 无敌码农  责编 | 张文头图 | CSDN 下载自东方 IC来源 | 无敌码农(ID:jiangqiaodege)本篇文章给大家分享平时开发中总结的一点小技巧!在工作中写过 Java 程序的朋友都知道,目前使用 Java 开发服务最主流的方式就是通过 Spring MVC 定义一个 Controller 层接口,并将接口请求或返回参数分别定义在一个 Java 实体类中,这样 Spring MVC 在接收到 Http 请求(POST/GET) 后,就会自动将请求报文自动映射成一个 Java 对象。这样的代码通常是这样写的:
    @RestControllerpublic class OrderController {    @Autowired    private OrderService orderServiceImpl;    @PostMapping("/createOrder")    public CreateOrderBO validationTest(@Validated CreateOrderDTO createOrderDTO) {        return orderServiceImpl.createOrder(createOrderDTO);    }}
    这样的代码相信大家并不陌生,但在后续的逻辑实现过程中却会遇到这样的问题:“在接收请求参数后如何实现报文对象数据值的合法性校验?”。一些同学也可能认为这并不是什么问题,因为具体某个参数字段是否为空、值的取值是否在约定范围、格式是否合法等等,在业务代码中校验就好了。例如可以在 Service实现类中对报文格式进行各种 if-else 的数据校验。从功能上说冗余的 if-else 代码没啥毛病,但从代码的优雅性来说冗长的 if-else 代码会显得非常臃肿。接下来的内容将给大家介绍一种处理此类问题的实用方法。具体将从以下几个方面进行介绍:
    • 使用@Validated 注解实现 Controller 接口层数据直接绑定校验;

    • 扩展约束性注解实现数据取值范围的校验;

    • 更加灵活的对象数据合法性校验工具类封装;

    • 数据合法性校验结果异常统一返回处理;

    05b69087e43b9f8f08cb13e8fac76709.png

    Controller 接口层数据绑定校验实际上在 Java 开发中目前普通使用的 Bean 数据校验工具是"hibernate-validator",它是一个 hibernete 独立的 jar 包,所以使用这个 jar 包并不需要一定要集成 Hibernete 框架。该jar包主要实现并扩展了 javax.validation (是一个基于 JSR-303 标准开发出来的 Bean 校验规范)接口。由于 Spring Boot 在内部默认集成了"hibernate-validator",所以使用Spring Boot 构建的 Java 工程可以直接使用相关注解来实现 Bean 的数据校验。例如我们最常编写的 Controller 层接口参数对象,可以在定义 Bean 类时直接编写这样的代码:
    @Datapublic class CreateOrderDTO {    @NotNull(message = "订单号不能为空")    private String orderId;    @NotNull(message = "订单金额不能为空")    @Min(value = 1, message = "订单金额不能小于0")    private Integer amount;    @Pattern(regexp = "^1[3|4|5|7|8][0-9]{9}$", message = "用户手机号不合法")    private String mobileNo;    private String orderType;    private String status;}
    如上所示代码,我们可以使用@NotNull 注解来约束该字段必须不能为空,也可以使用@Min 注解来约束字段的最小取值,或者还可以通过@Pattern 注解来使用正则表达式来约束字段的格式(如手机号格式)等等。以上这些注解都是“hibernate-validator”依赖包默认提供的,更多常用的注解还有很多,例如:d06153175504efbb0dd76b25c484cf1a.png利用这些约束注解,我们就可以很轻松的搞定接口数据校验,而不需要在业务逻辑中编写大量的 if-else 来进行数据合法性校验。而定义好 Bean 参数对象并使用相关注解实现参数值约束后,在 Controller 层接口定义中只需要使用@Validated 注解就可以实现在接收参数后自动进行数据绑定校验了,具体代码如下:
    @PostMapping("/createOrder")public CreateOrderBO validationTest(@Validated CreateOrderDTO createOrderDTO) {    return orderServiceImpl.createOrder(createOrderDTO);}
    如上所示,在 Controller 层中通过 Spring 提供的@Validated 注解可以自动实现数据 Bean 的绑定校验,如果数据异常则会统一抛出校验异常!

    b4335f90615c7bc0c9ffe546fd21ac60.png

    约束性注解扩展在“hibernate-validator”依赖 jar 包中,虽然提供了很多很方便的约束注解,但是也有不满足某些实际需要的情况,例如我们想针对参数中的某个值约定其值的枚举范围,如 orderType 订单类型只允许传“pay”、“refund”两种值,那么现有的约束注解可能就没有特别适用的了。此外,如果对这样的枚举值,我们还想在约束定义中直接匹配代码中的枚举定义,以更好地统一接口参数与业务逻辑的枚举定义。那么这种情况下,我们还可以自己扩展定义相应地约束注解逻辑。接下来我们定义新的约束注解@EnumValue,来实现上面我们所说的效果,具体代码如下:
    @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})@Retention(RUNTIME)@Documented@Constraint(validatedBy = {EnumValueValidator.class})public @interface EnumValue {    //默认错误消息    String message() default "必须为指定值";    //支持string数组验证    String[] strValues() default {};    //支持int数组验证    int[] intValues() default {};    //支持枚举列表验证    Class>[] enumValues() default {};    //分组    Class>[] groups() default {};    //负载    Class extends Payload>[] payload() default {};    //指定多个时使用    @Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE})    @Retention(RUNTIME)    @Documented    @interface List {        EnumValue[] value();    }    /**     * 校验类逻辑定义     */    class EnumValueValidator implements ConstraintValidatorObject> {        //字符串类型数组        private String[] strValues;        //int类型数组        private int[] intValues;        //枚举类        private Class>[] enumValues;        /**         * 初始化方法         *         * @param constraintAnnotation         */        @Override        public void initialize(EnumValue constraintAnnotation) {            strValues = constraintAnnotation.strValues();            intValues = constraintAnnotation.intValues();            enumValues = constraintAnnotation.enumValues();        }        /**         * 校验方法         *         * @param value         * @param context         * @return         */        @SneakyThrows        @Override        public boolean isValid(Object value, ConstraintValidatorContext context) {            //针对字符串数组的校验匹配            if (strValues != null && strValues.length > 0) {                if (value instanceof String) {                    for (String s : strValues) {//判断值类型是否为Integer类型                        if (s.equals(value)) {                            return true;                        }                    }                }            }            //针对整型数组的校验匹配            if (intValues != null && intValues.length > 0) {                if (value instanceof Integer) {//判断值类型是否为Integer类型                    for (Integer s : intValues) {                        if (s == value) {                            return true;                        }                    }                }            }            //针对枚举类型的校验匹配            if (enumValues != null && enumValues.length > 0) {                for (Class> cl : enumValues) {                    if (cl.isEnum()) {                        //枚举类验证                        Object[] objs = cl.getEnumConstants();                        //这里需要注意,定义枚举时,枚举值名称统一用value表示                        Method method = cl.getMethod("getValue");                        for (Object obj : objs) {                            Object code = method.invoke(obj, null);                            if (value.equals(code.toString())) {                                return true;                            }                        }                    }                }            }            return false;        }    }}
    如上所示的@EnumValue 约束注解,是一个非常实用的扩展,通过该注解我们可以实现对参数取值范围(不是大小范围)的约束,它支持对 int、string 以及 enum 三种数据类型的约束,具体使用方式如下:
    /** * 定制化注解,支持参数值与指定类型数组列表值进行匹配(缺点是需要将枚举值写死在字段定义的注解中) */@EnumValue(strValues = {"pay", "refund"}, message = "订单类型错误")private String orderType;/** * 定制化注解,实现参数值与枚举列表的自动匹配校验(能更好地与实际业务开发匹配) */@EnumValue(enumValues = Status.class, message = "状态值不在指定范围")private String status;
    如上所示代码,该扩展注解既可以使用 strValues intValues 属性来编程列举取值范围,也可以直接通过 enumValues 来绑定枚举定义。但是需要注意,处于通用考虑,具体枚举定义的属性的名称要统一匹配为 value、desc,例如  Status 枚举定义如下:
    public enum Status {    PROCESSING(1, "处理中"),    SUCCESS(2, "订单已完成");    Integer value;    String desc;    Status(Integer value, String desc) {        this.value = value;        this.desc = desc;    }    public Integer getValue() {        return value;    }    public String getDesc() {        return desc;    }}
    通过注解扩展,就能实现更多方便的约束性注解!

    f7a55663b02167d601b1148bcfd7988e.png

    更加灵活的数据校验工具类封装除了上面直接在 Controller 层使用@Validated 进行绑定数据校验外,在有些情况,例如你的参数对象中的某个字段是一个复合对象,或者业务层的某个方法所定义的入参对象也需要进行数据合法性校验,那么这种情况下如何实现像  Controller 层一样的校验效果呢?需要说明在这种情况下@Validated 已经无法直接使用了,因为@Validated 注解发挥作用主要是 Spring MVC 在接收参数的过程中实现了自动数据绑定校验,而在普通的业务方法或者复合参数对象中是没有办法直接绑定校验的。这种情况下,我们可以通过定义 ValidateUtils 工具类来实现一样的校验效果,具体代码如下:
    public class ValidatorUtils {    private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator();    /**     * bean整体校验,有不合规范,抛出第1个违规异常     */    public static void validate(Object obj, Class>... groups) {        Set> resultSet = validator.validate(obj, groups);        if (resultSet.size() > 0) {            //如果存在错误结果,则将其解析并进行拼凑后异常抛出            List errorMessageList = resultSet.stream().map(o -> o.getMessage()).collect(Collectors.toList());            StringBuilder errorMessage = new StringBuilder();            errorMessageList.stream().forEach(o -> errorMessage.append(o + ";"));            throw new IllegalArgumentException(errorMessage.toString());        }    }}
    如上所示,我们定义了一个基于"javax.validation"接口的工具类实现,这样就可以在非@Validated 直接绑定校验的场景中通过校验工具类来实现对 Bean 对象约束注解的校验处理,具体使用代码如下:
    public boolean orderCheck(OrderCheckBO orderCheckBO) {    //对参数对象进行数据校验    ValidatorUtils.validate(orderCheckBO);    return true;}
    方法入参对象则还是可以继续使用前面我们介绍的约束性注解进行约定,例如上述方法的入参对象定义如下:
    @Data@Builderpublic class OrderCheckBO {    @NotNull(message = "订单号不能为空")    private String orderId;    @Min(value = 1, message = "订单金额不能小于0")    private Integer orderAmount;    @NotNull(message = "创建人不能为空")    private String operator;    @NotNull(message = "操作时间不能为空")    private String operatorTime;}
    这样在编程体验上就可以整体上保持一致!

    e6512017908f29d4899f8c82d94725d0.png

    数据合法性校验结果异常统一处理通过前面我们所讲的各种约束注解,我们实现了对 Controller 层接口以及业务方法参数对象的统一数据校验。而为了保持校验异常处理的统一处理和错误报文统一输出,我们还可以定义通用的异常处理机制,来保证各类数据校验错误都能以统一错误格式反馈给调用方。具体代码如下:
    @Slf4j@ControllerAdvicepublic class GlobalExceptionHandler {    /**     * 统一处理参数校验错误异常(非Spring接口数据绑定验证)     *     * @param response     * @param e     * @return     */    @ExceptionHandler(BindException.class)    @ResponseBody    public ResponseResult> processValidException(HttpServletResponse response, BindException e) {        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());        //获取校验错误结果信息,并将信息组装        List errorStringList = e.getBindingResult().getAllErrors()                .stream().map(ObjectError::getDefaultMessage).collect(Collectors.toList());        String errorMessage = String.join("; ", errorStringList);        response.setContentType("application/json;charset=UTF-8");        log.error(e.toString() + "_" + e.getMessage(), e);        return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9998.getCode(),                errorMessage);    }    /**     * 统一处理参数校验错误异常     *     * @param response     * @param e     * @return     */    @ExceptionHandler(IllegalArgumentException.class)    @ResponseBody    public ResponseResult> processValidException(HttpServletResponse response, IllegalArgumentException e) {        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());        String errorMessage = String.join("; ", e.getMessage());        response.setContentType("application/json;charset=UTF-8");        log.error(e.toString() + "_" + e.getMessage(), e);        return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9998.getCode(),                errorMessage);    }    ...}
    如上所示,我们定义了针对前面两种数据校验方式的统一异常处理机制,这样数据校验的错误信息就能通过统一的报文格式反馈给调用端,从而实现接口数据报文的统一返回!其中通用的接口参数对象 ResponseResult 的代码定义如下:
    @Data@Builder@NoArgsConstructor@AllArgsConstructor@JsonPropertyOrder({"code", "message", "data"})public class ResponseResult<T> implements Serializable {    private static final long serialVersionUID = 1L;    /**     * 返回的对象     */    @JsonInclude(JsonInclude.Include.NON_NULL)    private T data;    /**     * 返回的编码     */    private Integer code;    /**     * 返回的信息     */    private String message;    /**     * @param data 返回的数据     * @param   返回的数据类型     * @return 响应结果     */    public static ResponseResultOK(T data) {        return packageObject(data, GlobalCodeEnum.GL_SUCC_0);    }    /**     * 自定义系统异常信息     *     * @param code     * @param message 自定义消息     * @param      * @return     */    public static ResponseResultsystemException(Integer code, String message) {        return packageObject(null, code, message);    }}
    当然,这样的统一报文格式也不仅仅只处理异常返回,正常的数据报文格式也可以通过该对象来进行统一封装!本文内容从实用的角度给大家演示了,如何在日常工作中编写通用的数据校验逻辑,希望能对大家有所帮助。faeee2fb8ffc69e0108a4d46cd03c91d.png27828d2e1b61f197f56ba0eb52168ea4.png
    更多精彩推荐

    程序员有钱了都干什么?买豪宅,玩跑车,上太空!| 涛滔不绝

    分库分表:TiDB,求别抢饭碗!

    他被称为印度“ IT 大王”,富可敌国,却精打细算如守财奴

    带你「周游世界」的 MODNet 算法

    一文聊“图”,从图数据库到知识图谱

    红帽"干掉" CentOS 8,CentOS Stream 上位

    科技垄断正在朝着纵向发展
    点分享点点赞点在看
    	
    展开全文
  • 例如:(1)后端接受一个参数Map param(可能是前端form维护的一个对象...)。(2)将一个对象个别属性(key)和对应值(value)存放到Map对象中。(3).......针对上面情况:1、对于对象属性较少时还是比较方便操作,可以手动...

    Java中利用反射进行Map和JavaBean间转换

    在日常工作中,有时候我们可能会遇到以下这样的情况发生。

    例如:

    (1)后端接受一个参数Map param(可能是前端form维护的一个对象...)。

    (2)将一个对象个别属性(key)和对应值(value)存放到Map对象中。

    (3).......

    针对上面情况:

    1、对于对象属性较少时还是比较方便操作,可以手动写入解决。

    2、如果是属性特别多(几十、甚至上百个字段),用到的地方也特别多时,再手动写的话就有点繁琐。

    这里给大家推荐一个方法:

    利用反射进行Map和JavaBean间转换

    案例:

    (1)下面是一个比较常见JavaBean。

    以Student为例,属性、构造器、set/get、toString......

    a70214e896969d3a02d670c37eea7781.png

    (2) 工具类MapAndJavaBeanUtil

    方法:将Map转化为JavaBean

    主要利用java反射的机制(此篇不针对反射)。

    Field类:封装了对象属性信息。

    //获取对象的属性fields数组

    Field[] fields = obj.getClass().getDeclaredFields();

    //设置对象属性名 属性值

    field.set(obj, map.get(field.getName()));

    7344dbe5cd33a425830fcc07f5e38163.png

    (3) 方法:将Object转化为Map

    与(2)同理。

    4eebe1a7e470464062a65a6e71a17d30.png

    (4) 测试

    1cdcf567275060bce334bb620b1bb85c.png

    如果大家还有其他方法欢迎评论留言,共同进步,感谢支持。

    源码贴在下面或者大家可以私信留言。

    MapAndJavaBeanUtil 工具类

    package util;

    import java.lang.reflect.Field;

    import java.lang.reflect.Modifier;

    import java.util.HashMap;

    import java.util.Map;

    public class MapAndJavaBeanUtil {

    /**

    * 将map转化为JavaBean

    * @param map

    * @param clazz

    * @return

    */

    public static Object mapToObject(Map map,Class> clazz) {

    if(map == null) return null;

    Object obj = null;

    try {

    obj = clazz.newInstance();

    Field[] fields = obj.getClass().getDeclaredFields();

    for (Field field : fields) {

    int mod = field.getModifiers();

    if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {

    continue;

    }

    field.setAccessible(true);

    //设置对象的属性名 属性值

    field.set(obj, map.get(field.getName()));

    }

    } catch (Exception e) {

    e.printStackTrace();

    }

    return obj;

    }

    /**

    * 将object转化为map

    * @param obj

    * @return

    */

    public static Map ObjectToMap(Object obj) {

    if(obj == null)return null;

    Map map = new HashMap<>();

    Class clazz = obj.getClass();

    Field[] fields = clazz.getDeclaredFields();

    try {

    for (Field field : fields) {

    //破坏封装(private)

    field.setAccessible(true);

    //属性名 属性值

    map.put(field.getName(), field.get(obj));

    }

    } catch (Exception e) {

    e.printStackTrace();

    }

    return map;

    }

    }

    Student实体类

    package entity;

    import java.util.Date;

    public class Student {

    private String pkid;

    private Integer sno;

    private String sname;

    private Date date;

    public Student() {}

    public Student(String pkid, Integer sno, String sname, Date date) {

    super();

    this.pkid = pkid;

    this.sno = sno;

    this.sname = sname;

    this.date = date;

    }

    public String getPkid() {

    return pkid;

    }

    public void setPkid(String pkid) {

    this.pkid = pkid;

    }

    public Integer getSno() {

    return sno;

    }

    public void setSno(Integer sno) {

    this.sno = sno;

    }

    public String getSname() {

    return sname;

    }

    public void setSname(String sname) {

    this.sname = sname;

    }

    public Date getDate() {

    return date;

    }

    public void setDate(Date date) {

    this.date = date;

    }

    @Override

    public String toString() {

    return "Student [pkid=" + pkid +

    展开全文
  • java 接口接受Date类型数据

    万次阅读 2018-06-28 10:11:13
    如果实体类接受页面参数时,实体类中因为有Date类型存在,导致接口请求出错,或者值set不到,可以在Date类型的属性上加上注解即可: 比如页面传递 实体类中添加@DateTimeFormat /**复查日期*/ @...
  • 1.springmvc接受参数1.1直接把表单的参数写在Controller相应的方法的形参中1.2通过HttpServletRequest接收1.3通过一个bean来接收,post方式和get方式都可以。创建user实体类1.4用注解@RequestParam绑定请求参数到方法...
  • 上述也就是我们前几天一直在分析的数据,也就是对应Goods这个实体类,同时将这个实体类和索引库对应起来。那导入什么数据?也就是164天整合的那些已经实现了的业务。但是只是查询出来了,现在还要将这些数据一一对.....
  • java将request接受数据转换成map

    万次阅读 2017-05-23 19:26:51
    如果前端传给了你五个以上的参数,你又没有对应的实体类接受,这个时候,你可以用request去接受,然后通过这个方法转换成map /** * 从request中获得参数Map,并返回可读的Map * * @param request * @...
  • 为接口声明许多只用一次的实体类而造成的啰嗦代码,在Java 8之前可以用匿名类来减少。 Java API包含很多可以用不同行为进行参数化的方法,包括排序、线程和GUI处理。 举个例子,应对需求的不断变化,现在一位农民想...
  • 接受参数以及数据回显 User.java 在上一节的aaoo例子中,新建一个com.pojo包,在包新建一个实体类 package com.pojo; public class User { private int id; private String name; private String pwd; public ...
  • Java实体类 public class HouseResult { private Integer id; @ApiModelProperty(value = "管理该房源的中介编号") private Integer aId; @ApiModelProperty(value = "小区编号") private Integer cId; @...
  • 行为参数化 行为参数化是一个很有用的模式,它能够轻松地适应不断变化的需求。这种模式可以把一个行为(一段代码)封装起来,并通过传和使用创建的行为(例如对Apple的不同谓词)...为接口声明许多只用一次的实体类
  • 行为参数化是用来处理频繁变更的需求的一种软件开发模式。拿出一个代码块,把它准备好却不去执行...但在java 8之前实现起来很啰嗦,为借口生命许多只用一次的实体类而造成的啰嗦代码,在java 8之前可以用匿名类来减...
  • 所谓ModelDriven ,意思是直接把实体类当成页面数据的收集对象。比如,有实体类User 如下: [code="java"] package cn.com.leadfar.struts2.actions; public class User { private ...
  • 目录 0、接受表单数据 1、效果 2、pojo 3、addProduct.jsp 4、ProductController ...0、接受表单数据 ...浏览器提交数据是非常常见的场景,本例演示用户提交产品名称和价格到Spring MVC ...实体类Product package po..
  • java源码包---java 源码 大量 实例

    千次下载 热门讨论 2013-04-18 23:15:26
    Java 组播组中发送和接受数据实例 3个目标文件。 Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密  Java非...
  • 前提: 前端传来string,采用ajax,post请求 后端(springboot 采用@RequestBody 接受对象) 后台报错: JSON parse error: Cannot deserialize ...实体类时间属性加上此注释: @JsonFormat(shape = JsonFor...
  • java.lang.Class的getTypeParameters()方法用于获取此实体的类型参数。该实体可以是,数组,接口等。该方法返回表示类型变量的TypeVariable对象的数组。用法:public TypeVariable> getTypeParameters()参数:...
  • java.lang.Class的getSuperclass()方法用于获取此实体的超类。该实体可以是,数组,接口等。该方法返回此实体的超类。用法:public Class getSuperclass()参数:此方法不接受任何参数。返回值:此方法返回此实体...
  • java.lang.Class的getClassLoader()方法用于获取此实体的classLoader。该实体可以是,数组,接口等。该方法返回此实体的classLoader。用法:public ClassLoader getClassLoader()参数:此方法不接受任何参数。...
  • java.lang.Class的getPackage()方法用于获取此实体的包。该实体可以是,数组,接口等。该方法返回该实体的包。用法:public Package getPackage()参数:此方法不接受任何参数。返回值:此方法返回此实体的包。...
  • java.lang.Class的getPackageName()方法用于获取此实体的包名称。该实体可以是,数组,接口等。该方法以String形式返回此实体的包名称。用法:public String getPackageName()参数:此方法不接受任何参数。返回值...
  • springmvc接收请求参数 1,使用HttpServletRequest接收请求参数 适用于get,post提交方法 2,使用@RequestParam接收请求参数 适用于get post提交方式,并且...5,使用封装类接受参数 人的属性中拥有一条狗 解决中文乱码问
  • java.lang.Class的hashCode()方法用于获取此实体的hashCode表示形式。此方法返回一个整数值,即hashCode。用法:public int hashCode()参数:此方法不接受任何参数。返回值:此方法返回一个整数值,即hashCode。...
  • java源码包2

    千次下载 热门讨论 2013-04-20 11:28:17
    Java 组播组中发送和接受数据实例 3个目标文件。 Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密  ...
  • java源码包3

    千次下载 热门讨论 2013-04-20 11:30:13
    Java 组播组中发送和接受数据实例 3个目标文件。 Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密  ...
  • java源码包4

    千次下载 热门讨论 2013-04-20 11:31:44
    Java 组播组中发送和接受数据实例 3个目标文件。 Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密  ...
  • JAVA面向对象

    2018-05-02 11:53:33
    一、面向对象基础1.基本概念对象:用来描述客观事物的一个实体,由一组属性和方法构成。:具有相同属性和方法的一组对象的集合。...2.参数参数的方法可以接受用户输入的内容。创建方法时定义的参数叫...
  • 行为参数

    2019-01-02 18:24:00
    1,行为参数化,就是一个方法接受多个不同的行为作为参数,并在内部使用...为接 口声明许多只用一次的实体类而造成的啰嗦代码,在Java 8之前可以用匿名类来减少。  4,Java API包含很多可以用不同行为进行参数化...

空空如也

空空如也

1 2 3 4 5
收藏数 82
精华内容 32
关键字:

java实体类接受参数

java 订阅