### 1. 接收请求参数

#### 1.1. 【不推荐】 通过HttpServletRequest获取请求参数

假设存在:

    <form action="handle_login.do" method="POST">
<div>请输入用户名</div>
<div><input name="username" /></div>
<div>请输入密码</div>
<div><input name="password" /></div>
<div><input type="submit" value="登录" /></div>
</form>

则在控制器中:

@RequestMapping("handle_login.do")
public String handleLogin() { // 暂不关心后续的页面
return null;
}

当需要处理请求时,可以在方法的参数中添加`HttpServletRequest`,然后,在方法体中,通过该参数获取请求参数:

    @RequestMapping("handle_login.do")
public String handleLogin(
HttpServletRequest request) {
String username = request.getParameter("username");
String password = request.getParameter("password"); System.out.println("username=" + username);
System.out.println("password=" + password); // 暂不关心后续的页面
return null;
}

注意:Spring MVC框架默认使用的编码是ISO-8859-1,是不支持中文的,解决方案再议。

#### 1.2. 【推荐】 直接使用同名参数

在Spring MVC中,也可以直接将请求参数声明为处理请求的方法的参数,例如:

    @RequestMapping("handle_reg.do")
public String handleReg(
String username, String password,
Integer age, String phone,
String email) {
System.out.println("username=" + username);
System.out.println("password=" + password);
System.out.println("age=" + age);
System.out.println("phone=" + phone);
System.out.println("email=" + email); // 暂不关心后续的页面
return null;
}

使用这种做法时,需要保证请求参数的名称与方法参数名称是一致的!如果不一致,则无法获取到对应的参数,且服务器端会视为“客户端并没有提交名为xxx的参数,则值为null。”

这种做法虽然简便,但是,不适合处理请求参数过多的请求,如果某个请求中有10个或更多参数,则处理请求的方法也需要添加这么多参数,是不合适的!

#### 1.3. 【推荐】 通过对象接收请求参数

如果请求参数过多,可以将请求参数封装在某个类型中:

    public class User {

        private String username;
private String password;
private Integer age;
private String phone;
private String email;
// SET/GET
}

然后,在处理请求时,将该类型作为方法的参数即可:

    @RequestMapping("handle_reg.do")
public String handleReg(User user) {
System.out.println(user); // 暂不关心后续的页面
return null;
}

在使用这种做法时,也需要保证名称的统一!

#### 1.4. 小结

以上3种做法,除了第1种比较麻烦以外,另2种做法,请根据具体情况选择性的使用,甚至这2种做法可以混合使用,处理请求时,参数不区分先后顺序。

当然,第1种做法也不是完全没有用武之地,在除了控制器以外的组件中依然可能需要使用。

### 2. 转发数据

#### 2.1. 通过HttpServletRequest对象转发

Spring MVC处理请求时,默认的返回即表示“转发”,所以,返回值应该理解为:处理完请求之后转发到的JSP文件的名称。

当需要转发数据时,直接将数据封闭在`HttpServletRequest`对象中即可:

request.setAttribute("msg", message);

后续,并不需要获取转发器执行转发!在SpringMVC中返回时,就会将数据进行转发的操作!

#### 2.2. 【不推荐】 使用ModelAndView转发

在ModelAndView中,model表示的就是转发的数据,而view表示的就是转发的目标JSP页面,在使用时:

    @RequestMapping("handle_login.do")
public ModelAndView handleLogin(
String username, String password) {
String viewName = null;
String message = null;
Map<String, Object> model
= new HashMap<String, Object>();
if ("root".equals(username)) {
if ("1234".equals(password)) {
// ...
} else {
viewName = "error";
message = "[2] 密码错误!";
model.put("msg", message);
}
} else {
viewName = "error";
message = "[2] 用户名不存在!";
model.put("msg", message);
} ModelAndView mav
= new ModelAndView(viewName, model); return mav;
}

#### 2.3. 使用ModelMap

`ModelMap`的使用方式与`HttpServletRequest`几乎相同:

    @RequestMapping("handle_login.do")
public String handleLogin(
String username, String password,
ModelMap modelMap) {
String message = null;
if ("root".equals(username)) {
if ("1234".equals(password)) {
// ...
} else {
message = "[3] 密码错误!";
modelMap.addAttribute("msg", message);
return "error";
}
} else {
message = "[3] 用户名不存在!";
modelMap.addAttribute("msg", message);
return "error";
}
return null;
}

### 3. 重定向

在控制器中处理请求时,如果需要重定向,方法的返回值应该是`String`,则值应该是`redirect:目标资源`,关于**目标资源**的表示,可以使用相对路径,也可以使用绝对路径,例如使用相对路径时可以返回`"redirect:index.do"`。

### 4. 关于@RequestMapping

`@RequestMapping`注解的作用主要是配置映射的路径。

该注解既可以添加在类之前,也可以添加在方法之前!例如:

    @Controller
@RequestMapping("user")
public class UserController { @RequestMapping("reg.do")
public String showReg() {
return "reg";
} }

以上配置后,访问时,所使用的URL应该是`http://localhost:8080/PROJECT/user/reg.do`。

在类之前使用该注解,可以简化每个方法之前的注解,例如,在类之前没有注解时,可能配置为: 

@RequestMapping("user_list.do")
@RequestMapping("user_info.do")
@RequestMapping("news_list.do")
@RequestMapping("news_info.do")

如果在类和方法之前都加注解,就可以:

@RequestMapping("user")
@RequestMapping("list.do")
@RequestMapping("info.do")

@RequestMapping("news")
@RequestMapping("list.do")
@RequestMapping("info.do")

所以,一般,推荐每个控制器只处理相关数据,例如`UserController`控制器只处理与`User`相关的请求,而`NewsController`控制器只处理与`News`相关的请求,并且,每个类之前都添加`@RequestMapping`注解。

在配置路径时,并没有明确要求类的注解和方法的注解中是否使用`/`路径分隔符,例如以下4种配置是完全等效的:

@RequestMapping("user") @RequestMapping("list.do")
@RequestMapping("/user") @RequestMapping("/list.do")
@RequestMapping("/user") @RequestMapping("list.do")
@RequestMapping("user") @RequestMapping("/list.do")

使用`@RequestMapping`注解还可以限制请求方式,例如:

@RequestMapping(value="路径", method=RequestMethod.POST)

对于以上映射路径,如果尝试进行GET请求,则会出现405错误:

HTTP Status 405 - Request method 'GET' not supported

**小结**

`@RequestMapping`主要用于配置请求路径,在实际应用时,首先,每个控制器类之前都应该添加该注解,用于配置路径中间层,然后,每个控制器类只处理1种数据相关的请求,每个处理请求的方法之前必须再使用该注解配置具体路径,可根据实际情况选择配置该注解的`method`属性,以限定请求方式。

关于`@RequestMapping`的`value`属性和`method`属性的值,都可以是数组。

从Spring 4.3起,另有`@GetMapping`和`@PostMapping`,等效于限制了请求方式的`@RequestMapping`,即`@GetMapping("路径") = @RequestMapping(value="路径", method=RequestMethod.GET)`。使用这些注解时,需要在Spring的配置文件中添加注解驱动`<mvc:annotation-driven />`。

### 5. 关于@RequestParam注解

`@RequestParam`注解是添加在处理请求的方法的参数之前的注解!

使用`@RequestParam`可以解决客户端提交的参数名与服务器端处理请求时方法的参数名不一致的问题:

    @PostMapping("handle_login.do")
public String handleLogin(
String username,
@RequestParam("pwd") String password) {
System.out.println("username=" + username);
System.out.println("password=" + password);
return null;
}

当使用了`@RequestParam`注解后,默认情况下,参数是必须提交的,如果客户端提交的请求中并不包含该名称的参数,则会报告400错误:

HTTP Status 400 - Required String parameter 'pwd' is not present

如果并不强制要求客户端提交某参数,可以:

@RequestParam(value="pwd", required=false)

通过该注解,还可以通过`defaultValue`属性来配置**默认值**,即客户端没有提交参数值时,服务器端视为提交了默认的某个值:

@RequestParam(value="pwd", required=false, defaultValue="111111")

注意:当使用`defaultValue`时,必须显式的将`required`属性设置为`false`,否则,如果没有设置,默认是必须提交参数值的,那么,默认值就没有意义了!

**小结**

关于`@RequestParam`注解的应用场景,可以是:

- 客户端提交的参数名与服务器端使用的方法的参数名不一致时;
- 要求客户端必须提交某些参数时;
- 为某些参数设置默认值时。

转发与重定向的核心区别在于客户端请求了几次!在转发的处理过程中,客户端其实只发出了1次请求,而在重定向中,客户端发出了2次请求!

转发是发生在服务器内部的!所以,转发时的URL并不会发生变化!并且,JSP文件可以存放在WEB-INF目录下(该目录是不允许通过http协议访问的)。由于转发是在服务器内部完成的,所以,组件之间(控制器与JSP)可以直接传递数据。

重定向的本质是第1次请求时,服务器端可能无法完全全部的处理,所以,服务器向客户端响应了重定向(通常响应码是302),客户端得到这第1次的响应结果时,由于响应码表示的是重定向,所以,会再次发生第2次请求,以尝试得到最终的响应结果。由于客户端发出了第2次请求,所以,在重定向时,URL是会发生变化的!并且,两次请求之间的数据默认是无法共享或传递的!

如果希望URL发生变化,必须使用重定向!

如果有大量的数据需要传递,可以考虑使用转发!

控制器处理好的数据,不便于在JAVA中编写如何显示,则应该转发给JSP页面!

枚举

    gender; // 性别

    String gender = "男"; // "女","帅哥"/"美女","先生"/"女士"

    int gender = 1;

    public enum Gender {
MALE, FEMALE
} if (gender == Gender.MALE) {
System.out.println("先生,您好!");
} else {
System.out.println("女士,您好!");
}

springMVC中接收请求参数&&数据转发的更多相关文章

  1. SpringMVC中post请求参数注解@requestBody使用问题

    一.httpClient发送Post 原文https://www.cnblogs.com/Vdiao/p/5339487.html public static String httpPostWithJ ...

  2. SpringMVC之接收请求参数和页面传参

    1.Spring接收请求参数 1>.使用HttpServletRequest获取 @RequestMapping("/login.do") public String log ...

  3. springMVC中接收数组参数

    方式一. 后台:public ResultBean queryItemRulesByItemIds(int userId, int[] itemIds) 方式二.

  4. SpringMVC——接收请求参数和页面传参

    Spring接收请求参数: 1.使用HttpServletRequest获取 @RequestMapping("/login.do") public String login(Ht ...

  5. SpringMVC接收请求参数和页面传参

    接收请求参数: 1,使用HttpServletRequest获取 @RequestMapping("/login.do") public String login(HttpServ ...

  6. Struts系列笔记(6)---action接收请求参数

    action接收请求参数 在web开发中,去接收请求参数来获得表单信息非常的常见,自己也总结整理了有关Struts2通过action接收请求参数的几种方法. Struts2 提供三种数据封装的方式: ...

  7. struts2 action接收请求参数和类型转换

    1,action接收请求参数 在struts2中action是什么?(struts2是一个mvc框架)         V:jsp        M:action         C:action  ...

  8. 【Java框架型项目从入门到装逼】第五节 - 在Servlet中接收和返回数据

    在上一节的程序中,我们可以看到HttpServletRequest, HttpServletResponse这两个对象.可以说,这是JavaWeb中至关重要的两个对象.接下来,我们来做一个简短的说明: ...

  9. Struts框架(6)---action接收请求参数

    action接收请求参数 在web开发中,去接收请求参数来获得表单信息非常的常见,自己也总结整理了有关Struts2通过action接收请求参数的几种方法. Struts2 提供三种数据封装的方式: ...

随机推荐

  1. 进程 multiprocessing详解

    一 ,核心 就是像线程一样管理进程 ,类似于threading ,cup利用率较好,该模块用来跨平台的多进程模块,含有一个Process 类代表进程对象,start() 启动进程 Process语法结 ...

  2. cf547D. Mike and Fish(欧拉回路)

    题意 题目链接 Sol 说实话这题我到现在都不知道咋A的. 考试的时候是对任意相邻点之间连边,然后一分没有 然后改成每两个之间连一条边就A了.. 按说是可以过掉任意坐标上的点都是偶数的数据啊.. #i ...

  3. javascript统计一个字符在一段字符串出现次数

      <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" ...

  4. JVM Guide

    Java Virtual Machine: the Essential Guide October 8th, 2014 - By Alexey Zhebel Introduction Java Vir ...

  5. Popularize what is heart of mobile phone?

    From: http://tech.sina.com.cn/mobile/n/2014-09-29/08399657494.shtml 只谈核数没意义 带你重新认识手机SoC 2014年09月29日  ...

  6. 多线程(二)~Thread类相关的API介绍

      一.线程安全问题:     当我们使用多个线程操作统一方法内的局部变量的时候,每个局部变量在当前线程里都有自己的副本,这种情况是不会出现线程安全问题的.当我们两个线程同时操作全局变量的时候,有可能 ...

  7. rel 属性<small>H5保留属性</small>

    源文件

  8. June 13th 2017 Week 24th Tuesday

    There are no regrets in life, just lessons. 人生中没有后悔,只有教训. Some people can learn from their past mist ...

  9. 【转】OpenGL概述

    英文原文 中文译文 1. 计算机图像硬件 1.1 GPU(图像处理单元) 如今,计算机拥有用来专门做图像处理显示的GPU模块,拥有独立的图像处理储存(显存). 1.2 像素和画面 任何图像显示都是基于 ...

  10. C++ double 小数精度控制

    第一种方法:cout<<fixed<<setprecision(20)<<mydouble<<endl; #include <iostream&g ...