文章目录
1.SpringMVC的基本概念
1)MVC概念:
M:model,模型,javaBean等
V:view,视图,JSP等
C:contrller,控制器,Servlet等
数据从浏览器端传过来的时候,先用Servlet来接收,然后封装成一个javaBean,传到业务层,持久层进行处理,然后再返回相应的javaBean,再传给jsp,进行页面的显示,这就是MVC与三层架构之间的联系了。
2)与Struts2的简单对比:
共同点:
- 他们都是表现层的框架,都是基于MVC模型来编写的。
- 他们的底层都离不开原始的ServletAPI
- 他们的处理请求的机制都是一个核心控制器
区别: - springMVC的入口是Servlet,而Struts2的入口是一个Filter
- SpringMVC是基于方法设计的,而Struts2是基于类进行设计的,Struts2每次创建都会新建一个动作类,所以运行速度上会比SpringMVC慢。
- SpringMVC使用更加简洁,同时还支持JSR303,处理ajax请求会更加的快捷。
- Struts2支持OGNL表达式开发效率相对于SpringMVC要高,但是执行效率却比JSTL语句要慢。
2.SpringMVC基本使用:
1)架包支持配置文件的编写:
<?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>com.xxx</groupId>
<artifactId>springMVC_day01_01_start</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>springMVC_day01_01_start 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>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<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>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>springMVC_day01_01_start</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
2)在web.xml中配置SpringMVC的核心容器:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMvcConfig.xml</param-value>
</init-param>
<!-- 标记容器是否在启动的时候就加载这个servlet -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
3)编写jsp跳转,index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>index</title>
</head>
<body>
<h2>入门mvc</h2>
<a href="hello">示例</a>
</body>
</html>
成功后跳转到的页面success.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>success</title>
</head>
<body>
<h3>mvc成功配置</h3>
</body>
</html>
4)配置一个servlet(一个类控制器),处理页面的跳转请求:
@Controller
public class Helloservlet {
/**
* 配置接受请求
* @return
*/
@RequestMapping(path = "/hello")
public String hello(){
System.out.println("简单入门案例");
return "success";
}
}
5)配置SpringMVC的支持:
在resources下配置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">
<!-- 配置包扫描器 -->
<context:component-scan base-package="com.xxx"></context:component-scan>
<!-- 配置视图解释器对象 -->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!--开启springMVC框架对注解的支持-->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
简单总结:
1)SpringMVC工作流程总结:
启动服务器的时候,首先是web.xml文件被加载,服务器读取到第一个Servlet(所有的Servlet都是在web.xml中配置的),并把DispatcherServlet创建成一个类对象,然后把这个类作为全局的控制器,控制全部的请求、响应,在DispatcherServlet类中还定义了一个初始化的的参数contextConfigLocation,表示初始化控制器类的时候需要加载这个文件,然后通过此文件来创建返回参数的视图InternalResourceViewResolver对象。大概的流程图如下:
2)SpringMVC的使用对注入的jar包有严格的要求,必须把所有的jar包都导入进来才可以使用框架。
3.SpringMVC对于请求参数的处理:
1)新增一个用于发送各种参数请求的jsp页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>请求参数测试</title>
</head>
<body>
<%--<a href="param/testParam?username='hehe'&password='123'">测试请求参数</a>--%>
<%-- 将数据封装到一个Account的实体类中去,里边包含了一个User对象 --%>
<%-- <form action="param/testBean" method="post">
姓名:<input type="text" name="username"/></br>
密码:<input type="text" name="password"/></br>
性别:<input type="text" name="sex"/></br>
用户姓名:<input type="text" name="user.uname"/></br>
用户年龄:<input type="text" name="user.age"/></br>
<input type="submit" value="提交">
</form>--%>
<%-- 将数据封装到Account实体类中去,里边包含了一个list和一个map --%>
<%--<form action="param/testBean2" method="post">
姓名:<input type="text" name="username"/></br>
密码:<input type="text" name="password"/></br>
性别:<input type="text" name="sex"/></br>
用户姓名:<input type="text" name="list[0].uname"/></br>
用户年龄:<input type="text" name="list[0].age"/></br>
用户姓名:<input type="text" name="map['one'].uname"/></br>
用户年龄:<input type="text" name="map['one'].age"/></br>
<input type="submit" value="提交">
</form>--%>
<%-- 类型转换器的使用 --%>
<%--<form action="param/saveUser" method="post">
用户姓名:<input type="text" name="uname"/></br>
用户年龄:<input type="text" name="age"/></br>
用户生日:<input type="text" name="birthday"/></br>
<input type="submit" value="提交">
</form>--%>
<a href="param/servletAPI">测试原生API</a>
</body>
</html>
2)新增一个专门处理参数请求的servlet(controller)对象实例:
@Controller
@RequestMapping(path="/param")
public class ParamRequest {
@RequestMapping(path = "/testParam")//path也可以不加,里边的/也可以不加
public String testParam(String username,String password){
System.out.println("测试参数");
System.out.println("username"+username);
System.out.println("password"+password);
return "success";
}
@RequestMapping(path = "/testBean")
public String testBean(Account account){
System.out.println("测试Bean");
System.out.println("username"+account.toString());
return "success";
}
@RequestMapping(path = "/testBean2")
public String testBean2(Account account){
System.out.println("测试Bean");
System.out.println("account"+account.toString());
return "success";
}
@RequestMapping(path = "/saveUser")
public String testBean2(User user){
System.out.println("测试ser");
System.out.println("account"+user.toString());
return "success";
}
@RequestMapping(path = "/servletAPI")
public String testBean2(HttpServletRequest request, HttpServletResponse response){
System.out.println("测试原生态的Servlet");
HttpSession session = request.getSession();
System.out.println(session);
ServletContext servletContext = session.getServletContext();
System.out.println(servletContext);
return "success";
}
}
注意:
@Controller 是标记在Controller 类(包和类名之间)上面的。用于指示Spring类的实例是一个控制器。Controller接口的实现类只能处理一个单一请求动作,而@Controller注解的控制器可以支持同时处理多个请求动作,更加灵活。Spring使用 扫描机制 查找应用程序中所有基于注解的控制器类。分发处理器 会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping注解,而使用@RequestMapping注解的方法才是真正处理请求的处理器。为了保证能找到控制器,需要完成两件事情:
①在Spring MVC的配置文件中,使用context:component-scan/元素,该元素的功能为:启动包扫描功能,以便注册带有@Controller,@Service,@repository,@Component等注解的类成为Spring的Bean。
②<context:component-scan base-package=“包路径”>
应该 将所有控制器类都在基本包下,并且指定扫描该包
4.SpringMVC注解的使用:
1)发送请求到注解处理页面的jsp代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注解参数的使用</title>
</head>
<body>
<%-- 常用的注解使用 --%>
<a href="anno/testAnnoParam?username=哈哈">测试注解参数</a>
<%-- 请求体的注解使用 --%>
<form action="anno/testRequestBody" method="post">
用户姓名:<input type="text" name="username"/></br>
用户年龄:<input type="text" name="age"/></br>
<input type="submit" value="提交">
</form>
<%-- 测试路径参数的使用 --%>
<a href="anno/testPathVariable/10">测试路径参数</a><br>
<%-- 测试获取请求头的信息 --%>
<a href="anno/testRequestHeader">测试获取请求头信息</a><br>
<%-- 测试获取请求cookie的信息 --%>
<a href="anno/testCookieValue">测试获取请求头信息</a><br>
<%-- 测试ModelAttribute注解 --%>
<form action="anno/testModelAttribute" method="post">
用户姓名:<input type="text" name="username"/></br>
用户年龄:<input type="text" name="age"/></br>
<input type="submit" value="提交">
</form>
<%-- 测试SessionAttributes注解 --%>
<a href="anno/testSessionAttributes">测试SessionAttributes</a>
</body>
</html>
2)注解处理的java类:
@Controller
@RequestMapping(path = "/anno")
@SessionAttributes(value = {"msg"}) //设置全局的session
public class AnnoRequest {
/**
* 测试注解的参数
*/
@RequestMapping(path = "/testAnnoParam")
public String testAnnoParam(@RequestParam(name = "username") String name){
System.out.println(name);
return "success";
}
/**
* 测试获取请求体的注解
*/
@RequestMapping(path = "/testRequestBody")
public String testRequestBody(@RequestBody String body){
System.out.println(body);
return "success";
}
/**
* 使用restFul风格编码,测试获取请求路径的注解
*/
@RequestMapping(path = "/testPathVariable/{sid}")
public String testPathVariable(@PathVariable(name = "sid") String id){
System.out.println(id);
return "success";
}
/**
* 测试获取请求头的信息
*/
@RequestMapping(path = "/testRequestHeader")
public String testRequestHeader(@RequestHeader(name = "Accept") String header){
System.out.println(header);
return "success";
}
/**
* 测试获取Cookie的信息
*/
@RequestMapping(path = "/testCookieValue")
public String testCookieValue(@CookieValue(name = "JSESSIONID") String session){
System.out.println(session);
return "success";
}
/**
* 测试 ModelAttribute
*/
@RequestMapping(path = "/testModelAttribute")
public String testModelAttribute(@ModelAttribute(name = "abc") User user){
System.out.println(user);
return "success";
}
// /**
// * 使用ModelAttribute的方法会最先地执行
// */
// @ModelAttribute
// public User showUser(String username){
// System.out.println("ModelAttribute方法执行了");
// //模拟从数据库中取出相对应名字的用户数据
// User user = new User();
// user.setUname(username);
// user.setAge(30);
// user.setBirthday(new Date());
// return user;
// }
/**
* 使用ModelAttribute的方法会最先地执行,使用一个map来接收
*/
@ModelAttribute
public void showUser2(String username, Map<String,User> map){
System.out.println("ModelAttribute方法执行了");
//模拟从数据库中取出相对应名字的用户数据
User user = new User();
user.setUname(username);
user.setAge(30);
user.setBirthday(new Date());
map.put("abc",user);
}
/**
* SessionAttributes 的注解使用
*/
@RequestMapping(path = "/testSessionAttributes")
public String testSessionAttributes(Model model){
System.out.println("SessionAttributes方法的执行。。。");
model.addAttribute("msg","测试数据");
return "success";
}
}
5.处理字符乱码的过滤器设置:
主要的思路就是设置一个全局的过滤器,引入spring框架的字符编码过滤器类:
配置的web.xml:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- 配置前端控制器 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMvcConfig.xml</param-value>
</init-param>
<!-- 标记容器是否在启动的时候就加载这个servlet,正数的值越小,启动该servlet的优先级越高 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</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>
到这里,SpringMVC的主要请求(request)配置,请求参数配置都已经介绍过了,后边继续介绍响应的配置。
6.SpringMVC对于响应参数的处理:
基本配置和上边的差不多,在使用json数据传输的时候加多了一个json的支持,并且也是必须使用jackjson这个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>
在springMvcConfig.xml中声明对哪些资源不拦截:
<!-- 配置前端控制器对哪些静态资源不拦截 -->
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/images/" mapping="/images/**"/>
<mvc:resources location="/js/" mapping="/js/**"/>
编写响应参数的案例页面jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>response</title>
<script src="js/jquery.min.js"></script>
<script>
$(function () {
$("#btn").click(function () {
// alert("hello");
//发送ajax请求
$.ajax({
url:"user/testAjax",
data:'{"userName":"zhangsan","password":"123","age":30}',//一定要非常注意这种json数据格式的书写!!!
contentType:"application/json;charset=UTF-8",
dataType:"json",
type:"POST",
success:function (data) {
//对传回来的数据进行处理
alert(data);
alert(data.userName);
}
});
});
})
</script>
</head>
<body>
<a href="user/testResponse">testResponse测试</a><br>
<a href="user/testVoid">testVoid 测试</a><br>
<a href="user/testModelAndView">testModelAndView 测试</a><br>
<a href="user/testForwardAndRedirect">testForwardAndRedirect 测试</a><br>
<button id="btn">发送ajax请求</button>
</body>
</html>
编写控制器:
@Controller
@RequestMapping(path = "/user")
public class ResponseController {
@RequestMapping(path = "/testResponse")
public String testResponse(Model model){
System.out.println("testResponse。。。");
//模拟从数据库中取出数据返回结果
User user = new User();
user.setUserName("zhangsan");
user.setPassword("123");
user.setAge(30);
//将user对象放到响应的request域中去
model.addAttribute("user",user);
return "success";
}
//使用原生的Servlet进行转发请求,或者重定向
@RequestMapping(path = "/testVoid")
public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception{
System.out.println("testVoid。。。");
//请求转发演示
// request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
//重定向演示
// response.sendRedirect(request.getContextPath()+"/index.jsp");
//通过write方法流的方式写入,因为要输入中文,所以先解决中文乱码问题
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("您好!");
return;
}
/**
* 测试使用ModelAndView
* @return
*/
@RequestMapping(path = "/testModelAndView")
public ModelAndView testModelAndView(){
System.out.println("testModelAndView。。。");
ModelAndView mv = new ModelAndView();
//模拟从数据库中取出数据返回结果
User user = new User();
user.setUserName("张三");
user.setPassword("345");
user.setAge(30);
//将user对象放到响应的request域中去
mv.addObject("user",user);
//存入跳转的页面,也会去找视图解释器的
mv.setViewName("success");
return mv;
}
/**
* 测试使用返回关键字sendRedirect或者forward请求转发
* @return
*/
@RequestMapping(path = "/testForwardAndRedirect")
public String testForwardAndRedirect(){
System.out.println("testForwardAndRedirect。。。");
//请求转发关键字的使用演示
// return "forward:/WEB-INF/pages/success.jsp";
//重定向的关键字演示
return "redirect:/index.jsp";
}
/**
* 测试使用返回关键字sendRedirect或者forward请求转发
* 在这个之前,在支持架包中添加了支持json数据封装的架包
* @return
*/
@RequestMapping(path = "/testAjax")
public @ResponseBody User testAjax(@RequestBody User user){
System.out.println("testAjax。。。");
//使用@RequestBody处理ajax类的请求参数,使用jackjson架包直接把前端传过来的json数据直接封装成了user对象
System.out.println(user);
user.setUserName("zhaosi");
//因为使用了架包,这里返回的虽然表面上看就是一个user对象,但是其实是一个json数据的
return user;
}
}
在WEB-INF的pages文件夹中编写响应页面success:
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>执行成功</h3>
${user.username}
${user.password}
</body>
</html>
7.文件上传功能:
1)在pom.xml中添加上传架包的支持:
<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>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.18.1</version>
</dependency>
2)编写web.xml,和上边的都一样的,在spring的配置文件中需要添加文件解释器:
<!-- 配置文件解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"/>
</bean>
3)编写文件上传的jsp页面:
upload.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>upload</title>
</head>
<body>
<a href="user/testUpload">文件上传跳转</a>
<!-- 演示文件上传 -->
<form action="user/upload" method="post" enctype="multipart/form-data"><!-- 这个enctype是必须要写的!!! -->
文件上传:<input type="file" name="upload"><br>
<input type="submit" value="提交"/>
</form>
<h2>SpringMVC方式上传文件</h2>
<form action="user/upload2" method="post" enctype="multipart/form-data"><!-- 这个enctype是必须要写的!!! -->
文件上传:<input type="file" name="upload"><br>
<input type="submit" value="提交"/>
</form>
<h2>SpringMVC跨服务器方式上传文件</h2>
<form action="user/upload3" method="post" enctype="multipart/form-data"><!-- 这个enctype是必须要写的!!! -->
文件上传:<input type="file" name="upload"><br>
<input type="submit" value="提交"/>
</form>
</body>
</html>
编写文件上传的控制器:
@Controller
@RequestMapping(path = "/user")
public class UserController {
@RequestMapping(path = "/testUpload")
public String testResponse(){
System.out.println("文件上传。。。");
return "success";
}
@RequestMapping(path = "/upload")
public String testUpload(HttpServletRequest request) throws Exception{
System.out.println("文件上传。。。");
//使用fileupload组件进行文件的上传
String path = request.getSession().getServletContext().getRealPath("/uploads/");
File file = new File(path);
//判断该路径是否存在
if(!file.exists()){
//如果不存在就新建一个文件夹
file.mkdirs();
}
//解析request对象,获取上传文件项
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items = upload.parseRequest(request);
//遍历
for(FileItem item:items){
//进行判断,当前的item对象是否是上传的文件项
if(item.isFormField()){
//说明是普通标单项
}else {
//说明是上传文件项
//获取上传文件的名称
String fileName = item.getName();
//使用UUID给文件名一个唯一值
String uid = UUID.randomUUID().toString().replace("-","");
fileName = fileName+"_"+uid;
//完成文件上传
item.write(new File(path,fileName));
//删除临时文件
item.delete();
}
}
return "success";
}
/**
* springmvc方式上传文件
* @param request
* @param upload
* @return
* @throws Exception
*/
@RequestMapping(path = "/upload2")
public String testUpload2(HttpServletRequest request, MultipartFile upload) throws Exception{
System.out.println("文件上传。。。");
//使用fileupload组件进行文件的上传
String path = request.getSession().getServletContext().getRealPath("/uploads/");
File file = new File(path);
//判断该路径是否存在
if(!file.exists()){
//如果不存在就新建一个文件夹
file.mkdirs();
}
//获取上传文件的名称
String fileName = upload.getOriginalFilename();
//使用UUID给文件名一个唯一值
String uid = UUID.randomUUID().toString().replace("-","");
fileName = fileName+"_"+uid;
//完成文件上传
upload.transferTo(new File(path,fileName));
return "success";
}
/**
* 跨服务器上传文件
* @param upload
* @return
* @throws Exception
*/
@RequestMapping(path = "/upload3")
public String testUpload3(MultipartFile upload) throws Exception{
System.out.println("文件上传。。。");
//上传的服务器路径名称
String path = "http://localhost:9090/springMVC_day02_03_uploadServer_war/uploads/";
//获取上传文件的名称
String fileName = upload.getOriginalFilename();
//使用UUID给文件名一个唯一值
String uid = UUID.randomUUID().toString().replace("-","");
fileName = uid+"_"+fileName;
//创建一个客户端对象
Client client = Client.create();
//与图片服务器建立连接
WebResource webResource = client.resource(path+fileName);
//实现文件的上传
webResource.put(upload.getBytes());
return "success";
}
}
注意:如果是跨服务器的上传,服务器端只负责接受文件即可,所以将服务器端的程序部署在新的tomcat上,然后再添加输出文件夹即可。
7.异常处理:
1)配置和上边的基本一样,在spring的配置文件中需要添加:
<!-- 配置异常处理器 -->
<bean id="sysExceptionResolver" class="com.xxx.exception.SysExceptionResolver"/>
2)在pages中配置异常处理的jsp页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>错误页面</title>
</head>
<body>
${errorMsg}
</body>
</html>
3)自定义异常类:
SysException:
public class SysException extends Exception {
//存储提示信息
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public SysException(String msg) {
this.msg = msg;
}
}
4)定义一个异常解释器:
public class SysExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
SysException exception = null;
if(e != null){
exception = (SysException) e;
} else {
exception = new SysException("系统正在维护。。。");
}
ModelAndView mv = new ModelAndView();
mv.addObject("errorMsg",exception.getMsg());
mv.setViewName("error");
return mv;
}
}
5)编写一个控制器类:
@Controller
@RequestMapping(path = "/user")
public class Response_ExceptionController {
@RequestMapping(path = "/testException")
public String testResponse() throws SysException{
System.out.println("testException。。。");
try {
int i = 1/0;
} catch (Exception e) {
e.printStackTrace();
throw new SysException("系统出现异常。。。");
}
return "success";
}
}
6)SpringMVC专属拦截器的使用:
1.和上边一样配置好pom.xml之后,配置spring的配置文件:
<?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">
<!-- 配置包扫描器 -->
<context:component-scan base-package="com.xxx"></context:component-scan>
<!-- 配置视图解释器对象,Controller在处理请求之后会跳转到的页面 -->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 配置日期转换器 -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.xxx.util.StringToDateConverter"/>
</set>
</property>
</bean>
<!-- 配置前端控制器对哪些静态资源不拦截 -->
<!-- <mvc:resources location="/css/" mapping="/css/**"/>-->
<!-- <mvc:resources location="/images/" mapping="/images/**"/>-->
<mvc:resources location="/js/" mapping="/js/**"/>
<!-- 配置文件解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"/>
</bean>
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 配置拦截器对哪些资源进行拦截 -->
<mvc:mapping path="/user/*"/>
<!-- 配置拦截器对哪些资源不拦截 -->
<!-- <mvc:exclude-mapping path=""/>-->
<!-- 配置拦截器的对象 -->
<bean class="com.xxx.interceptor.MyInterceptor1"/>
</mvc:interceptor>
<!-- 配置第二个拦截器 -->
<mvc:interceptor>
<!-- 配置拦截器对哪些资源进行拦截 -->
<mvc:mapping path="/**"/>
<!-- 配置拦截器对哪些资源不拦截 -->
<!-- <mvc:exclude-mapping path=""/>-->
<!-- 配置拦截器的对象 -->
<bean class="com.xxx.interceptor.MyInterceptor2"/>
</mvc:interceptor>
</mvc:interceptors>
<!--开启springMVC框架对注解的支持-->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
</beans>
2.编写拦截器类:
public class MyInterceptor1 implements HandlerInterceptor {
//拦截器的预处理方法,即执行controller中的方法之前先执行的方法
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截器作用了。。。前111");
// request.getRequestDispatcher("WEB-INF/pages/error.jsp").forward(request,response);
return true;
}
//拦截器的后处理方法,即执行controller中的方法之后,但是先于jsp页面执行前执行的方法
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("拦截器作用了。。。后111");
}
//拦截器最后的处理的方法,即执行了jsp页面之后,最后执行的方法,一般可以用于释放资源
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("拦截其作用了。。。最后111");
}
}
3.配置控制器类:
/**
* @Date: 2019/12
* 拦截器只可以拦截controller注解过的方法,不可以拦截jsp等内容。而过滤器可以拦截所有的内容。
* springMVC中的拦截器使用其实就是AOP思想的体现!
* SpringMvc拦截器使用方法:
* 1。编写拦截器类
* 2.配置拦截器
**/
@Controller
@RequestMapping(path = "/user")
public class InterceptorController {
@RequestMapping(path = "/testInterceptor")
public String testResponse(){
System.out.println("testInterceptor。。。");
return "success";
}
}
稍微总结一些:
- SpringMVC中最重要的是前端控制器DispatcherServlet的使用,返回的视图解析器InternalResourceViewResolver,这两个必须注意配置好!
关于@RequestBody与@ResponseBody
@RequestBody的作用其实是将前端传过来json格式的数据在后端转为java对象。
@ResponseBody的作用其实是将后端中的java对象传到前端页面展示时转为json格式的数据。
一般这两个注解都是在ajax中使用,当然当传输的参数是json格式时,也是能用到这两个参数的。