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="width: 150px">
    <h3>您正在学习的技术方向</h3>
    <select name="course" style="width: 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="width: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="width: 150px">
<h3>联系电话</h3>
<input name="userInfo.mobile" class="text"  style="width: 150px">
<h3>收货地址</h3>
<input name="userInfo.address" class="text"  style="width: 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,一旦增加了对应了日期转换器,那么优先使用转换器类来处理,而直接忽略掉注解。

猜你喜欢

转载自www.cnblogs.com/yangmingxianshen/p/12521520.html