一、springmvc中的转发和重定向:
return “视图名”:默认是转发。
SpringMVC页面转发:
服务器内部跳转(forward)和 客户端重定向(redirect)
1) 转发
(1) 转发到JSP页面: 请求处理方法返回字符串,默认使用服务器内部跳转 ( request.getRequestDispatcher(“指定页面”).forward(request,response) )
示例: return “hello”; (视图名: 视图解析器会根据视图名拼接成正确的访问路径 " /hello.jsp")
(2)转发到服务器内部的请求:在返回的字符串前面加入 “ forward:/ 路径名 ”
示例: return " forward:/ main "( 在服务器内部跳转到名为 main 的请求处理方法中)
2)重定向
(1)重定向到 JSP页面:在返回字符串的前面加上 “ redirect:/xxx.jsp ”
示例:return " redirect:/xxx.jsp "
注意: 由于客户端重定向(redirect)相当于在浏览器重新发一次请求,所以不能访问 WEB-INF 下的资源文件,而且资源文件必须写完整(xxx.jsp),因为此时的视图解析器不会将该字符串进行解析,拼接
(2)重定向到 Controller 上 : 在返回的字符串前面加上 “ redirect:/路径名 ”
示例: return " redirect:/main "; ( 客户端重定向到名为 main 的请求处理方法中 )
二、springmvc数据绑定:
数据绑定介绍:
springmvc会根据客户端请求参数的不同,将请求消息中的信息以一定的方式转换并绑定到Controller控制器类的方法参数中。
在数据绑定的过程中,springmvc框架会通过数据绑定组件DataBinder将请求参数串的内容进行类型转换,然后赋值给controller类中方法的形参,这样后台就可以获取前端请求的参数了。
简单数据绑定:
简单数据绑定,指的是集中基本类型数据和String类型的绑定。
当前端请求的参数比较简单时,可以在后台方法的形参中直接使用springmvc提供的默认的参数类型进行数据绑定。
如可以直接在请求的方法的参数上使用原生的API进行参数绑定:HttpServletRequest(通过请求对象获取请求信息),HttpServletResponse(处理响应的信息),HttpSession(通过session对象获取session中的信息),Model/ModelMap(将模型数据填充到request中)等。
1.当前端提交的域名称和controller中处理方法的参数名一致时,则一一对应匹配填充。
代码演示:
//前台请求:http://localhost:8080/springmvc02/user?id=1
@RequestMapping(value = {"/user"})//请求的路径
public String hello2(Integer id){//形参是数据模型类型Model
System.out.println("id="+id);
return "hello";//直接返回视图名称
}
控制台输出:id=1
2.当前端提交的域名称和controller中处理方法的参数名不一致时,springmvc提供了@RequestParam(“前端参数名”)来进行间接数据的绑定。
代码演示:
//前台请求:http://localhost:8080/springmvc02/user?uid=2
@RequestMapping(value = {"/user"})//请求的路径
public String hello2(@RequestParam("uid") Integer id){//形参是数据模型类型Model
System.out.println("id="+id);
return "hello";//直接返回视图名称
}
绑定POJO类型(绑定一个对象类型)
在实际开发中,客户端传递多个参数的时候,我们使用POJO类型进行数据绑定,即将所有关联的请求参数自动封装到一个POJO中,然后在方法中直接使用该POJO作为形参来完成数据绑定。这个封装过程由springmvc帮我们自动完成表单数据的封装。
代码演示:
实体类User:
package com.fan.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
//使用lombok生成全餐构造方法,无参构造方法,和set,get方法
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
private String id;
private String username;
private String password;
}
pages文件夹下的注册页面regist.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册页面</title>
</head>
<body>
<%--action 作用:规定当提交表单时向何处发送表单数据--%>
<%--${pageContext.request.contextPath}用于解决使用相对路径时出现的问题,它的作用是取出所部署项目的名字。--%>
<form action="${pageContext.request.contextPath}/registUser" method="post">
<input type="text" name="username" placeholder="请输入姓名">
<input type="text" name="password" placeholder="请输入姓名">
<input type="submit" value="提交"></button>
</form>
</body>
</html>
Controller:
package com.fan.controller;
import com.fan.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller//将此类对象注册到容器中
public class HelloController {
//去到注册页面,不携带数据
@RequestMapping(value = "/toRegist")
public String toRegist(){
return "regist";//返回一个视图名,默认转发到注册页面
}
//注册页面发送数据
@RequestMapping(value = "/registUser")
public String registUser(User user){
System.out.println(user);
System.out.println(user.getUsername());
System.out.println(user.getPassword());
return "hello";
}
}
开启tomcat运行:
http://localhost:8080/springmvc02/toRegist
然后提交表单数据:
控制台结果:
User(id=null, username=admin, password=123)
admin
123
当我们输入中文的时候:
控制台结果显示:
User(id=null, username=???, password=123)
???
123
出现乱码。
解决请求参数中的中文乱码问题:在web.xml中配置编码过滤器:
<!--配置编码过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
然后测试,中文正常显示。
数据回显:
绑定包装POJO:
当一个类中依赖另一个类的对象的时候(即一个POJO中包含另一个简单的POJO),我们要考虑使用包装POJO类型的数据绑定:如Person类中有Food属性。Food又是另一个类。
代码演示:
订单实体类:
package com.fan.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Orders {
private String orderId;//订单编号
private User user;//所属用户
}
User类:
package com.fan.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
//使用lombok生成全餐构造方法,无参构造方法,和set,get方法
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
private String id;
private String username;
private String password;
}
orders.jsp:
<%--
Created by IntelliJ IDEA.
User: fan
Date: 2021/3/19
Time: 1:30
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>订单查询</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/findOrders" method="post">
订单编号:<input type="text" name="orderId"><br>
所属用户:<input type="text" name="user.username">
<input type="submit" value="查询">
</form>
</body>
</html>
OrderController:
package com.fan.controller;
import com.fan.pojo.Orders;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class OrderController {
//去到订单查询页
@RequestMapping(value = "/toOrders")
public String toOrders(){
return "orders";
}
//查询订单和用户信息
@RequestMapping(value = "/findOrders")
public String findOrder(Orders orders){
System.out.println(orders);//打印订单信息
return "hello";
}
}
测试结果:
Orders(orderId=123, user=User(id=null, username=张三, password=null))
可以得到我们需要的信息。
注意:在使用包装POJO类型进行数据绑定的时候,前端请求的参数名编写必须符合以下两种情况;
`1。如果查询条件参数是包装类的直接属性,则参数名直接用对应的属性名,如上jsp中代码name=“orderId”
2.如果查询条件参数是包装类中POJO的子属性,则参数名必须写【对象.属性】,其中对象要和包装类POJO中的对象属性名称一致,属性要和包装POJO中的对象的子属性一致。如上jsp中的name=“user.username”