SpringMVC概述
(一)SpringMVC的概念
SpringMVC是一种使用[模型-视图-控制器]来设计并创建Web应用程序的开发模式
模型(Model):表示应用程序核心,比如在数据库中的数据记录列表
视图(View):表示显示数据(数据库记录),比如Java Server Pages(Java服务器页面)
控制器(Controller):处理输入(写入数据库的记录),接收请求数据并转发视图
(二)SpringMVC核心类与接口
前端控制器(DispatcherServlet):也称总控制器,将请求转发到具体的控制类
映射处理器(HandlerMapping):负责映射中央处理器转发给Controller时的映射策略
控制器(Controller):具体处理请求的控制器
ModelAndView:服务层返回的数据和视图层的封装类
视图解析器(ViewResolver):解析具体的视图
拦截器(Interceptors):负责拦截定义的请求并进行处理
(三)SpringMVC的运行结构
1 . 发送请求(Send Message)
2 . 前端控制器(DispatcherServlet):将请求发送给具体的控制类
3 . 映射控制器(HandlerMapping):判断将请求发送给哪个类的控制器
4 . 控制器(Controller):根据映射控制器的判断结果执行后续操作
按照控制器名称映射查找:BeanNameUrlHandlerMapping
按照简单Url映射查找:SimpleUrlHandlerMapping
按照控制类的类名控制器映射查找:ControllerClassNameHandlerMapping(访问时首字母需要小写)
5 . 视图和模型层(ModelAndView)
6 . 视图解析器(ViewResolver)
7 . 视图层(View):JSP
8 . 完成响应
(四)SpringMVC的执行步骤
1 . 配置JAR包:将jar包拷贝到工程目录下的WEB-INF文件夹中的lib文件夹中(Eclipse)
2 . 配置前端控制器DispatcherServlet:WEB.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>springmvc001</display-name>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
<!-- 配置前端控制器DispatcherServlet -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
3 . 配置Spring核心文件:创建SpringMVC核心控制配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://springframework.org/schema/mvc"
xmlns:context="http://springframework.org/schema/context"
xmlns:aop="http://springframework.org/schema/aop"
xmlns:tx="http://springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">
<!-- 配置Controller -->
<bean id="loginController" name="/login.do" class="com.pmzeroa.controller.LoginController"></bean>
<!-- 配置映射处理器1:按照name进行映射查找 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
<!-- 配置映射处理器2:按照简单Url进行映射查找 -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="login1.do">loginController</prop>
</props>
</property>
</bean>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置前缀 -->
<property name="prefix" value="/jsp/"></property>
<!-- 配置后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
4 . 配置控制器:编写控制器类(使用注解)
登陆页面演示代码:
package com.pmzeroa.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
public class LoginController extends AbstractController{
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
String userName = request.getParameter("userName");//获取账号
String userPw = request.getParameter("userPw");//获取密码
System.out.println("-----我是SpringMVC的控制器-----");
System.out.println("账号:" + userName);
System.out.println("密码:" + userPw);
ModelAndView mav = new ModelAndView("index");
//模拟调用Model
if("admin".equals(userName) && "123".equals(userPw)){
mav.addObject("message", "用户登录成功");
} else {
mav.addObject("message", "账号或密码错误");
}
return mav;
}
}
5 . 编写JSP页面并显示数据
(五)使用注解配置控制器
1 . 注解配置的概念
- @Controller是SpringMVC中最常用的注解,它可以定义当前类为一个Spring管理的BEAN,同时指定该类是一个控制器类,可以用来接受请求,表示当前类是控制层的一个具体实现
- @Controller会默认使用当前类名作为Spring Bean Name,也可以进行自定义设置
- 例如@Controller(“LoginController”)
- 设置当前Bean名称为LoginController
- @RequestMapping
- 放在方法前面用来指定某个方法的路径
- 当放在类前面的时候,相当于命名空间需要组合方法上的RequestMapping来访问
- @RequestMapping
2 . 使用注解的意义
- Controller不需要继承任何接口,开发人员对于Controller的代码维护变得更加灵活
- 可以通过@Controller注解声明将该类的实例添加到Spring的容器中管理,而不需要通过SpringMVC的配置文件进行配置,简化SpringMVC的配置量
- @RequestMapping
- SpringMVC中的大部分请求都是通过RequestMapping提交的,通过设置属性可以达到不同的请求效果
3 . 注解配置流程
(1) . 配置前端控制器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>springmvc002</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<!-- 配置前端控制器DispatcherServlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
(2)配置SpringMVC核心配置文件
(3)配置SpringMVC注解驱动
(4)配置SpringMVC扫描驱动(如果使用了扫描驱动,可以省略注解驱动)
(5)添加视图解析器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">
<!-- 配置SpringMVC注解驱动 -->
<mvc:annotation-driven/>
<!-- 配置SpringMVC扫描驱动 -->
<context:component-scan base-package="com.pmzeroa.servlet"/>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置前缀 -->
<property name="prefix" value="/view/"></property>
<!-- 配置后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
(6)使用注解配置控制器
package com.pmzeroa.servlet;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
//用来标注SpringMVC的控制器类
@Controller
@RequestMapping(value="sys/")//定义命名空间
public class RegController {
//用户访问控制器类的方法的注解
@RequestMapping(value="reg.do", method=RequestMethod.GET)
public String reg() {
System.out.println("-----用户注册1-----");
return "index";
}
@RequestMapping(value="reg.do", method=RequestMethod.POST)
public String reg1() {
System.out.println("-----用户注册2-----");
return "index";
}
@RequestMapping(value="add.do")
public String add() {
System.out.println("-----添加信息-----");
return "index";
}
}
(7)返回到视图层
(六)参数传递
1 . 参数传递的意义:将数据库中的查询结果返回至页面视图
2 . 参数传递的方法:通过HttpServletRequest获取页面数据
(1)获取数据:
package com.pmzeroa.servlet;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
//用来标注SpringMVC的控制器类
@Controller
@RequestMapping(value="sys/")//定义命名空间
public class RegController {
//用户访问控制器类的方法的注解
@RequestMapping(value="reg.do")
public String reg() {
System.out.println("-----用户注册-----");
return "index";
}
/**
* 通过HttpServletRequest获取页面数据
* @return
*/
@RequestMapping("reg1.do")
public String reg1(HttpServletRequest request) {
String userId = request.getParameter("userId");
String userPw = request.getParameter("userPw");
System.out.println("账号:" + userId);
System.out.println("密码:" + userPw);
return "index";
}
}
(2)获取单个数据:
/**
* 获取姓名数据
* @param request
* @return
*/
@RequestMapping("reg2.do")
public String reg2(String userName) {
System.out.println("姓名:" + userName);
return "index";
}
- 如果出现了中文编码错误,以下方法用来解决返回数据为乱码的情况:
- 重新配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>springmvc002</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<!-- 配置前端控制器DispatcherServlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- 配置编码过滤器 -->
<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>
</web-app>
(3)获取多个数据:
/**
* 获取多个数据,包含时间属性数据(需要添加时间属性编辑器)
* @param request
* @return
*/
@RequestMapping("reg3.do")
public String reg3(Integer userId, String userName, Integer userPw, Date userBrithday) {
System.out.println("账号:" + userId);
System.out.println("姓名:" + userName);
System.out.println("密码:" + userPw);
System.out.println("出生日期:" + userBrithday);
return "index";
}
/**
* 添加时间属性编辑器
*/
@InitBinder
public void InitBinder(ServletRequestDataBinder bin) {
bin.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}
(4)利用数组获取数据的多个值(例如:复选框)
- 修改.jsp页面:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PMZeroA</title>
</head>
<body>
<form action="sys/reg4.do" method="post">
<h1>用户注册</h1>
账号:<input type="text" name="userId"/><br/>
密码:<input type="password" name="userPw"/><br/>
姓名:<input type="text" name="userName"/><br/>
出生日期:<input type="text" name="userBrithday"/><br/>
兴趣爱好:
<input type="checkbox" name="xqs" value="绘画"/>绘画
<input type="checkbox" name="xqs" value="游戏"/>游戏
<input type="checkbox" name="xqs" value="网球"/>网球
<input type="checkbox" name="xqs" value="钢琴"/>钢琴
<input type="checkbox" name="xqs" value="动漫"/>动漫
<input type="submit" value="提交"/>
</form>
</body>
</html>
- 编写控制器类:
/**
* 获取复选框内的数据
* @param request
* @return
*/
@RequestMapping("reg4.do")
public String reg4(String[] xqs) {
for(String xq:xqs) {
System.out.println("兴趣:" + xq);
}
return "index";
}
(5)通过创建类来获取多个数据
- 创建UserInfo类:
import java.util.Arrays;
import java.util.Date;
public class UserInfo {
private Integer userId;
private String userPw;
private String userName;
private Integer userAge;
private Date userBrithday;
private String[] xqs;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserPw() {
return userPw;
}
public void setUserPw(String userPw) {
this.userPw = userPw;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getUserAge() {
return userAge;
}
public void setUserAge(Integer userAge) {
this.userAge = userAge;
}
public Date getUserBrithday() {
return userBrithday;
}
public void setUserBrithday(Date userBrithday) {
this.userBrithday = userBrithday;
}
public String[] getXqs() {
return xqs;
}
public void setXqs(String[] xqs) {
this.xqs = xqs;
}
@Override
public String toString() {
return "UserInfo [userId=" + userId + ", userPw=" + userPw + ", userName=" + userName + ", userAge=" + userAge
+ ", userBrithday=" + userBrithday + ", xqs=" + Arrays.toString(xqs) + "]";
}
}
- 通过对象来获取页面参数:
/**
* 通过对象获取页面参数
* @param request
* @return
*/
@RequestMapping("reg5.do")
public String reg5(UserInfo user) {
System.out.println(user);
return "index";
}
(七)数据返回
1 . 通过HttpServletRequest返回数据
(1)获取单一数据
- 编写数据类
package com.pmzeroa.domain;
public class UserInfo {
private Integer userId;
private String userName;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
- 编写控制器类
package com.pmzeroa.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.pmzeroa.domain.UserInfo;
@Controller
public class UserInfoController {
@RequestMapping("/query1.do")
public String queryUser1(HttpServletRequest request) {
//返回单一数据
String name = "明日香";
request.setAttribute("name", name);
return "index";
}
}
- 配置.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<hr/>
1.HttpServletRequest 返回数据:<br/>
<form action="query1.do" method="post">
<input type="submit" value="查询"/>
</form>
<br/>
name:${name }
<hr/>
</body>
</html>
- 查询结果示例:
(2)获取多条数据
- 编写控制器类
import com.pmzeroa.domain.UserInfo;
@Controller
public class UserInfoController {
@RequestMapping("/query1.do")
public String queryUser1(HttpServletRequest request) {
//返回单一数据
String name = "明日香";
request.setAttribute("name", name);
//返回对象
UserInfo user = new UserInfo();
user.setUserId(002);
user.setUserName("明日香");
request.setAttribute("user", user);
return "index";
}
}
- 配置.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<hr/>
1.HttpServletRequest 返回数据:<br/>
<form action="query1.do" method="post">
<input type="submit" value="查询"/>
</form>
<br/>
name:${name }
<br/>
userId:${user.userId }
userName:${user.userName }
<hr/>
</body>
</html>
- 查询结果示例:
2 . ModelAndView
- 编写控制器类
@RequestMapping("/query2.do")
public ModelAndView queryUser2() {
UserInfo user = new UserInfo();
user.setUserId(1001);
user.setUserName("淀真嗣");
Map<String, Object> map = new HashMap<String, Object>();
map.put("user2", user);
return new ModelAndView("index", map);
}
- 配置.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
2.ModelAndView 返回数据:<br/>
<form action="query2.do" method="post">
<input type="submit" value="查询"/>
</form>
<br/>
userId:${user2.userId }
userName:${user2.userName }
</body>
</html>
- 查询结果示例:
3 . Map<String, Object> map
- 编写控制器类
@RequestMapping("/query3.do")
public String queryUser3(Map<String, Object> map) {
UserInfo user = new UserInfo();
user.setUserId(1000);
user.setUserName("绫波丽");
map.put("user3", user);
return "index";
}
- 配置.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
3.Map<String, Object> map 返回数据:<br/>
<form action="query3.do" method="post">
<input type="submit" value="查询"/>
</form>
<br/>
userId:${user3.userId }
userName:${user3.userName }
</body>
</html>
- 查询结果示例:
4 . 通过Model model
Model相当于ModelAndView中的Model
- 编写控制器类
@RequestMapping("/query4.do")
public String queryUser4(Model model) {
UserInfo user = new UserInfo();
user.setUserId(1);
user.setUserName("淀真嗣");
model.addAttribute("user4", user);
return "index";
}
- 编写.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
4.Model 返回数据:<br/>
<form action="query4.do" method="post">
<input type="submit" value="查询"/>
</form>
<br/>
userId:${user4.userId }
userName:${user4.userName }
</body>
</html>
- 查询结果示例:
5 . 返回List数据
- 编写控制器类
@RequestMapping("/query5.do")
public String queryUser5(Model model) {
UserInfo user = new UserInfo();
user.setUserId(1);
user.setUserName("淀真嗣");
List<UserInfo> list = new ArrayList<UserInfo>();
list.add(user);
list.add(user);
list.add(user);
model.addAttribute("list", list);
return "index";
}
- 编写.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
5.List 返回数据:<br/>
<form action="query5.do" method="post">
<input type="submit" value="查询"/>
</form>
<br/>
list:${list }
<hr/>
</body>
</html>
- 查询结果示例:
(八)使用AJAX和JSON
1 . 使用AJAX异步通信创建登陆验证页面
(1)配置登陆页面jsp
获取登陆页面文本框的值
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PMZeroA</title>
<!-- 配置javascript -->
<script type="text/javascript" src="js/jquery-3.3.1.js"></script>
<script type="text/javascript">
$().ready(function(){
$("#button1").click(function(){
var userId = $("#userId").val();
if(userId.length !=0){
$.post("ajax1.do", {usrId:userId},function(data){
alert(data);
});
} else {
alert('请输入账号');
}
});
});
</script>
</head>
<body>
<form action="">
账号:<input type="text" id="userId" name="userId"/>
<input type="button" id="button1" value="验证"/>
</form>
</body>
</html>
在JSP编辑页面中需要对输入的数据进行条件判断:
- 如果数据存在作出的响应(账号已经存在)
- 如果数据不存在作出的响应(账号可以注册)
- 如果数据为空作出的响应(账号不能为空)
(2)编写控制器类
package com.pmzeroa.controller;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class RegController {
@RequestMapping("ajax1.do")
public void ajax1(String usrId, HttpServletResponse response) {
try {
System.out.println(usrId);
//响应输入
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
//进行条件判断
if("admin".equals(usrId)) {
out.println("账号已被注册!");
} else {
out.println("账号可以使用!");
}
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
2 . 使用JSON数据格式将后台的数据对象传输到前台页面
(1) 创建用户数据类:
package com.pmzeroa.domain;
public class UserInfo {
private Integer userId;
private String userName;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public UserInfo(Integer userId, String userName) {
this.userId = userId;
this.userName = userName;
}
}
(2)使用@ReponseBody将内容或对象作为HTTP响应正文返回
@RequestMapping("/ajax2.do")
//通过@ResponseBody将内容或者对象作为HTTP进行响应并返回
public @ResponseBody UserInfo ajax2(String userId) {
UserInfo user = new UserInfo();
if("1001".equals(userId)) {
user.setUserId(1001);
user.setUserName("淀真嗣");
} else {
user.setUserId(1002);
user.setUserName("明日香");
}
return user;
}
(3)配置HttpMessageConverter:
- HTTP的请求和响应是基于文本的,也就是说浏览器与服务器通过交换文本进行通信
- 从请求和响应中读取或编写字符串,默认情况下支持媒体类型text/*,并使用文本或无格式内容类型进行编写
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">
<!-- 配置SpringMVC注解驱动 -->
<mvc:annotation-driven/>
<!-- 配置SpringMVC扫描驱动 -->
<context:component-scan base-package="com.pmzeroa.controller"/>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置前缀 -->
<property name="prefix" value="/"></property>
<!-- 配置后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 从请求或响应读取和编写字符串 -->
<bean id="stringConverter"
class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
</list>
</property>
</bean>
</beans>
(4)使用MappingJacksonHttpMessageConverter
- 将对象转换为JSON格式
- 内置转换程序使用Jackson的ObjectMapper将JSON映射到JavaBean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">
<!-- 配置SpringMVC注解驱动 -->
<mvc:annotation-driven/>
<!-- 配置SpringMVC扫描驱动 -->
<context:component-scan base-package="com.pmzeroa.controller"/>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置前缀 -->
<property name="prefix" value="/"></property>
<!-- 配置后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 从请求或响应读取和编写字符串 -->
<bean id="stringConverter"
class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- 将对象转换为JSON格式 -->
<bean id="jsonConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="stringConverer"/>
<ref bean="jsonConverer"/>
</list>
</property>
</bean>
</beans>
废弃的:org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
最新使用:org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
返回List<>对象
@RequestMapping("/ajax3.do")//响应地址
public @ReponseBody List<UserInfo> ajax3() {
List<UserInfo> list = new ArrayList<UserInfo>();
UserInfo user1 = new UserInfo():
user1.setUserId(001);
user1.setUserName("淀真嗣");
list.add(user1);
UserInfo user2 = new UserInfo():
user2.setUserId(002);
user2.setUserName("明日香");
list.add(user2);
UserInfo user3 = new UserInfo():
user3.setUserId(003);
user3.setUserName("绫波丽");
list.add(user3);
return list;
}
(九)上传和下载
1 . 上传
JSP页面表单是使用二进制进行数据传输,所以如果传输图片格式的文件,需要进行格式配置
配置解析器,并同时可以限制上传文件的大小
- 转化request
- 获取文件
- 获得文件的字节组数
- 获得文件的后缀名称
- 获取当前项目路径
- 设置上传的文件名称
- 进行上传操作
(1)配置DispatcherServlet前端过滤器:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>springmvc005</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<!-- 配置前端控制器DispatcherServlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- 配置编码过滤器 -->
<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>
</web-app>
(2)配置SpringMVC核心配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">
<!-- 配置SpringMVC注解驱动 -->
<mvc:annotation-driven/>
<!-- 配置SpringMVC扫描驱动 -->
<context:component-scan base-package="com.pmzeroa.controller"/>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置前缀 -->
<property name="prefix" value="/"></property>
<!-- 配置后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="1024000"></property>
</bean>
</beans>
(3)配置JSP登录页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PMZeroA</title>
</head>
<body>
<!-- 设置属性enctype="multipart/form-data",进行二进制数据转换 -->
<form action="upload.do" method="post" enctype="multipart/form-data">
<h1>用户注册</h1>
账号:<input type="text" name="userId"/><br/>
姓名:<input type="text" name="userName"/><br/>
头像:<input type="file" name="userImg"/><br/>
年龄:<input type="text" name="userAge"/><br/>
<input type="submit" value="注册"/>
</form>
</body>
</html>
(4)编写用户信息类:
package com.pmzeroa.domain;
public class UserInfo {
private String userId;
private String userName;
private String url;
private Integer userAge;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Integer getUserAge() {
return userAge;
}
public void setUserAge(Integer userAge) {
this.userAge = userAge;
}
@Override
public String toString() {
return "UserInfo [userId=" + userId + ", userName=" + userName + ", url=" + url + ", userAge=" + userAge + "]";
}
}
(5)编写控制器类:
package com.pmzeroa.controller;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import com.pmzeroa.domain.UserInfo;
@Controller
public class RegController {
@RequestMapping(value="upload.do",method=RequestMethod.POST)
public String upload(UserInfo user, HttpServletRequest req, Model model) {
try {
System.out.println(user);
//转换MultipartHttpServletRequest
MultipartHttpServletRequest request = (MultipartHttpServletRequest)req;
//获取目标文件
CommonsMultipartFile cmfile = (CommonsMultipartFile)request.getFile("userImg");
//获得文件并转化为byte[]
byte[] byte1 = cmfile.getBytes();
//获取文件名称
String oldfilename = cmfile.getOriginalFilename();
//获取文件格式名称
String suffix = oldfilename.substring(oldfilename.lastIndexOf("."));
//获取当前项目文件路径
String path = req.getSession().getServletContext().getRealPath("/");
//设置输出文件时间格式
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String filename = sdf.format(date);
//输出目标文件到项目路径
String url = path+"upload/"+filename+suffix;
System.out.println(url);
OutputStream os = new FileOutputStream(url);
//进行读写文件操作
os.write(byte1);
//关闭资源
os.flush();
os.close();
} catch (Exception e){
e.printStackTrace();
}
return "reg";
}
}
2 . 下载
(1)重新编修JSP
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>PMZeroA</title>
</head>
<body>
<!-- 设置属性enctype="multipart/form-data",进行二进制数据转换 -->
<form action="upload.do" method="post" enctype="multipart/form-data">
<h1>用户注册</h1>
账号:<input type="text" name="userId"/><br/>
姓名:<input type="text" name="userName"/><br/>
头像:<input type="file" name="userImg"/><br/>
年龄:<input type="text" name="userAge"/><br/>
<input type="submit" value="注册"/>
</form>
<hr />
${user }
<hr />
下载:
<a href="${user.url }">下载</a>
</body>
</html>
(2)添加控制器类的下载代码
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
@Controller
public class RegController {
@RequestMapping(value = "/upload.do", method = RequestMethod.POST)
public String upload(UserInfo user, HttpServletRequest req, Model model) {
try {
System.out.println(user);
//转换MultipartHttpServletRequset
MultipartHttpServletRequset requset = (MultipartHttpServletRequset)req;
//获取文件:使用CommonsMultiparFile
CommonsMultipartFile cmfile = (CommonsMultipartFile)request.getFile("userImg");
//获取文件后转换为byte[]
byte[] byte1 = cmfile.getBytes();
//获取文件的后缀名称
String oldfilename = cmfile.getOriginalFilename();//文件名称
String suffix = oldfilename.substring(oldfilename.lastIndexOf("."));//后缀名称
//获取当前项目的路径
String path = req.getSession().getServletContext().getRealPath("/");
//设置文件名称:获取当前时间
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
String filename = sdf.format(date);
String url = path + "upload/" + filename + suffix;
System.out.println(url);
//设置OutputStream
OutputStream os = new FileOutputStream(url);
os.write(byte1);
os.flush();
os.close();
//将页面上的文件信息返回到Model
user.setUrl("upload/" + filename + suffix);//将文件地址返回
model.addAttribute("user", user);//将当前user返回到页面
} catch (Exception e) {
e.printStackTrace();
}
return "reg";
}
}
测试实例:
(十)SpringMVC拦截器
1 . Interceptor拦截器的概念
Interceptor拦截请求是通过HandlerInterceptor接口来实现的,这个接口中主要包含了3个方法:
(1)preHandle(HttpServletRequest request, HttpServletRespons e response, Object handle)
- preHandle方法将在请求处理之前进行调用
- 在一个请求或应用中可以同时存在多个Interceptor
- 每一个Interceptor的调用会根据声明的顺序依次执行,最先执行的是preHandle方法
- 当preHandle方法的返回值为false时,表示请求结束,后续的Interceptor和Controller都不会再执行
- 当preHandle方法的返回值为true时,会继续调用下一个Interceptor的preHandle方法
- 如果已经执行到最后一个Interceptor,会调用当前请求的Controller
(2)postHandle(HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView, modelAndView)
- Interceptor的preHandle方法只有在返回值为true时才会被调用
- postHandle在当前请求进行处理后,Controller方法被调用后执行,但同时会在DispatcherServlet进行视图返回渲染之前被调用,所以可以使用这种方法对Controller处理之后的ModelAndView对象进行操作
- postHandle方法被调用的方向与preHandle相反,也就是说,先进行声明的postHandle方法会后执行
(3)afterCompletion()HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)
- afterCompletion方法需要当前对应的Interceptor的preHandle方法的返回值为true时才能够执行
- afterCompletion将在整个请求结束之后,在DispatcherServlet渲染了对应的视图之后执行
- afterCompletion主要作用于进行资源清理工作
2 . 实现过程
(1)配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>springmvc006</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<!-- 配置前端控制器 -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- 配置过滤器 解决乱码问题 -->
<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>
</web-app>
(2)配置核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">
<!-- springmvc注解驱动 <mvc:annotation-driven/> -->
<mvc:annotation-driven/>
<!-- springmvc的扫描器 -->
<context:component-scan base-package="com.pmzeroa.controller" />
<!-- 视图解析器 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/"></property>
<!-- 后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 配置拦截器Interceptor -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/*"/>
<bean class="com.pmzeroa.interceptor.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
</beans>
(3)编写控制器类
package com.pmzeroa.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class TestController {
@RequestMapping("/test.do")
public String test() {
System.out.println("-----我是控制器-----");
return "index";
}
}
(4)编写拦截器类
package com.pmzeroa.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class MyInterceptor implements HandlerInterceptor {
//afterCompletion
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("-----afterCompletion-----");
}
//postHandle
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println("-----postHandle-----");
}
//preHandle
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("-----preHandle-----");
return true;
}
}