Spring MVC 学习总结(三)——请求处理方法Action详解

目录

  • 一、Action参数类型
    • 1.1、自动参数映射
      • 1.1.1、基本数据类型
      • 1.1.2、自定义数据类型
      • 1.1.3、复杂数据类型
      • 1.1.4、List集合类型
      • 1.1.5、Map集合类型
    • 1.2、@RequestParam参数绑定
      • 1.2.1、基本数据类型绑定与注解属性
      • 1.2.2、List与数组绑定基本数据类型
      • 1.2.3、List与数组直接绑定自定义数据类型与AJAX
    • 1.3、重定向与Flash属性
    •  1.4、@ModelAttribute模型特性
      • 1.4.1、注解在参数上
      • 1.4.2、注解在方法上
  • 二、Action返回值类型
    • 2.1、视图中url问题
    • 2.2、返回值为String
      • 2.2.1、String作为视图名称
      • 2.2.2、String作为内容输出
    • 2.3、返回值为void
      • 2.3.1、方法名默认作为视图名
      • 2.3.2、直接响应输出结果
    • 2.4、返回值为ModelAndView
    • 2.5、返回值为Map
    • 2.6、返回值为任意类型
      •  2.6.1、返回值为基本数据类型
      • 2.6.2、当返值为自定义类型
    • 2.7、返回值为Model类型
    • 2.8、小结
  • 三、示例下载

Spring MVC中每个控制器中可以定义多个请求处理方法,我们把这种请求处理方法简称为Action,每个请求处理方法可以有多个不同的参数,以及一个多种类型的返回结果。

一、Action参数类型

如果在请求处理方法中需要访问HttpSession对象,则可以添加HttpSession作为参数,Spring会将对象正确的传递给方法,如:public  String action(HttpSession session);若需要访问客户端语言环境和HttpServletRequest对象,则可以在方法签名上包含这样的参数,如:public String action(HttpServletRequest request,Locale locale)。可以在请求中出现的参数类型有:

org.springframework.web.context.request.WebRequest
org.springframework.web.context.request.NativeWebRequest
java.util.Locale 当前请求的语言环境
java.util.TimeZone 时区
java.io.InputStream或java.io.Reader
java.io.OutputStream或java.io.Writer
org.springframework.http.HttpMethod
java.security.Principal
HttpEntity 参数用于访问Servlet的HTTP请求的标题和内容
java.util.Map / org.springframework.ui.Model / org.springframework.ui.ModelMap 视图隐含模型
org.springframework.web.servlet.mvc.support.RedirectAttributes 重定向
命令或表单对象
基本数据类型,如int,String,double...
复杂数据类型,如自定义的POJO对象
HandlerAdapter
org.springframework.validation.Errors / org.springframework.validation.BindingResult 验证结果
org.springframework.web.bind.support.SessionStatus 会话状态
org.springframework.web.util.UriComponentsBuilder
@PathVariable 注解参数访问URI模板变量。
@MatrixVariable 注释参数用于访问位于URI路径段键值对对,矩阵变量。
@RequestParam 注解参数访问特定的Servlet请求参数,请求参数绑定。
@RequestHeader 注解参数访问特定的se​​rvlet请求HTTP标头,映射请求头。
@RequestBody 注解参数访问HTTP请求主体,注解映射请求体
@RequestPart 注解参数访问“的multipart / form-data的”请求部分的内容。处理客户端上传文件,多部分文件上传的支持
@SessionAttribute 注解参数会话属性
@RequestAttribute 注解参数访问请求属性

1.1、自动参数映射

1.1.1、基本数据类型

方法的参数可以是任意基本数据类型,如果方法参数名与http中请求的参数名称相同时会进行自动映射,视图foo目录下的index.jsp与示例代码如下:

  // 自动参数映射
    @RequestMapping("/action0")
    public String action0(Model model, int id, String name) {
        model.addAttribute("message", "name=" + name + ",id=" + id);
        return "foo/index";
    }
<%@ 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>Footitle>
head>
<body>
${message}
body>
html>

 

运行结果如下:

Spring MVC 学习总结(三)——请求处理方法Action详解_第1张图片

包装类型也一样,但如果参数中没有对应名称与类型的数据则会异常。

1.1.2、自定义数据类型

除了基本数据类型,也可以自定义的数据类型,如一个自定义的POJO对象,Spring MVC会通过反射把请中的参数设置到对象中,转换类型,示例代码如下:

  // 自动参数映射自定义数据类型
    @RequestMapping("/action01")
    public String action01(Model model, Product product) {
        model.addAttribute("message", product);
        return "foo/index";
    }

运行结果如下:

Spring MVC 学习总结(三)——请求处理方法Action详解_第2张图片

示例中使用的是的URL中的参数,其实也可以是客户端提交的任意参数,特别是表单中的数据。

1.1.3、复杂数据类型

这里指的复杂数据类型指的是一个自定义类型中还包含另外一个对象类型,如用户类型中包含产品对象:

package com.zhangguo.springmvc03.entities;

public class User {
    private String username;
    private Product product;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }
}
// 自动参数映射复杂数据类型
    @RequestMapping("/action02")
    public String action02(Model model, User user) {
        model.addAttribute("message", user.getUsername() + "," + user.getProduct().getName());
        return "foo/index";
    }

测试运行结果:

Spring MVC 学习总结(三)——请求处理方法Action详解_第3张图片

为了方便这里我使用的是url,这里当然可以是一个表单,如下代码所示:

<form method="post" action="foo/action02">
     username:<input name="username" /><br/>
     pdctname:<input name="product.name" /><br/>
    <button>提交button>
form>

1.1.4、List集合类型

不能直接在action的参数中指定List类型,定义一个类型包装List集合在其中,ProductList类如下所示:

package com.zhangguo.springmvc03.entities;

import java.util.List;

//产品集合
public class ProductList {
    private List items;

    public List getItems() {
        return items;
    }

    public void setItems(List items) {
        this.items = items;
    }
}

定义的action代码如下所示:

    // 集合类型
    @RequestMapping("/action03")
    public String action03(Model model, ProductList products) {
        model.addAttribute("message", products.getItems().get(0) + "
" + products.getItems().get(1)); return "foo/index"; }

在url中模拟表单数据,提交后的结果如下所示:

Spring MVC 学习总结(三)——请求处理方法Action详解_第4张图片

这里同样可以使用一个表单向服务器提交数据。

1.1.5、Map集合类型

Map与List的实现方式基本一样,这里先定义了一个包装Map的类型ProductMap,代码如下所示:

package com.zhangguo.springmvc03.entities;

import java.util.Map;

/**
 * * 产品字典
 */
public class ProductMap {
    private Map items;

    public Map getItems() {
        return items;
    }

    public void setItems(Map items) {
        this.items = items;
    }
}

Action的定义如下:

// Map类型
    @RequestMapping("/action04")
    public String action04(Model model, ProductMap map) {
        model.addAttribute("message", map.getItems().get("p1") + "
" + map.getItems().get("p2")); return "foo/index"; }

测试运行结果如下:

Spring MVC 学习总结(三)——请求处理方法Action详解_第5张图片

集合类型基本都一样,set也差不多,问题是如果为了获得一个集合需要刻意去包装会很麻烦,可以通过@RequestParam结合@RequestBody等注解完成。

1.2、@RequestParam参数绑定

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

1.2.1、基本数据类型绑定与注解属性

package com.zhangguo.springmvc03.controllers;

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互为别名关系用于指定参数名称。

运行结果:

Spring MVC 学习总结(三)——请求处理方法Action详解_第6张图片

Spring MVC 学习总结(三)——请求处理方法Action详解_第7张图片

1.2.2、List与数组绑定基本数据类型

在上一节中我们使用自动参数映射是不能直接完成List与数组绑定的,结合@RequestParam可以轻松实现,示例代码如下所示:

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

运行结果:

Spring MVC 学习总结(三)——请求处理方法Action详解_第8张图片

直接在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 ids) {
        model.addAttribute("message", Arrays.deepToString(ids.toArray()));
        return "bar/index";
    }

运行结果:

Spring MVC 学习总结(三)——请求处理方法Action详解_第9张图片

Spring MVC 学习总结(三)——请求处理方法Action详解_第10张图片

@RequestParam("id")是必须的,因为页面中的表单name的名称为id,所有服务器在收集数据时应该使用id页非ids,如果同名则可以省去。

1.2.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注解驱动功能,

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

    
    <dependency>
        <groupId>com.fasterxml.jackson.coregroupId>
        <artifactId>jackson-coreartifactId>
        <version>2.5.2version>
    dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.coregroupId>
        <artifactId>jackson-databindartifactId>
        <version>2.5.2version>
    dependency>

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

Action定义的示例代码如下:

    // List与数组直接绑定自定义数据类型与AJAX
    @RequestMapping("/action21")
    public void action21(@RequestBody List 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与数组直接绑定自定义数据类型与AJAXtitle>
head>
<body>
    <button type="button" onclick="addPdts_click1();">向服务器发送jsonbutton>
    <button type="button" onclick="addPdts_click2();">接收服务器返回的jsonbutton>
    <p id="msg">p>
    <script type="text/javascript"
        src="/scripts/jQuery1.11.3/jquery-1.11.3.min.js"/>">
    
                    
                    

你可能感兴趣的:(Spring MVC 学习总结(三)——请求处理方法Action详解)