• SpringMVC


    处理提交过来的数据

    提交的域名称与方法中的参数名一致

    • 没啥说的,自动封装
    http://localhost:8081/springmvc_2/sout?name=APP&phone=1008611
    @RequestMapping("sout")
    public String test(String name,String phone){
        System.out.println(name);
        System.out.println(phone);
        //不进行任何操作
        return null;
    }
    //输出APP	 1008611
    

    提交的域名称与方法中的参数名不一致

    • 如果取请求过来的name与方法中的参数名不一致,就不能封装上,为NULL

    • 使用@RequestParam注解,将域名称与方法参数进行绑定

    http://localhost:8081/springmvc_2/sout?uuu=PPP&ppp=121212
    @RequestMapping("sout")
    public String test(@RequestParam("uuu") String name, @RequestParam("ppp") String phone){
        System.out.println(name);
        System.out.println(phone);
        //不进行任何操作
        return null;
    }
    

    提交一个对象

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        private Integer id;
        private String name;
        private String pwd;
    }
    http://localhost:8081/springmvc_2/login?id=123&name=Poer&pwd=123
    @RequestMapping("login")
    public String login(User user){
        System.out.println(user);
        return null;
    }
    

    提交的域名城要与封装的实体类属性名一致,不然为null

    自定义工具类实现对象自动封装

    • 工具类
    package com.mlyr.d;
    import java.lang.reflect.Field;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;
    /**
     * @Author 陌路邑人
     * @Date
     * @Project
     */
    public class MapUtils {
        public static Object MapToObject(Map<String, String[]> parameterMap, Class clazz) {
            Set<String> keySet = parameterMap.keySet();//先获取map集合的所有key
            Iterator<String> iterator = keySet.iterator();//迭代这个key
            Object o = null;
            try {
                o = clazz.newInstance();
                while (iterator.hasNext()){
                    String key = iterator.next();//获取map的key
                    Field field = clazz.getDeclaredField(key);//根据key值找到要封装的类对应的属性
                    field.setAccessible(true);//打破封装
                    String[] values = parameterMap.get(key);//根据key获取value
                    Class<?> type = field.getType();//获取属性的数据类型
                    //根据属性的数据类型不同,转换与之对应的数据类型进行封装
                    if (type==Integer.class){
                        field.set(o,Integer.parseInt(values[0]));
                    }else{
                        field.set(o,values[0]);
                    }
                }
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
            return o;
        }
    }
    
    • controller
    @RequestMapping("login")
    public String login(HttpServletRequest request, HttpServletResponse response){
        //获取请求参数map
        Map<String, String[]> parameterMap = request.getParameterMap();
        //自定义对象封装
        User user = (User)MapUtils.MapToObject(parameterMap,User.class);
        System.out.println(user);
        return null;
    }
    

    处理请求中的时间类型数据

    • 首先会报错,Field error in object 'user' on field 'date': rejected value [2021-03-03]; codes [typeMismatch.user.date,typeMismatch.date,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.date,date]; arguments []; default message [date]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.util.Date] for value '2021-03-03'; nested exception is java.lang.IllegalArgumentException]]

    第一种解决方案

    • 需要自定义一个类来处理全局的日期转换,把页面请求过来的字符串转换为Date类型的数据
    package com.mlyr.f;
    import org.springframework.core.convert.converter.Converter;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    /**
     * @Author 陌路邑人
     * @Date
     * @Project  日期转换
     */
    public class DateConvert implements Converter<String, Date> {
        String format1 = "yyyy-MM-dd";
        String format2 = "yyyy/MM/dd";
        SimpleDateFormat format = null;
        @Override
        public Date convert(String source) {
            format = new SimpleDateFormat(format1);
            Date date = null;
            try {
                date = format.parse(source);
            } catch (ParseException e) {
                format = new SimpleDateFormat(format2);
                try {
                    date = format.parse(source);
                } catch (ParseException parseException) {
                    parseException.printStackTrace();
                }
            }
            return date;
        }
    }
    
    • 还要在mvc配置文件中配置
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/mvc
           http://www.springframework.org/schema/mvc/spring-mvc.xsd">
        <!--扫描指定包下加有注解的放入spring容器中-->
        <context:component-scan base-package="com.mlyr.f"/>
        <!--指向自定义的日期转换Bean-->
        <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
        <mvc:default-servlet-handler/>
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/"></property>
            <property name="suffix" value=".jsp"></property>
        </bean>
        <!--配置日期转换器-->
        <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
            <property name="converters">
                <set>
                    <!--注入自定义的日期转换器-->
                    <bean class="com.mlyr.f.DateConvert"></bean>
                </set>
            </property>
        </bean>
    </beans>
    

    第二种解决方案

    • 在实体类上加@DateTimeFormat(pattern = "yyyy-MM-dd")
    • 只能解决局部的类中的日期类型映射
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        private Integer id;
        private String name;
        private String pwd;
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        private Date date;
    }
    

    @RequestBody

    • @RequestBody 注解可以接收json格式的数据,并将其转换成对应的数据类型

    • 在使用之前一定要导入一个依赖,不然会报415错误

    • <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.12.1</version>
      </dependency>
      
    • 还有要设置传过去的是json数据,请求类型为contentType : "application/json;charset=UTF-8"

    • 还有要在mvc配置文件中配置<mvc:annotation-driven/>

    @RequestMapping("app")
    public String app(@RequestBody User user){
        System.out.println("APP+"+user);
        return null;
    }
    <button type="button" id="btn">按钮</button>
    <script>
        $("#btn").click(function (){
            $.ajax({
                url: "app",
                type: "post",
                dataType:"json",
                //headers contentType 选其一设置去请求类型
                // headers: {'Content-type': 'application/json;charset=UTF-8'},
                contentType : "application/json;charset=UTF-8",
                data: JSON.stringify({"name": "ADD", "pwd": "1234"}),
                success: function (data) {
                    alert(data)
                }
            })
        })
    </script>
    

    还有一种是自定义一个消息转换器

    • 自定义消息转换器
    public class UserHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
        @Override
        protected boolean supports(Class<?> clazz) {
            return true;
        }
        @Override
        protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
            System.out.println("=========");
            //获取到从页面传递过来的字符串
            InputStream body = inputMessage.getBody();
            byte[] bytes = new byte[1024];
            body.read(bytes);//将输入流中的数据读到byte数组中去
            String str = new String(bytes).trim();//将数组转换为字符串,并去除掉多余的空格   name=AAA&pwd=123
            String[] strings = str.split("&");//将传过来的字符串先按照&进行分割 {name=AAA,pwd=123}
            Object obj = null;
            try {
                 obj = clazz.newInstance();
                for (String string : strings) {
    
                    String[] ss = string.split("=");//再将分割后的字符串数组再以=进行分割  此时ss[0]=name,ss[1]=AAA
                    Field declaredField = clazz.getDeclaredField(ss[0]);//反射获取对应的属性
                    declaredField.setAccessible(true);//打破封装
                    declaredField.set(obj,ss[1]);//赋值
                }
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
            return obj;
        }
        @Override
        protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
        }
    }
    
    • 在mvc中配置
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/mvc
           http://www.springframework.org/schema/mvc/spring-mvc.xsd">
        <!--扫描指定包下加有注解的放入spring容器中-->
        <context:component-scan base-package="com.mlyr.j"/>
        <mvc:annotation-driven>
            <!--配置消息转换器-->
            <mvc:message-converters register-defaults="true">
                <!--自定义的信息转换器-->
                <bean class="com.mlyr.j.UserHttpMessageConverter">
                    <property name="supportedMediaTypes" >
                        <!--配置转换的数据格式-->
                        <list>
                            <value>application/x-www-form-urlencoded</value>
                        </list>
                    </property>
                </bean>
            </mvc:message-converters>
        </mvc:annotation-driven>
        <mvc:default-servlet-handler/>
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/"></property>
            <property name="suffix" value=".jsp"></property>
        </bean>
    </beans>
    
    • 发送的请求
    <button type="button" id="btn">按钮</button>
    <script>
        $("#btn").click(function (){
            $.ajax({
                url: "app",
                type: "post",
                dataType:"json",
                //headers contentType 选其一设置去请求类型
                // headers: {'Content-type': 'application/json;charset=UTF-8'},
                // contentType : "application/json;charset=UTF-8",
                // data: JSON.stringify({"name": "ADD", "pwd": "1234"}),
                data:{"name": "ADD", "pwd": "1234"},
                success: function (data) {
                    alert(data)
                }
            })
        })
    </script>
    

    注意:

    • 这个自定义的消息转换器只能转换传过来的key=value这种形式的数据,json格式的转换不了
    • 当然他与SpringMVC默认的json格式转换可以共同使用,不影响,传过来的如果是 contentType : "application/json;charset=UTF-8",
      data: JSON.stringify({"name": "ADD", "pwd": "1234"}), 的他就会不走自定义的转换器
    • data:{"name": "ADD", "pwd": "1234"} 会走自定义的消息转换器

    不经风雨,怎见彩虹?
  • 相关阅读:
    设计模式-单例模式
    Java对象声明时:new与null的区别
    Mysql的UseAffectedRows问题 以及其他常见配置说明
    将form表单元素的值序列化成对象
    idea教程视频以及常用插件整理
    Ajax获取Response头信息
    BootstrapTable返回结果集递增序号
    mybaitis动态sql利用bind标签代替%拼接完成模糊查询
    Numpy库使用
    基于socket实现websocket服务
  • 原文地址:https://www.cnblogs.com/MLYR/p/14487014.html
Copyright © 2020-2023  润新知