SpringMVC介绍及详细使用
介绍
了解SpringMVC之前我们先要了解什么是三层架构
三层架构
1.开发服务器端程序,一般都基于两种形式,一种C/S架构程序,一种B/S架构程序
2.使用Java语言基本上都是开发B/S架构的程序,B/S架构又分成了三层架构
3.三层架构
表现层:WEB层,用来和客户端进行数据交互的。表现层一般会采用MVC的设计模型
业务层:处理公司具体的业务逻辑的
持久层:用来操作数据库的
MVC(Model-View-Controller)是一种常见的软件设计模式,用于将应用程序的逻辑分离成三个独立的组件:
Model:数据模型,JavaBean的类,用来进行数据封装。
View:指JSP、HTML用来展示数据给用户
Controller:用来接收用户的请求,整个流程的控制器。用来进行数据校验等
Spring Web MVC是基于Servlet API构建的原始Web框架,也是Spring框架的一部分。它提供了灵活可扩展的MVC架构,方便开发者构建高性能的Web应用程序,并与 Spring 生态系统无缝集成。
SpringMVC的入门程序
执行流程
入门程序
打开idea创建一个mavenWEB项目,在pom文件中导入依赖
<!-- 版本锁定 -->
<properties>
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
编写index.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Hello World!</h2>
<%--超链接--%>
<h3>入门</h3>
<a href="/hello.do" >入门程序</a>
</body>
</html>
编写Controller类和方法
/**
* 表现层的类 交给spring去管理
*/
@Controller
//@RequestMapping("/hello") //第一层路径
public class HelloController {
@RequestMapping("/hello.do") //第二层路径
public String sayHello(){
System.out.println("SpringMVC入门程序!!");
return "suc";
}
}
创建一个springMVC.xml配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解扫描 -->
<!-- 配置spring创建容器时要扫描的包 -->
<context:component-scan base-package="com.qcby.controller"/>
<!-- 配置视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
在WEB-INF下面放置一个pages包,创建一个suc.jsp,这就是成功页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>成功页面</title>
</head>
<body>
<h1>SpringMVC入门案例成功了!!</h1>
</body>
</html>
配置核心的控制器(配置DispatcherServlet)
在web.xml配置文件中核心控制器DispatcherServle
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- 总的Servlet -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 加载springmvc.xml配置文件,配置的是Spring配置 -->
<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>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
之后直接打开就可以了
流程如下:启动tomcat后找到web.xml,就可以加载入SpringMVC.xml的配置文件,配置文件中可以加载视图解析器和找到要管理的类,通过web.xml中的拦截器找到*.do就可以找到方法,调用方法返回字符串suc,最后通过视图解析器找到WEB-INF/pages中的suc.jsp,启动界面
执行流程
RequestMapping注解
在上面的controller中用到了RequestMapping注解,
RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系,通过该注解才能使前端发起请求时找到后端中对应的方法。
RequestMapping注解可以作用在方法和类上
1.作用在类上:第一级的访问目录
2.作用在方法上:第二级的访问目录
3.细节:路径可以不编写 / 表示应用的根目录开始
RequestMapping的属性
1.path 指定请求路径的url
2.value value属性和path属性是一样的,但不可以省略
3.mthod 指定该方法的请求方式
4.params 指定限制请求参数的条件
例如:
@RequestMapping(path = "/save.do",method = {RequestMethod.GET},params = "username")
请求参数的绑定
SpringMVC 简单的一个或者两个直接可以传递的用参数就可以接收,但是要保证参数名和表单里的input标签的name属性一样
底层通过反射获取到参数进行对比,一旦匹配了就可以接收到
配置文件:
<context:component-scan base-package="com.qcby"/>
<!-- 配置视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
基本类型数据
Controller类中接收数据
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/save.do")
public String save(String username,Integer age){
System.out.println("名字:"+username);
return "suc";
}
}
jsp页面中表单提交数据
<head>
<title>演示请求参数的绑定</title>
</head>
<body>
<h3>SpringMVC请求参数的绑定</h3>
<form method="post" action="/user/save.do">
姓名:<input type="text" name="username">
年龄:<input type="text" name="age">
<input type="submit" value="提交" />
</form>
</body>
引用类型和集合数据类型
加上了引用数据类型和list集合和map集合
前端:
</form>
<h3>SpringMVC请求参数的绑定(实体类中由引用类型和集合的绑定)</h3>
<form method="post" action="/user/save3.do">
姓名:<input type="text" name="username">
年龄:<input type="text" name="age">
工资:<input type="text" name="address.money">
工资1:<input type="text" name="list[0].money">
工资2:<input type="text" name="map['aaa'].money">
<input type="submit" value="提交" />
</form>
实体类:
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/save3.do")
public String save3(User user){
System.out.println(user);
return "suc";
}
}
public class Address {
private Double money;
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
@Override
public String toString() {
return "Address{" +
"money=" + money +
'}';
}
}
public class User {
private String username;
private Integer age;
private Address address;
private List<Address> list;
private Map<String,Address> map;
public String getName() {
return username;
}
public Map<String, Address> getMap() {
return map;
}
public void setName(String username) {
this.username = username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public List<Address> getList() {
return list;
}
public void setList(List<Address> list) {
this.list = list;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", age=" + age +
", address=" + address +
", list=" + list +
", map=" + map +
'}';
}
}
如果出现中文乱码问题
可以在配置文件中添加
<!-- 配置过滤器,解决中文乱码的问题 -->
<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>
日期类型数据
使用日期时xxxx/xx/xx这种形式是可以绑定的,但是实际中xxxx-xx-xx这种形式更多,因此要用别的方法来获取绑定
一、使用DateTimeFormat注解的方式
在类型中的变量前加上注解,pattern为数据按什么格式返回
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;
再在配置文件中加上
<mvc:annotation-driven>
二、自定义类型转换器
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
*
* 自定义类型转换器 把String转换成Date
*/
public class StringToDate implements Converter<String,Date>{
/**
* 进行类型转换的方法
* @param s 用户输入的内容
* @return
*/
@Override
public Date convert(String s) {
// 判断
if(s == null){
throw new RuntimeException("请输入内容");
}
// 进行转换
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
// 进行转换
return sdf.parse(s);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
注册自定义类型转换器,在springmvc.xml配置文件中编写配置
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解扫描 -->
<!-- 配置spring创建容器时要扫描的包 -->
<context:component-scan base-package="com.qcby"/>
<!-- 配置视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--配置日期类型转换器,类型转换器的组件,把日期类型转换注入到组件对象中-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.qcby.demo2.StringToDate" />
</set>
</property>
</bean>
<!--让映射器、适配器和处理器生效(默认不配置也是可以的)-->
<mvc:annotation-driven conversion-service="conversionService"/>
</beans>
常用的注解
- RequestParam注解
作用:把请求中的指定名称的参数传递给控制器中的形参赋值
属性
a.value:请求参数中的名称
b.required:请求参数中是否必须提供此参数,默认值是true,必须提供,不想传递可以false
c.defaultValue:设置默认值
- RequestBody注解
作用:用于获取请求体的内容(注意:get方法不可以)
属性:required:是否必须有请求体,默认值是true
@RequestMapping("/save2.do")
public String save2(@RequestBody String body){
System.out.println("请求体内容:"+body);
return "suc";
}
- PathVaribale注解
作用:拥有绑定url中的占位符的。例如:url中有/delete/{id},{id}就是占位符
属性:value:指定url中的占位符名称
Restful风格的URL
1.请求路径一样,可以根据不同的请求方式去执行后台的不同方法
2.restful风格的URL优点
a.结构清晰
b.符合标准
c.易于理解
d.扩展方便
@Controller
// @RequestMapping("/emp")
public class EmpController {
@RequestMapping(path = "/emp",method = RequestMethod.POST)
public String save(){
System.out.println("保存员工...");
return "suc";
}
@RequestMapping(path = "/emp",method = RequestMethod.GET)
public String findAll(){
System.out.println("查询员工...");
return "suc";
}
@RequestMapping(path = "/emp/{id}",method = RequestMethod.GET)
public String findById(@PathVariable(value = "id") Integer id){
System.out.println("通过id查询员工..."+id);
return "suc";
}
}
修改配置文件
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
- RequestHeader注解
作用:获取指定请求头的值
属性:value:请求头的名称
@RequestMapping("/save3.do")
public String save3(@RequestHeader(value = "Accept") String header){
System.out.println("Accept请求头的值:"+header);
return "suc";
}
- CookieValue注解
作用:用于获取指定cookie的名称的值
属性:value:cookie的名称
@RequestMapping("/save4.do")
public String save4(@CookieValue(value = "JSESSIONID") String cookie){
System.out.println("值:"+cookie);
return "suc";
}
响应数据和结果视图
返回值分类
导入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
前端控制器和过滤器web.xml
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!--过滤器-->
<filter>
<filter-name>charset</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>charset</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--总的Servlet-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--加载springmvc.xml配置文件,配置的是Spring配置-->
<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>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
springmvc.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解扫描-->
<!-- 配置spring创建容器时要扫描的包 -->
<context:component-scan base-package="com.qcby"/>
<!-- 设置静态资源不过滤 -->
<!--<mvc:resources location="/css/" mapping="/css/**"/> <!– 样式 –>-->
<!--<mvc:resources location="/images/" mapping="/images/**"/> <!– 图片 –>-->
<!--<mvc:resources location="/js/" mapping="/js/**"/> <!– javascript –>-->
<!-- 配置视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!--配置文件上传的组件 id名称固定 multipartResolver-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--设置上传文件的总大小 8M = 8 * 1024 * 1024 -->
<property name="maxUploadSize" value="8388608"/>
</bean>
<!--让映射器、适配器和处理器生效-->
<mvc:annotation-driven/>
</beans>
Controller方法返回各种类型:
@Controller
//@RestController //使该控制器下的所有的方法的返回都是json形式返回
public class UserController {
/**
* 返回String类型
* @return
*/
@RequestMapping("/save.do")
public String save(){
System.out.println("返回String的形式!!!");
return "suc";
}
/**
* 返回void类型 没有返回值
* /WEB-INF/pages/save1.jsp 请求路径的jsp页面
* @return
*/
@RequestMapping("/save1.do")
public void save1(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("返回void的形式!!!");
//request.getRequestDispatcher("/pages/suc.jsp").forward(request,response);
response.getWriter().print("hello");
}
/**
* 返回ModelAndView 对象形式
* @return
*/
@RequestMapping("/save2.do")
public ModelAndView save2(){
System.out.println("返回ModelAndView的形式!!!");
// 创建mv对象
ModelAndView mv=new ModelAndView();
// 设置逻辑视图的名称
mv.setViewName("suc");
// 把一些数据,存储到mv对象中
mv.addObject("msg", "用户名或者密码已经存在");
return mv;
}
/**
* 返回ModelAndView 对象形式
* @return
*/
@RequestMapping("/save3.do")
public String save3(Model model){
System.out.println("返回ModelAndView的第二种形式!!!");
// 创建mv对象
// 设置逻辑视图的名称
// 把一些数据,存储到mv对象中
model.addAttribute("msg", "用户名或者密码已经存在00002");
return "suc";
}
SpringMVC框架提供的转发和重定向
forward请求转发
controller方法返回String类型,想进行请求转发也可以编写成
@RequestMapping("/save4.do")
public String save4(){
System.out.println("请求转发执行了...");
return "forward:/pages/suc.jsp";
}
redirect重定向
controller方法返回String类型,想进行重定向也可以编写成
@RequestMapping("/save5.do")
public String save5(){
System.out.println("重定向执行了...");
return "redirect:/pages/suc.jsp";
}
以上方法的前端界面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>响应结果和视图的形式</title>
</head>
<body>
<H1>返回String的形式!!</H1>
<a href="/save.do">返回String的形式!</a>
<H1>返回void的形式!!</H1>
<a href="/save1.do">返回Viod的形式!</a>
<H1>返回ModelAndView的形式!!</H1>
<a href="/save2.do">返回ModelAndView的形式!</a>
<H1>返回ModelAndView的第二种形式!!</H1>
<a href="/save3.do">返回ModelAndView的形式!</a>
<H1>springMVC请求转发</H1>
<a href="/save4.do">springMVC中的请求转发形式!</a>
<H1>springMVC重定向</H1>
<a href="/save5.do">springMVC中的重定向形式!</a>
</body>
</html>
ResponseBody响应json数据
json字符串和JavaBean对象互相转换的过程中,需要使用jackson的jar包
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img、css、js)也会被拦截到,从而不能被使用。解决问题就是需要配置静态资源不进行拦截,在springmvc.xml配置文件添加如下配置
标签配置不过滤
1.location元素表示webapp目录下的包下的所有文件
2.mapping元素表示以/static开头的所有请求路径,如/static/a 或者/static/a/b
<!-- 设置静态资源不过滤 -->
<mvc:resources location="/css/" mapping="/css/**"/> <!-- 样式 -->
<mvc:resources location="/images/" mapping="/images/**"/> <!-- 图片 -->
<mvc:resources location="/js/" mapping="/js/**"/> <!-- javascript -->
jsp代码编写
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>发送AJAX异步请求</title>
<script src="../js/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
//页面加载
$(function () {
//单击事件
$("#btn").click(function () {
//编写发送ajax的异步请求 传递json数据 返回json数据
$.ajax({
//异步请求路径
url:"/save6.do",
//请求方式
type:"post",
//传递的数据类型及编码
contentType:"application/json;charset=UTF-8",
//传递的参数
data:'{"username":"haha","age":"20"}',
//回调返回的数据类型 必须是json
dataType: "json",
//回调函数
success:function(d){
//处理我们拿到的服务器返回的数据
// 编写很多代码
alert(d.username+" - "+d.age);
}
})
})
})
</script>
</head>
<body>
<h1>发送AJAX异步请求 传递JSON数据给服务端 服务端响应JSON数据给前端</h1>
<input type="button" id="btn" value="ajax交互">
</body>
</html>
后台代码编写
@RequestMapping("/save6.do")
@ResponseBody
public /*@ResponseBody*/ User save6(@RequestBody User user){
System.out.println("接收json数据返回json数据的方法执行了...");
System.out.println("前端传递的json串通过注解转变成了对象:"+user);
user.setAge(28);
user.setUsername("张三");
//Object json = JSONObject.toJSON(user1);
return user;
}
public class User {
private String username;
private Integer age;
public User() {
}
public User(String username, Integer age) {
this.username = username;
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", age=" + age +
'}';
}
}
文件上传
导入依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
-------重点是下面两个jar包---------
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
</dependencies>
编写一个界面
<html>
<head>
<title>springMVC文件上传</title>
</head>
<body>
<h3>文件上传</h3>
<form action="/fileupload.do" method="post" enctype="multipart/form-data">表单中记得写enctype="multipart/form-data"
选择文件:<input type="file" name="upload" /><br/>
<input type="submit" value="上传" />
</form>
</body>
</html>
配置文件解析器
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解扫描 -->
<!-- 配置spring创建容器时要扫描的包 -->
<context:component-scan base-package="com.qcby"/>
<!-- 配置视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--配置文件上传的解析器组件。id的名称是固定,不能乱写-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--设置上传文件的总大小 8M = 8 * 1024 * 1024 -->
<property name="maxUploadSize" value="8388608" />
</bean>
<!--让映射器、适配器和处理器生效(默认不配置也是可以的)-->
<mvc:annotation-driven />
</beans>
实现类
@Controller
public class UploadController {
@RequestMapping("/fileupload.do")
public String upload(MultipartFile upload, HttpServletRequest request)throws IOException {
//1. 文件上传的位置 http://127.0.0.1/项目名称/文件夹/01.jpg
String realPath = request.getSession().getServletContext().getRealPath("/uploads");
File file= new File(realPath);
if(!file.exists()){
file.mkdirs();
}
//2.文件名称需不需要处理 每一次上传生成一个唯一的文件名
//获取文件名
String filename = upload.getOriginalFilename();
// 把文件的名称修改成为一的值 sdfs-csdf-fwer-sdfw
String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
// 直接字符串拼接,产生唯一的值
filename = uuid+"_"+filename;
System.out.println("文件名称:"+filename);
//3.文件上传 file=uploads filename=sdfscsdffwersdfw.jpg
upload.transferTo(new File(file,filename));
return "suc";
}
}
上传好的文件会在target文件夹中
异常处理
异常处理思路:Controller调用service,service调用dao,异常都是向上抛出的,最终有DispatcherServlet找异常处理器进行异常的处理。
编写类模拟异常
@Controller
@RequestMapping("/role")
public class RoleController {
/**
* 模拟异常
* @return
*/
@RequestMapping("findAll.do")
public String findAll(){
System.out.println("controller方法执行了");
int i =10/0;
return "suc";
}
}
自定义异常类
public class MyException extends Exception{
private String message;
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public MyException(String message) {
this.message = message;
}
}
自定义异常处理类
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SysExceptionResolver implements HandlerExceptionResolver {
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
e.printStackTrace();
//做强转
MyException exception = null;
// 判断
if(e instanceof MyException){
exception=(MyException)e;
}else {
exception = new MyException("系统正在维护,请联系管理员");
}
// 存入异常提示信息
ModelAndView mv = new ModelAndView();
mv.addObject("errorMsg",e.getMessage());
// 设置跳转的页面
mv.setViewName("error");
return mv;
}
}
配置异常处理器
<bean id="sysExceptionResolver" class="com.qcby.controller.SysExceptionResolver" />
jsp错误页面代码
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>错误提示页面</title>
</head>
<body>
<h3>错误的友好提示页面</h3>
${errorMsg}
</body>
</html>
SpringMVC的拦截器
拦截器的概述
SpringMVC框架中的拦截器用于对处理器进行预处理和后处理的技术。
可以定义拦截器链,连接器链就是将拦截器按着一定的顺序结成一条链,在访问被拦截的方法时,拦截器链中的拦截器会按着定义的顺序执行。
拦截器和过滤器的功能比较类似,有区别:
a.过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术。
b.拦截器是SpringMVC框架独有的。
c.过滤器配置了/*,可以拦截任何资源。
d.拦截器只会对控制器中的方法进行拦截。
拦截器也是AOP思想的一种实现方式
想要自定义拦截器,需要实现HandlerInterceptor接口
自定义拦截器
controller中的方法
@Controller
@RequestMapping("/dept")
public class DeptController {
public String finaAll(){
System.out.println("controller方法执行了...");
return "suc";
}
}
建类,实现HandlerInterceptor接口,重写需要的方法
public class MyInterceptor implements HandlerInterceptor {
/**
* 拦截器拦截后执行的方法
* boolean true放行
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截器preHandle方法执行了...");
// 拦截,不放行
//return false;
//放行
return true;
}
}
在springmvc.xml中配置拦截器类
<mvc:interceptors>
<mvc:interceptor>
<!--该拦截器拦截哪些资源-->
<mvc:mapping path="/dept/**"/>
<!--哪些资源不想拦截
<mvc:exclude-mapping path="" />
-->
<!--拦截器对象-->
<bean class="com.qcby.controller.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
配置多个拦截器
再编写一个拦截器的类
配置2个拦截器
<!--配置拦截器们-->
<mvc:interceptors>
<!--配置拦截器-->
<mvc:interceptor>
<!--该拦截器拦截哪些资源-->
<mvc:mapping path="/dept/**"/>
<!--哪些资源不想拦截
<mvc:exclude-mapping path="" />
-->
<!--拦截器对象-->
<bean class="com.qcbyjy.demo4.MyInterceptor2" />
</mvc:interceptor>
<!--配置拦截器-->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.qcbyjy.demo4.MyInterceptor3" />
</mvc:interceptor>
</mvc:interceptors>
HandlerInterceptor接口中的方法
preHandle方法是controller方法执行前拦截的方法
1.可以使用request或者response跳转到指定的页面
2.return true放行,执行下一个拦截器,如果没有拦截器,执行controller中的方法。
3.return false不放行,不会执行controller中的方法。
postHandle是controller方法执行后执行的方法,在JSP视图执行前。
1.可以使用request或者response跳转到指定的页面
2.如果指定了跳转的页面,那么controller方法跳转的页面将不会显示。
postHandle方法是在JSP执行后执行
request或者response不能再跳转页面了
原文地址:https://blog.csdn.net/m0_62902381/article/details/136995434
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!