SpringMVC(六)处理请求3.0

(1)@RequestParam参数绑定
简单的参数可以使用上一节中讲过的自动参数映射,复杂一些的需使用@RequestParam完成,虽然自动参数映射很方便,但有些细节是不能处理的,如参数是否为必须参数,名称没有办法指定,参数的默认值就没有有办法做到了。如果使用@RequestParam可以实现请求参数绑定,Spring MVC会自动查找请求中的参数转类型并将与参数进行绑定,示例代码如下:
1、基本数据类型绑定与注解属性

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/foo")
public class FooController {
    @RequestMapping("/action1")
    public String action1(Model model, @RequestParam(required = false, defaultValue = "99") int id) {
        model.addAttribute("message", id);
        return "foo/index";
    }
}

@RequestParam共有4个注解属性,required属性表示是否为必须,默认值为true,如果请求中没有指定的参数会报异常;defaultValue用于设置参数的默认值,如果不指定值则使用默认值,只能是String类型的。name与value互为别名关系用于指定参数名称。
在这里插入图片描述
(2)List与数组绑定基本数据类型
在上一节中我们使用自动参数映射是不能直接完成List与数组绑定的,结合@RequestParam可以轻松实现,示例代码如下所示:

// List集合与数组类型
    @RequestMapping("/action05")
    public String action05(Model model, @RequestParam("u") List<String> users) {
        model.addAttribute("message", users.get(0) + "," + users.get(1));
        return "foo/index";
    }

在这里插入图片描述
直接在URL中输入测试数据可以绑定成功,使用表单同样可行,页面脚本如下:

<form action="bar/action11" method="post">
    <p>
        <label>爱好:</label> 
        <input type="checkbox" value="15" name="id" />阅读
         <input type="checkbox" value="20" name="id" />上网
         <input type="checkbox" value="73" name="id" />电游
    </p>
    <button>提交</button>
</form>

请求处理方法action代码如下:

// List与数组绑定基本数据类型
    @RequestMapping("/action11")
    public String action11(Model model, @RequestParam("id") List<Integer> ids) {
        model.addAttribute("message", Arrays.deepToString(ids.toArray()));
        return "bar/index";
    }

在这里插入图片描述
(3)@RequestBody
@RequestBody 注解将HTTP请求正文插入方法中,使用适合的 HttpMessageConverter将请求体写入某个对象。
作用:

  1. 该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上;
  2. 再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。

使用时机:

A) GET、POST方式提时, 根据request header Content-Type的值来判断:

application/x-www-form-urlencoded, 可选(即非必须,因为这种情况的数据@RequestParam, @ModelAttribute也可以处理,当然@RequestBody也能处理);
multipart/form-data, 不能处理(即使用@RequestBody不能处理这种格式的数据);
其他格式, 必须(其他格式包括application/json, application/xml等。这些格式的数据,必须使用@RequestBody来处理);

B) PUT方式提交时, 根据request header Content-Type的值来判断:

application/x-www-form-urlencoded, 必须;multipart/form-data, 不能处理;其他格式, 必须;

说明:request的body部分的数据编码格式由header部分的Content-Type指定;

@RequestMapping(value = "user/login")
@ResponseBody
// 将ajax(datas)发出的请求写入 User 对象中
public User login(@RequestBody User user) { 
// 这样就不会再被解析为跳转路径,而是直接将user对象写入 HTTP 响应正文中
return user; 
}

@requestBody注解常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,比如说:application/json或者是application/xml等。一般情况下来说常用其来处理application/json类型。

通过@requestBody可以将请求体中的JSON字符串绑定到相应的bean上,当然,也可以将其分别绑定到对应的字符串上。

$.ajax({
        url:"/login",
        type:"POST",
        data:'{"userName":"admin","pwd","admin123"}',
        content-type:"application/json charset=utf-8",
        success:function(data){
          alert("request success ! ");
        }
    });

action:

  @requestMapping("/login")
    public void login(@requestBody String userName,@requestBody String pwd){
      System.out.println(userName+" :"+pwd);
    }

这种情况是将JSON字符串中的两个变量的值分别赋予了两个字符串,但是呢假如我有一个User类,拥有如下字段:
String userName;
String pwd;
那么上述参数可以改为以下形式:@requestBody User user 这种形式会将JSON字符串中的值赋予user中对应的属性上
需要注意的是,JSON字符串中的key必须对应user中的属性名,否则是请求不过去的。
(3)List与数组直接绑定自定义数据类型与AJAX
上一小节中我们绑定的集合中存放的只是基本数据类型,如果需要直接绑定更加复杂的数据类型则需要使用@RequestBody与@ResponseBody注解了,先解释一下他们的作用:

@RequestBody 将HTTP请求正文转换为适合的HttpMessageConverter对象。
@ResponseBody 将内容或对象作为 HTTP 响应正文返回,并调用适合HttpMessageConverter的Adapter转换对象,写入输出流。

AnnotationMethodHandlerAdapter将会初始化7个转换器,可以通过调用AnnotationMethodHandlerAdapter的getMessageConverts()方法来获取转换器的一个集合 List,7个转换器类型分别是

ByteArrayHttpMessageConverter
StringHttpMessageConverter
ResourceHttpMessageConverter
SourceHttpMessageConverter
XmlAwareFormHttpMessageConverter
Jaxb2RootElementHttpMessageConverter
MappingJacksonHttpMessageConverter

@RequestBody默认接收的Content-Type是application/json,因此发送POST请求时需要设置请求报文头信息,否则Spring MVC在解析集合请求参数时不会自动的转换成JSON数据再解析成相应的集合,Spring默认的json协议解析由Jackson完成。要完成这个功能还需要修改配置环境,具体要求如下:

a)、修改Spring MVC配置文件,启用mvc注解驱动功能,<mvc:annotation-driven />

b)、pom.xml,添加jackson依赖,添加依赖的配置内容如下:

<!--jackson-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.7.4</version>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.7.4</version>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.7.4</version>
    </dependency>

c)、ajax请求时需要设置属性dataType 为 json,contentType 为 ‘application/json;charse=UTF-8’,data 转换成JSON字符串,如果条件不满足有可能会出现415异常。

Action定义的示例代码如下:

// List与数组直接绑定自定义数据类型与AJAX
    @RequestMapping("/action21")
    public void action21(@RequestBody List<Product> products, HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("UTF-8");
        System.out.println(Arrays.deepToString(products.toArray()));
        response.getWriter().write("添加成功");
    }

action21的参数@RequestBody List products是接收从客户端发送到服务器的产品集合,默认的请求内容并非是application/json,而是:application/x-www-form-urlencoded,在参数前增加@RequestBody的作用是让Spring MVC在收到客户端请求时将选择合适的转换器将参数转换成相应的对象。action22的返回值为List,且在方法上有一个注解@ResponseBody,系统会使用jackson将该对象自动序列化成json字符;在客户端请求时设置内容类型为application/json,定义一个myform21.jsp页面,页面的脚本如下所示:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>List与数组直接绑定自定义数据类型与AJAX</title>
</head>
<body>
    <button type="button" "addPdts_click1();">向服务器发送json</button>
    <button type="button" "addPdts_click2();">接收服务器返回的json</button>
    <p id="msg"></p>
    <script type="text/javascript"
        src="<c:url value="/scripts/jQuery1.11.3/jquery-1.11.3.min.js"/>"></script>
    <script type="text/javascript">
        var products = new Array();
        products.push({
            id : 1,
            name : "iPhone 6 Plus",
            price : 4987.5
        });
        products.push({
            id : 2,
            name : "iPhone 7 Plus",
            price : 5987.5
        });
        products.push({
            id : 3,
            name : "iPhone 8 Plus",
            price : 6987.5
        });
        function addPdts_click1() {
            $.ajax({
                type : "POST",
                //请求谓词类型
                url : "bar/action21",
                data : JSON.stringify(products), //将products对象转换成json字符串
                contentType : "application/json;charset=UTF-8",
                //发送信息至服务器时内容编码类型,(默认: "application/x-www-form-urlencoded")
                dataType : "text", //预期服务器返回的数据类型
                success : function(result) {
                    $("#msg").html(result);
                }
            });
        }
        function addPdts_click2() {
            $.ajax({
                type : "POST",
                //请求谓词类型
                url : "bar/action22",
                data : JSON.stringify(products), //将products对象转换成json字符串
                contentType : "application/json;charset=UTF-8",
                //发送信息至服务器时内容编码类型,(默认: "application/x-www-form-urlencoded")
                dataType : "json", //预期服务器返回的数据类型
                success : function(result) {
                    var str = "";
                    $.each(result, function(i, obj) {
                        str += "编号:" + obj.id + ",名称:" + obj.name + ",价格:"+ obj.price + "<br/>";
                    });
                    $("#msg").html(str);
                }
            });
        }
    </script>
</body>
</html>

页面中有两个方法,第一个方法是实现将一个json集合发送到服务器并映射成一个List集合;第二个方法是实现接收服务器返回的json对象。
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值