• Java——Spring MVC数据绑定


    1.URL Mapping(URL映射)

    URL Mapping指将URL与Controller方法绑定。
    通过将URL与方法绑定,SpringMVC便可通过Tomcat对外暴露服务。

    1)@GetMapping 绑定Get请求

    @GetMapping("/g")
    @ResponseBody
    public String getMapping(){
        return "This is get method";
    }

    2)@PostMapping 绑定Post请求

    @PostMapping("/p")
    @ResponseBody
    public String postMapping(){
        return "This is post mathod";
    }

    再访问Post请求的时候,我们可以使用form表单或者postman
    form表单:

    <div>
        <form action="/p" method="post">
            <input type="submit" value="submit">
        </form>
    </div>

    postman:

    3)@RequestMapping 通用绑定

    (1)如果直接定义在类上,这是给类下面的所有逻辑处理增加URL前缀

    @Controller
    @RequestMapping("/test")
    public class URLMappingController {
        @GetMapping("/g")
        @ResponseBody
        public String getMapping(){
            return "This is get method";
        }
    
        @PostMapping("/p")
        @ResponseBody
        public String postMapping(){
            return "This is post mathod";
        }
    }

    那么在访问路径下面都需要添加前缀:

     (2)还可以直接定义在具体方法上面,功能与GetMapping与PostMapping一样

    @Controller
    public class URLMappingController {
    //    @GetMapping("/g")
        @RequestMapping("/g")
        @ResponseBody
        public String getMapping(){
            return "This is get method";
        }
    }

    如果这样定义将不区分是post方法还是get方法:

    也可以通过下面方式来指定具体请求方式: 

    public class URLMappingController {
    //    @GetMapping("/g")
        @RequestMapping(value = "/g",method = RequestMethod.GET)
        @ResponseBody
        public String getMapping(){
            return "This is get method";
        }
    }

    2.Controller方法参数接收

    在spring中要接受请求参数有两种做法:
      a.使用Controller方法参数接收
      b.使用Java Bean接受数据

    (1)Controller方法参数接受

    @Controller
    public class URLMappingController {
        @PostMapping("/p")
        @ResponseBody
        public String postMapping(String name,String password){
            return name + ":" + password;
        }
    }

    访问:

     需要注意的是:
    public String postMapping(String name,String password)
    我们这里输入的是数字,接收的是字符串,这是spring帮我们完成的强转。
    但是强转可能出现问题。

    get的参数传递是在url中拼接:
    例如:localhost:8080/g?name=kebi&password=123456

    @Controller
    public class URLMappingController {
        @GetMapping("/g")
        @ResponseBody
        public String getMapping(String name, String password){
            return name + ":" + password;
        }
    }

    如果我们在传参的时候:
    localhost:8080/g?nameOld=kebi&password=123456
    这样不符合URL的定义规则,虽然不会报错。
    如果改成这样:
    localhost:8080/g?nameo_ld=kebi&password=123456
    java那边也会不符合命名规范:
    public String getMapping(String name_old, String password)
    所以可以使用注解映射:
    public String getMapping(@RequestParam("name_old") String nameOld, String password)

    (2)使用Java Bean来接受请求的参数

    如果一个请求里面传入了100个参数,那么使用Controller就会现在繁琐,因此我们可以将所有参数封装到一个对象,
    这样在对象管理上面会方便很多。
    创建User实体类:

    public class User {
        private String name;
        private String password;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    }

    然后就可以使用对象来接收参数:

    @PostMapping("/p1")
    @ResponseBody
    public String postMapping1(User user){
        return user.getName() + ": " + user.getPassword();
    }

    当我们在请求这个URL的时候,spring MVC会自动创建实体对象,并将参数填充到User对象同名的参数中。

    public String postMapping1(User user,String name)
    如果我们在实体类之外在定义一个相同的参数,那么SpringMVC在填充的时候

    只要是URL中同名的参数都会进行赋值,不论是实体类中的参数还是自定义的参数。

    3.接收复合表单数据

    利用数组或者List接收请求中的复合数据
    利用@RequestParam为参数设置默认值
    使用Map对象接收请求参数及注意事项
    绝对路径与相对路径吗:

     一般在提交数据的时候,可能并不简单:

     当有多个复选按钮的时候,可能会一次提交多个数据

    <form action="./apply" method="post">
        <h3>您的姓名</h3>
        <input name="name" class="text"  style=" 150px">
        <h3>您正在学习的技术方向</h3>
        <select name="course" style=" 150px">
            <option value="java">Java</option>
            <option value="h5">HTML5</option>
            <option value="python">Python</option>
            <option value="php">PHP</option>
        </select>
        <div>
            <h3>您的学习目的:</h3>
            <input type="checkbox" name="purpose" value="1">就业找工作
            <input type="checkbox" name="purpose" value="2">工作要求
            <input type="checkbox" name="purpose" value="3">兴趣爱好
            <input type="checkbox" name="purpose" value="4">其他
        </div>
        <div style="text-align: center;padding-top:10px" >
            <input type="submit" value="提交" style="100px">
        </div>
    </form>

    (1)使用list接收

    @PostMapping("/apply")
    @ResponseBody
    public String apply(String name,String course,Integer[] purpose){
        System.out.println(name);
        System.out.println(course);
        for (Integer p: purpose){
            System.out.println(p);
        }
        return "apply test";
    }

    我们还可以设置默认值:
    public String apply(@RequestParam(defaultValue = "ANON") String name, String course, Integer[] purpose)
    这样如果前端不传参数,那么将会使用ANON默认值。

    (2)使用List集合接收

    public String apply(String name, String course, @RequestParam List<Integer> purpose)
    只需要增加@RequestParam注解,spring才知道需要使用List集合来进行存储。

    其实也可以使用对象接收:

    public class Form {
        private String name;
        private String course;
        private List<Integer> purpose;
    }

    控制器书写方式与前面类似。

    @PostMapping("/apply")
    @ResponseBody
    public String apply(Form form){
        System.out.println(form.getName());
        System.out.println(form.getCourse());
        for (Integer p: form.getPurpose()){
            System.out.println(p);
        }
        return "apply test";
    }

    (3)使用Map注意事项

    在使用map接收数据时,Map会无法接收复合数据的。

    4.关联对象赋值

    将关联对象的对象名放在表单参数名的前面,就可以给关联对象赋值。

    public class Form {
        private String name;
        private String course;
        private List<Integer> purpose;
        private UserInfo userInfo=new UserInfo();
    }
    
    public class UserInfo {
        private String name;
        private String mobile;
        private String address;
    }

    表单传参的时候需要注意:

    <h3>收货人</h3>
    <input name="userInfo.name" class="text"  style=" 150px">
    <h3>联系电话</h3>
    <input name="userInfo.mobile" class="text"  style=" 150px">
    <h3>收货地址</h3>
    <input name="userInfo.address" class="text"  style=" 150px">   

    这样就可以取出数据。

    5.日期类型数据转换

    1)@DateTimeFormat注解

    如果前面传一个时间参数:
    <input type="text" name="date">
    后台直接使用date对象进行接收,那样肯定会强转失败:
    public String postMapping(String name, String password, Date date)

     400错误一般是由于强转失败。
    可以使用@DateTimeFormat这个注解,pattern表示接收格式:
    public String postMapping(String name, String password, @DateTimeFormat(pattern = "yyyy-MM-dd") Date date)
    将其封装成为对象也是可行的:

    将其封装成为对象也是可行的:
    public class User {
        private String name;
        private String password;
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        private Date date;
    }

    只是也需要加上@DateTimeFormat这个注解。

    @PostMapping("/p")
    @ResponseBody
    public String postMapping(User user){
        System.out.println(user.getName());
        System.out.println(user.getPassword());
        System.out.println(DateFormat.getDateInstance().format(user.getDate()));
        return "date test";
    }

    2)Converter全局转换器

    如果每一个时间我需要进行时间注解,那也太麻烦了。
    因此我们可以设置一个全局默认的时间转换器。

    (1)创建转换器

    新建converter这个包,以及转换器类MyDateConverter:

    /*
    * 实现日期转换器的要点有三个:
    * 1.实现Converter这个接口
    * 2.Converter<String, Date>有两个范型
    * 3.必须要实现convert这个接口
    * */
    
    public class MyDateConverter implements Converter<String, Date> {
        public Date convert(String s){  //s表示输入的字符串
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            try {
                Date d = sdf.parse(s);  //格式转换
                return d;
            } catch (ParseException e){
                return null;  //如果输入的字符串格式不对,直接返回null
            }
        }
    }

    (2)注册使用

    在applicationContext.xml中配置:

    <!--FormattingConversionServiceFactoryBean通知MVC有哪些自定义的转换类-->
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <!--转化类定义-->
        <property name="converters">
            <set>
                <bean class="com.ikidana.springmvc.converter.MyDateConverter"/>
            </set>
        </property>
    </bean>
    
    <mvc:annotation-driven conversion-service="conversionService"/>

    spring mvc在遇到类型转换的时候,一旦遇到date类型,就会使用MyDateConverter这个类进行转换。

    那么如果既使用了@DateTimeFormat这个注解,又使用了全局转换器,那么以谁为准了?
    对于SpringMVC,一旦增加了对应了日期转换器,那么优先使用转换器类来处理,而直接忽略掉注解。

  • 相关阅读:
    python学习之路-day3
    python学习之路-day2
    python学习之路-day1
    Hystrix断路器
    jmater的使用
    记录1
    springcloud-Gateway
    Quartz框架
    红黑树的左旋和右旋
    异步回调CompletableFuture
  • 原文地址:https://www.cnblogs.com/yangmingxianshen/p/12521520.html
Copyright © 2020-2023  润新知