目录
简介
代替早期的Servlet控制层使它更加的简便,使用注解方式让代码越少。
MVC模式
- 视图(View)-对应组件:JSP或者HTML文件
- 控制器(Controller)-对应组件:Servlet
- 模型(Model)-对应组件:JavaBean
配置思路
- 新建maven-webapp项目
- 引入SpringMVC需要的依赖
- 创建,编辑SpringMVC配置文件
- 编辑web配置文件
- 创建Controller文件测试常用的方法
- 网页上显示
新建MVC项目
点击下一步创建
在pom.xml里面添加SpringMVC要用的依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>springMVC01</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>springMVC01 Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source><!--jdk改为8-->
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>5.2.5.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- log4j 日志jar -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- 连接mysql5 的驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
<!-- mybatis依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.2</version>
</dependency>
<!-- 参考版本对应 http://www.mybatis.org/spring/ -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.2</version>
</dependency>
<!-- 数据源管理 使用了dbcp2数据 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- commons 文件上传jar -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!-- jstl -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- 加入JSON转换工具 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
</dependencies>
<build>
<finalName>springMVC01</finalName>
</build>
</project>
创建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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
">
<!--扫描controller包-->
<context:component-scan base-package="com.controller"></context:component-scan>
<!--解决前后端传值中文乱码问题-->
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json</value>
</list>
</property>
<property name="features">
<list>
<!-- Date的日期转换器 -->
<value>WriteDateUseDateFormat</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!--转发时的前后坠-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property><!--前缀-->
<property name="suffix" value=""></property><!--后缀-->
</bean>
<!--设置存放图片的静态文件夹-->
<mvc:resources mapping="/static/**" location="/static/"></mvc:resources>
<!-- 配置multipartResolver,用于上传文件,使用spring的CommonsMultipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxInMemorySize" value="5000000"></property>
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
</beans>
编辑web配置文件
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<!--让jsp里添加的<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>有效果-->
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>Archetype Created Web Application</display-name>
<servlet>
<!--引入spring配置文件-->
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--前后端传值的中文乱码问题-->
<filter>
<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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
创建Controller文件
在类上面添加注解
@Controller
@RequestMapping("/hello")
public class HelloController {
}
@Controller注解将此类成为Controller,可以在spring配置文件识别使用
@RequestMapping("/hello")注解在前端输入网址时输入的网址
添加一个简单方法
return表示转发到的某个页面
@RequestMapping("/hello01")
public String hello01(){
System.out.println("hello01");
return "hello01.jsp";
}
带参数传值的四种方法
向前端页面跳转需要Model(数据)和View(页面)
1.ModelAndView方式传值
@RequestMapping("/hello02")
public ModelAndView hello02(ModelAndView modelAndView){
modelAndView.setViewName("hello01.jsp");
modelAndView.addObject("username","pp");
return modelAndView;
}
2.Model方式传值
@RequestMapping("/hello03")
public String hello03(Model model){
model.addAttribute("username","ppp");
return "hello01.jsp";
}
3.HttpServletRequest方式传值
@RequestMapping("/hello04")
public String hello04(HttpServletRequest request){
request.setAttribute("username","pppp");
return "hello01.jsp";
}
4.Map方式传值
@RequestMapping("/hello05")
public String hello05(Map map){
map.put("username","ppppp");
return "hello01.jsp";
}
其实四种传值方式本质上都是转发,比较常用的是Model方式。
重定项
重定项在SpringMVC中非常的简单就是在return后面添加redirect:
@RequestMapping("/hello05")
public String hello05(Map map){
map.put("username","ppppp");
return "redirect:/login.jsp";
}
前端向后端传值
前端传值一般使用表单提交
前端传值页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Hello World!</h2>
<form action="/hello/hello03" method="post">
用户名:<input type="text" name="username">
密码:<input type="text" name="pwd">
<br>
<input type="submit" value="提交">
</form>
</body>
</html>
后端接收
可以直接把name值写在方法参数里面(不推荐使用)
@RequestMapping("/hello03")
public String hello03(String username,String pwd,Model model){
System.out.println("用户名:"+username+"密码:"+pwd);
model.addAttribute("username","ppp");
return "hello01.jsp";
}
也可以创建个实体类接收,前提实体类里要有这些属性(推荐使用)
@RequestMapping("/hello03")
public String hello03(User user,Model model){
System.out.println("用户名:"+user.getUsername()+"密码:"+user.getPwd());
model.addAttribute("username","ppp");
return "hello01.jsp";
}
网页报错跳转
应用场景,网页的404页面或者500页面
网页中只要有错误就会跳转到你设置的那个错误页面
这个是在本类里面的错误跳转,RuntimeException表示运行时的错误,可以改变
@ExceptionHandler(RuntimeException.class)
public String error(Exception e){
System.out.println(e.getMessage());
return "error.jsp";
}
写在SpringMVC配置文件表示这个项目中的错误都跳转,RuntimeException表示运行时的错误,可以改变
<!--有错误时跳转的页面-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.RuntimeException">error.jsp</prop>
</props>
</property>
</bean>
Ajax方式
发起Ajax请求
发起Ajax请求只需要在方法上面添加@ResponseBody注解就可以实现
这样return返回的就不再是页面而是数据,前端发起Ajax请求就能获取到
@RequestMapping("/hello06")
@ResponseBody
public String hello06(){
User user=new User();
user.setUsername("牛牛");
user.setPwd("123");
String result= JSON.toJSONString(user);
return result;
}
发起Ajax请求直接赋值
@RequestMapping(value = "/hello07/{username}/{pwd}",produces = {"text/html;charset=utf-8"})
@ResponseBody
public String hello07(@PathVariable("username") String username,
@PathVariable("pwd") String pwd){
return username+pwd;
}
效果:
虽然这种方式很方便,但是不安全,用户也不会在这里直接输入,(目前不常用)
上传图片
前端页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>上传页面</title>
</head>
<body>
<form action="/hello/upload" method="post" enctype="multipart/form-data">
<input type="text" name="username">
<br>
<input type="file" name="photo">
<br>
<input type="submit" value="提交">
</form>
</body>
</html>
后端代码
@RequestMapping("/upload")
public String upload(String username,MultipartFile photo,HttpServletRequest request){
String fileType=photo.getOriginalFilename();//获取文件名
int index=fileType.lastIndexOf(".");//获取文件后缀有几位
fileType=fileType.substring(index);截取后缀
String path=request.getSession().getServletContext().getRealPath("static"+ File.separator+"uploadfiles");//拼接地址
long filename=System.currentTimeMillis();//获取当前时间时间戳
File file=new File(path+"\\"+filename+fileType);//上传的地址
System.out.println(path+"\\"+filename+fileType);//打印地址
try {
photo.transferTo(file);
} catch (IOException e) {
e.printStackTrace();
}
return "上传成功";
}
获取时间戳,将图片名称改为时间戳传入tomcat容器
输出:
可以通过此地址在网页里查询到刚刚上传的图片
拦截器
SpringMVC中写入拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/hello/**"/>
<mvc:exclude-mapping path="/hello/hello04"/>
<bean class="com.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
解释:
- <mvc:mapping path="/hello/**"/>拦截的地址
- <mvc:exclude-mapping path="/hello/hello04"/>规定不拦截的地址
- <bean class="com.interceptor.LoginInterceptor"></bean>调用拦截的类
拦截器类方法编写
package com.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
String username= request.getParameter("username");
//判断是否有username
if (null==username||"".equals(username)){
response.sendRedirect("/index.jsp");
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("afterCompletion:页面没加载之前");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion:全部执行完毕后执行");
}
}
应用场景:一般在登录页面