SpringMVC简介
本博客的小目标:
1.重点理解 MVC 思想,能够表达清楚;
2.能够借助 maven 搭建 springmvc 运行环境,理解 SpringMvc 框架内部请求流程;
3.掌握 springmvc 常用注解,掌握请求参数的绑定,页面控制器 Controller的编写与访问请求映射地址的配置。
4.掌握 SpringMvc Json 数据的返回与解析,熟悉拦截器编写与配置
5.熟悉 SpringMvc 文件上传实现
6.SSM 三大框架集成步骤,完成 SSM 框架集成
目录
8.启动 jetty 服务器(至此,springmvc 环境搭建完毕)
1.实现 HandlerInterceptorAdapter类继承定义我们的拦截器代码如下:
2.实现 HandlerInterceptor 接口方式定义我们的拦截器代码如下:
1.Pom 文件修改 添加 commons-fileupload 依赖
一、 什么叫 MVC
模型-视图-控制器(MVC) 是一个众所周知的以设计界面应用程序为基础的设计思想。 它主要通过分离模型、 视图及控制器在应用程序中的角色将业务逻辑从界面中解耦。 通常, 模型负责封装应用程序数据在视图层展示。 视图仅仅只是展示这些数据, 不包含任何业务逻辑。 控制器负责接收来自用户的请求,并调用后台服务(service 或者 dao) 来处理业务逻辑。 处理后, 后台业务层可能会返回了一些数据在视图层展示。 控制器收集这些数据及准备模型在视图层展示。 MVC 模式的核心思想是将业务逻辑从界面中分离出来, 允许它们单独改变而不会相互影响。
二、 Spring MVC 的面容
简介:
Spring MVC 是 Spring 家族中的一个 web 成员, 它是一种基于 Java 的实现了 Web MVC 设计思想的请求驱动类型的轻量级 Web 框架, 即使用了 MVC 架构模式的思想, 将 web 层进行职责解耦, 基于请求驱动指的就是使用请求-响应模型, 框架的目的就是帮助我们简化开发, Spring MVC 也是要简化我们日常Web 开发的。Spring MVC 是服务到工作者思想的实现。 前端控制器是DispatcherServlet; 应用控制器拆为处理器映射器(Handler Mapping)进行处理器管理和视图解析器(View Resolver)进行视图管理; 支持本地化/国际(Locale) 解析及文件上传等; 提供了非常灵活的数据验证、 格式化和数据绑定机制; 提供了强大的约定大于配置(惯例优先原则) 的契约式编程支持。
Spring MVC的用处:
- 让我们能非常简单的设计出干净的 Web 层;
- 进行更简洁的 Web 层的开发;
- 天生与 Spring 框架集成(如 IoC 容器、 AOP 等);
- 提供强大的约定大于配置的契约式编程支持;
- 能简单的进行 Web 层的单元测试;
- 支持灵活的 URL 到页面控制器的映射;
- 非常容易与其他视图技术集成, 如 Velocity、 FreeMarker 等等, 因为模型
- 数据不放在特定的 API 里, 而是放在一个 Model 里(Map 数据结构实现, 因此很容易被其他框架使用);
- 非常灵活的数据验证、 格式化和数据绑定机制, 能使用任何对象进行数据绑定, 不必实现特定框架的 API;
- 支持灵活的本地化等解析;
- 更加简单的异常处理;
- 对静态资源的支持;
- . 支持 Restful 风格。
Spring MVC 架构:
Spring MVC 框架也是一个基于请求驱动的 Web 框架, 并且使用了前端控制器模式(是用来提供一个集中的请求处理机制, 所有的请求都将由一个单一的处理程序处理来进行设计, 再根据请求映射规则分发给相应的页面控制器(动作/处理器) 进行处理。
Spring MVC 核心架构图:
三.Spring Mvc 环境搭建
1.开发环境
Idea2018 + jdk1.8 + jetty
2.新建 Maven webApp
3.springmvc 环境 jar 包依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- spring web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- spring mvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- web servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
4.配置 web.xml (前端控制器配置,老是忘记)
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<!-- 表示容器启动时 加载上下文配置 这里指定spring 相关配置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:*.xml</param-value>
</context-param>
<!-- 启用spring容器环境上下文监听 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 编码过滤 utf-8 -->
<filter>
<description>char encoding filter</description>
<filter-name>encodingFilter</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>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- servlet请求分发器 -->
<servlet>
<servlet-name>springMvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:servlet-context.xml</param-value>
</init-param>
<!-- 表示启动容器时初始化该Servlet -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<!-- 这是拦截请求, /代表拦截所有请求,拦截所有.do请求 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
5. servlet-context.xml 配置
<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"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 扫描com.shsxt.controller 下包 -->
<context:component-scan base-package="com.shsxt.controller" />
<!-- mvc 请求映射 处理器与适配器配置-->
<mvc:annotation-driven/>
<!--配置视图解析器 默认的视图解析器- -->
<bean id="defaultViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="contentType" value="text/html" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- 配置拦截器 -->
<mvc:interceptors>
<!-- 全部拦截 -->
<bean class="com.shsxt.interceptor.MyInterceptor"></bean>
<mvc:interceptor>
<!– 全部拦截 –>
<mvc:mapping path="/**"/>
<bean class="com.shsxt.interceptor.MyInterceptor01"></bean>
</mvc:interceptor>
<mvc:interceptor>
<!– 部分拦截 –>
<mvc:mapping path="/user/**"/>
<bean class="com.shsxt.interceptor.MyInterceptor02"></bean>
</mvc:interceptor>
</mvc:interceptors>
</beans>
6.页面控制器的编写
/**
* Created on 2018/10/11 9:31
* Author: Mr Tong
*/
@Controller
@RequestMapping("my")
public class HelloController {
@RequestMapping("hello01")
public String hello01(){
return "hello";
}
@RequestMapping("hello02")
public ModelAndView hello02(){
ModelAndView mv = new ModelAndView();
/***
* ModelAndView类:
* Model 数据模型
* View 视图
*
*/
mv.addObject("a", 11);
mv.setViewName("hello");
return mv;
}
}
7.添加视图页面
<%--
Created by IntelliJ IDEA.
User: 威威
Date: 2018/10/11
Time: 9:32
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>something is me springmvc</h1>
<br>
<hr>
a = ${a} ---- b = ${b}
</body>
</html>
8.启动 jetty 服务器(至此,springmvc 环境搭建完毕)
四.SpringMvc 注解特性
[email protected] 控制器定义
在 spring 3.0 中,通过@controller 标注即可将 class 定义为一个 controller 类。为使 spring 能找到定义为 controller 的 bean,需要在 spring-context 配置文件中增加如下定义:
<context:component-scan base-package="com.shsxt.controller"/>
[email protected]
在类前面定义,则将 url 和类绑定。在方法前面定义,则将 url 和类的方法绑定,也即是类或方法的访问路径
3.参数绑定
请求参数到处理器功能处理方法的方法参数上的绑定, 对于参数绑定非常灵活,采用@RequestParam(defaultValue = "33", name="aa") 给Integer设置,如果前台没有传名字叫aa的变量默认为33,同理bb也如此.
@RequestMapping("hello11")
public String hello11(@RequestParam(defaultValue = "33", name="aa") Integer a,
@RequestParam(defaultValue = "44", name = "bb") Integer b){
System.out.println(a +"---"+ b);
return "hello";
}
五、 请求转发与重定向的问题
Springmvc 默认采用服务器内部转发的形式展示页面信息。同样也支持重定向页面。
/**
* Created on 2018/10/11 15:03
* Author: Mr Tong
*/
@Controller
public class ViewController {
@RequestMapping("view01")
public String view01(){
return "redirect:v1.jsp?a=1&b=上海";
}
//解决乱码
@RequestMapping("view02")
public String view02(RedirectAttributes attr){
attr.addAttribute("a",1);
attr.addAttribute("b", "上海");
return "redirect:v1.jsp";
}
@RequestMapping("view03")
public ModelAndView view03(RedirectAttributes attr){
attr.addAttribute("a",1);
attr.addAttribute("b", "上海松江");
ModelAndView mv = new ModelAndView();
mv.setViewName("redirect:v1.jsp");
return mv;
}
@RequestMapping("view04")
public String view04(){
System.out.println(" 正在 view04中;;;;;;");
return "redirect:/view05";
}
@RequestMapping("view05")
public String view05(){
System.out.println(" 正在 view05中;;;;;;");
return "view";
}
@RequestMapping("view06")
public String view06(){
System.out.println(" 正在 view06中;;;;;;");
return "forward:/view07";
}
@RequestMapping("view07")
public String view07(){
System.out.println(" 正在 view07中;;;;;;");
return "view";
}
}
六.SpringMvc 之 Json 数据开发
@ResponseBody
该注解用于将 Controller 的方法返回的对象,通过适当的 HttpMessageConverter转换为指定格式后,写入到 Response 对象的 body 数据区。返回的数据不是 html 标签的页面,而是其他某种格式的数据时(如 json、xml 等)使用(通常用于 ajax 请求)
@RequestBody
该注解用于读取 Request 请求的 body 部分数据,使用系统默认配置的HttpMessageConverter 进行解析,然后把相应的数据绑定到要返回的对象上 ,再把HttpMessageConverter 返回的对象数据绑定到 controller 中方法的参数上Json 数据使用好处Json 在企业开发中已经作为通用的接口参数类型,在页面(客户端)解析很方便。SpringMvc 对于 json 提供了良好的支持,这里需要修改相关配置,添加 json 数据支持
1.添加 json 依赖 jar 包
<!-- 添加 json 依赖 jar 包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.7.0</version>
</dependency>
2.修改 servlet-context.xml
<!-- json 支持 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</list>
</property>
</bean>
3.Json 数据绑定的支持
@RequestMapping("queryUser")
@ResponseBody
public User queryUser(Integer id){
User user = new User();
user.setId(id);
user.setUsername("tony");
user.setUserpwd("123456");
System.out.println(" queryUser------- " + id);
return user;
}
七.拦截器
SpringMVC 中的 Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理。比如通过它来进行权限验证,或者是来判断用户是否登陆等操作。对于 springmvc 拦截器的定义方式有两种方式
1. 实现接口: org.springframework.web.servlet.HandlerInterceptor
2. 继承适配器: org.springframework.web.servlet.handler.HandlerInterceptorAdapter
1.实现 HandlerInterceptorAdapter类继承定义我们的拦截器代码如下:
public class LoginInterceptor01 extends HandlerInterceptorAdapter {
/**
* 思路:
* 1. 获取请求路径,判断是否为登陆!!!
* 2. 如果不是登陆, 判断是否含有session,
有就通过没有就跳转到登陆页面!
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//得到请求路径
String uri = request.getRequestURI();
System.out.println("请求的路径为: " + uri);
if (uri.indexOf("/login") != -1){
//登录
return true;
}else {
// 获取session
User user = (User) request.getSession().getAttribute("user");
if(null == user){
response.sendRedirect(request.getContextPath()+"/login.jsp");
return false;
}
}
return true;
}
}
对应的servlet-contect.xml的配置如下:
<mvc:interceptor>
<!-- 拦截登录 -->
<mvc:mapping path="/**"/>
<bean class="com.shsxt.interceptor.LoginInterceptor01"></bean>
</mvc:interceptor>
2.实现 HandlerInterceptor 接口方式定义我们的拦截器代码如下:
/**
* Created on 2018/10/11 16:12
* Author: Mr Tong
*/
public class MyInterceptor01 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println(" 拦截器 MyInterceptor01 的开始~~~");
System.out.println("拦截的对象: " + handler);
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println(" 拦截器 MyInterceptor01 的处理时候~~~");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println(" 拦截器 MyInterceptor01 的结束时候~~~");
}
}
对应的servlet-contect.xml的配置如下:
<mvc:interceptor>
<!-- 全部拦截 -->
<mvc:mapping path="/**"/>
<bean class="com.shsxt.interceptor.MyInterceptor01"></bean>
</mvc:interceptor>
八.SpringMvc 文件上传
1.Pom 文件修改 添加 commons-fileupload 依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
2.在servlet-context.xml中添加配置
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize">
<value>104857600</value>
</property>
<property name="maxInMemorySize">
<value>4096</value>
</property>
</bean>
3.主要实现步骤(对应的jsp文件自己准备吧!)
/**
* Created on 2018/10/11 18:50
* Author: Mr Tong
*/
@Controller
public class FileController {
@RequestMapping("uploadFile")
public String uploadFile(HttpServletRequest request, Model model){
/***
* 1. 获取 MultipartHttpServletRequest(强转即可)
* 2. 获取上传文件,以及存储路径和文件名
* 3. 存储transferTo
* */
MultipartHttpServletRequest muliRequest = (MultipartHttpServletRequest) request;
//根据前台传过来的参数名创建一个对象
MultipartFile file = muliRequest.getFile("file");
if(null != file && !file.isEmpty()){
//得到文件名
String fileName = file.getOriginalFilename();
//得到存储路径
String path = request.getSession().getServletContext().getRealPath("upload");
try {
//存储文件 到指定路径
file.transferTo(new File(path,fileName));
} catch (IOException e) {
e.printStackTrace();
model.addAttribute("msg", "上传失败");
}
model.addAttribute("msg", "上传成功");
}
return "success";
}
@RequestMapping("file")
public String file(){
return "file";
}
}
九.SSM 框架集成环境搭建
ssm框架(Spring-SpringMVC-Mybatis)环境已经搭建完成,在本人的GitHub上面:https://github.com/fly-tong/ssm.git 欢迎下载.