SpringMVC
文章目录
1、SpringMVC的概述
- 是一种基于Java实现的MVC设计模型的请求驱动类型的轻量级WEB框架
- Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块
- 使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架
2、SpringMVC的入门程序
步骤(七步)
-
第一步:创建WEB工程,引入开发的jar包
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.0.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-client</artifactId> <version>1.19.4</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-core</artifactId> <version>1.19.4</version> </dependency> </dependencies>
-
第二步:配置前端控制器(配置DispatcherServlet)
-
在web.xml配置文件中配置前端控制器 DispatcherServlet
<!--前端控制器 org.springframework.web.servlet.DispatcherServlet--> <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:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
-
-
第三步:编写springmvc.xml的配置文件
-
在 resources 目录下创建 springmvc.xml 的配置文件
<?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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 开启注解扫描 --> <context:component-scan base-package="com.itfzk.springmvc01"></context:component-scan> <!--视图解析器对象--> <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 前缀(路径) --> <property name="prefix" value="/WEB-INF/springmvc/"></property> <!-- 后缀 --> <property name="suffix" value=".jsp"></property> </bean> <!--开启 SpringMVC 注解的支持--> <mvc:annotation-driven /> </beans>
-
-
第四步:编写index.jsp
<body> <!-- springmvc01 是 springmvcJava01.java 中 @RequestMapping(path = "/springmvc01") 注解中的 springmvc01 --> <a href="springmvc01">点击入门</a> </body>
-
第五步:编写 Controller 控制器类 (springmvcJava01.java)
@Controller public class springmvcJava01 { @RequestMapping(path = "/springmvc01") //建立请求 URL 和处理请求方法之间的对应关系 public String springmvc01(){ // 返回的是以 springmvc01.xml 中的 InternalResourceViewResolver 前缀 + 返回值 + 后缀 组成的路径文件 return "success"; } }
-
第六步:在 WEB-INF 目录下创建 springmvc文件夹,编写 success.jsp 的成功页面
<body> <h3>入门成功</h3> </body>
-
第七步:启动Tomcat服务器,进行测试
入门案例的执行过程分析
- 入门案例的执行流程
- 1、当启动Tomcat服务器的时候,因为配置了load-on-startup标签,所以会创建DispatcherServlet对象,就会加载springmvc.xml配置文件
- 2、开启了注解扫描,那么 springmvcJava01 对象就会被创建
- 3、从index.jsp发送请求,请求会先到达DispatcherServlet核心控制器,根据配置@RequestMapping注解找到执行的具体方法
- 4、根据执行方法的返回值,再根据配置的视图解析器,去指定的目录下查找指定名称的JSP文件
- 5、Tomcat服务器渲染页面,做出响应
- 入门案例中的组件分析
- 前端控制器(DispatcherServlet)
- 处理器映射器(HandlerMapping)
- 处理器(Handler)
- 处理器适配器(HandlAdapter)
- 视图解析器(View Resolver)
- 视图(View)
3、@RequestMapping注解
-
作用 :
- 建立请求URL和处理方法之间的对应关系
-
可用地方 :
- 方法和类
- 作用在类上:第一级的访问目录
- 作用在方法上:第二级的访问目录
- 细节 :
- 路径可以不编写 / 表示应用的根目录开始
- ${ pageContext.request.contextPath }也可以省略不写,但是路径上不能写 /
- 属性 :
- path :用于指定请求的URL
- value :它和path属性的作用是一样的
- method :用于指定请求的方式(GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE)
- params :用于指定限制请求参数的条件。它支持简单的表达式
- headers :用于指定限制请求消息头的条件
jsp文件
<body> <!-- springmvc01 是 springmvcJava01.java 中 @RequestMapping(path = "/springmvc01") 注解中的 springmvc01 --> <a href="fzk01/springmvc01">点击入门</a> </body>
Controller类
@Controller @RequestMapping(path = "/fzk01") //可不写这个注解,如果写上,建立请求 URL 前面要加上 user(<a href="fzk01/springmvc01">) public class springmvcJava01 { @RequestMapping(path = "/springmvc01") //建立请求 URL 和处理请求方法之间的对应关系 public String springmvc01(){ // 返回的是以 springmvc01.xml 中的 InternalResourceViewResolver 前缀 + 返回值 + 后缀 组成的路径文件 return "springmvcJsp01"; } }
- 方法和类
4、请求参数的绑定
请求参数的绑定支持的数据类型
基本数据类型和字符串类型
-
提交表单的name和参数的名称是相同的
-
区分大小写
jsp文件
<body> <!-- 请求参数绑定 : 基本数据类型和字符串类型 --> <a href="fzk02/springmvc02?username=fzk&password=123">提交</a> </body>
Controller类
@Controller @RequestMapping(path = "/fzk02") public class springmvcJava02 { /** * 请求参数绑定 : 基本数据类型和字符串类型 */ @RequestMapping(path = "/springmvc02") public String springmvc02(String username, String password){ System.out.println("执行。。。"); System.out.println("用户名:" + username); System.out.println("密码:" + password); return "springmvcJsp01"; } }
实体类型(JavaBean)
-
提交表单的name和JavaBean中的属性名称需要一致
-
如果一个JavaBean类中包含其他的引用类型,那么表单的name属性需要编写成:对象.属性
Javabean类(User.java、Account.java)
//User.java public class User implements Serializable { private String username; private String password; private Account account; public Account getAccount() { return account; } public void setAccount(Account account) { this.account = account; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "username='" + username + '\'' + ", password='" + password + '\'' + ", account=" + account + '}'; } } //Account.java public class Account implements Serializable { private String accountName; private String accountPrice; public String getAccountName() { return accountName; } public void setAccountName(String accountName) { this.accountName = accountName; } public String getAccountPrice() { return accountPrice; } public void setAccountPrice(String accountPrice) { this.accountPrice = accountPrice; } @Override public String toString() { return "Account{" + "accountName='" + accountName + '\'' + ", accountPrice='" + accountPrice + '\'' + '}'; } }
jsp文件
<body> <!-- 请求参数绑定 :实体类型( JavaBean ) --> <form action="fzk02/springmvcJavaBeanPlus" method="post"> 用户名:<input type="text" name="username" /> <br/> 密码:<input type="text" name="password" /> <br/> 账户名称:<input type="text" name="account.accountName"/><br/> 账户价格:<input type="text" name="account.accountPrice"/><br/> <input type="submit" value="提交"> </form> </body>
Controller类
@Controller @RequestMapping(path = "/fzk02") public class springmvcJava02 { /** * 请求参数绑定 :实体类型( JavaBean ) */ @RequestMapping(path = "/springmvcJavaBeanPlus") public String springmvcJavaBeanPlus(User user){ System.out.println(user); return "springmvcJsp01"; } }
集合数据类型(List、map集合等)
-
JSP页面编写方式:list[0].属性
-
Javabean类(User.java、Account.java)
//User.java public class User implements Serializable { private String username; private String password; private List<Account> listAccount; private Map<String, Account> mapAccount; public List<Account> getListAccount() { return listAccount; } public void setListAccount(List<Account> listAccount) { this.listAccount = listAccount; } public Map<String, Account> getMapAccount() { return mapAccount; } public void setMapAccount(Map<String, Account> mapAccount) { this.mapAccount = mapAccount; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "username='" + username + '\'' + ", password='" + password + '\'' + ", listAccount=" + listAccount + ", mapAccount=" + mapAccount + '}'; } } //Account.java public class Account implements Serializable { private String accountName; private String accountPrice; public String getAccountName() { return accountName; } public void setAccountName(String accountName) { this.accountName = accountName; } public String getAccountPrice() { return accountPrice; } public void setAccountPrice(String accountPrice) { this.accountPrice = accountPrice; } @Override public String toString() { return "Account{" + "accountName='" + accountName + '\'' + ", accountPrice='" + accountPrice + '\'' + '}'; } }
jsp文件
<body> <!-- 请求参数绑定 :集合数据类型(List、map集合等) --> <h3>请求参数绑定 :集合数据类型(List、map集合等)</h3> <form action="fzk02/springmvcJavaBeanListAndMap" method="post"> 用户名:<input type="text" name="username" /> <br/> 密码:<input type="text" name="password" /> <br/> 账户名称:<input type="text" name="listAccount[0].accountName"/><br/> 账户价格:<input type="text" name="listAccount[0].accountPrice"/><br/> 账户名称:<input type="text" name="listAccount[1].accountName"/><br/> 账户价格:<input type="text" name="listAccount[1].accountPrice"/><br/> 账户名称:<input type="text" name="mapAccount['one'].accountName"/><br/> 账户价格:<input type="text" name="mapAccount['one'].accountPrice"/><br/> 账户名称:<input type="text" name="mapAccount['two'].accountName"/><br/> 账户价格:<input type="text" name="mapAccount['two'].accountPrice"/><br/> <input type="submit" value="提交"> </form> </body>
Controller类
@Controller @RequestMapping(path = "/fzk02") public class springmvcJava02 { /** * 请求参数绑定 :集合数据类型(List、map集合等) */ @RequestMapping(path = "/springmvcJavaBeanListAndMap") public String springmvcJavaBeanListAndMap(User user){ System.out.println(user); return "springmvcJsp01"; } }
请求参数中文乱码的解决
-
在web.xml中配置Spring提供的过滤器类 CharacterEncodingFilter
<!--配置解决中文乱码的过滤器--> <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>
自定义类型转换器
-
表单提交的任何数据类型全部都是字符串类型,但是后台定义Integer类型,数据也可以封装上,说明Spring框架内部会默认进行数据类型转换
-
如果想自定义数据类型转换,可以实现Converter的接口
-
自定义类型转换(String --> Date)
-
第一步:编写自定义数据类型转换类,实现Converter的接口
public class StringToDateConverter implements Converter<String, Date> { @Override public Date convert(String source) { if(source == null){ throw new RuntimeException("请输入时间"); } SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); try { return simpleDateFormat.parse(source); } catch (ParseException e) { throw new RuntimeException("数据类型转换失败"); } } }
-
注册自定义类型转换器,在springmvc.xml配置文件中编写配置
<!-- 配置自定义类型转换器 --> <bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="com.itfzk.utils.StringToDateConverter"></bean> </set> </property> </bean> <!--开启 SpringMVC 注解的支持--> <mvc:annotation-driven conversion-service="conversionServiceFactoryBean" />
-
在控制器中使用原生的ServletAPI对象
-
只需要在控制器的方法参数定义HttpServletRequest和HttpServletResponse对象
jsp文件
<body> <!-- 获取 Servlet原生的 API --> <a href="fzk02/springmvcGetServletAPI">提交</a> </body>
Controller类
@Controller @RequestMapping(path = "/fzk02") public class springmvcJava02 { /** * 获取 Servlet原生的 API */ @RequestMapping(path = "/springmvcGetServletAPI") public String springmvcServletAPI(HttpServletRequest request, HttpServletResponse response){ System.out.println("request:" + request); HttpSession session = request.getSession(); System.out.println("session:" + session); ServletContext servletContext = session.getServletContext(); System.out.println("servletContext:" + servletContext); System.out.println("response:" + response); return "springmvcJsp01"; } }
5、常用的注解
@RequestParam
-
作用:
- 把请求中指定名称的参数给控制器中的形参赋值。
-
属性:
- value:请求参数中的名称
- required:请求参数中是否必须提供此参数。默认值: true。 表示必须提供,如果不提供将报错。
-
代码
jsp
<!-- RequestParam注解--> <a href="fzk03/springmvcRequestParam?name=fzk">提交</a>
Controller类
@Controller @RequestMapping(path = "/fzk03") public class springmvcJava03 { @RequestMapping(path = "/springmvcRequestParam") public String springmvcRequestParam(@RequestParam(value = "name") String username){ System.out.println(username); return "springmvcJsp01"; } }
@RequestBody
-
作用
- 用于获取请求体内容。直接使用得到是key=value&key=value… .结构的数据。(username=fzk&password=123)
get请求方式不适用。
- 用于获取请求体内容。直接使用得到是key=value&key=value… .结构的数据。(username=fzk&password=123)
-
属性:
- required:请求参数中是否必须提供此参数。默认值: true。 表示必须提供,如果不提供将报错。
-
代码
jsp
<!-- RequestBody注解 --> <form action="fzk03/springmvcRequestBody" method="post"> 用户名:<input type="text" name="username" /> <br/> 密码:<input type="text" name="password" /> <br/> <input type="submit" value="提交"> </form>
Controller类
@Controller @RequestMapping(path = "/fzk03") public class springmvcJava03 { @RequestMapping(path = "/springmvcRequestBody") public String springmvcRequestBody(@RequestBody String body){ System.out.println(body); return "springmvcJsp01"; } }
@PathVariable
-
作用
- 用于绑定 url 中的占位符。例如:请求 url 中 /springmvcPathVariable/{id}, 这个 {id} 就是 url 占位符
-
属性:
- value:用于指定url中占位符名称
- required:请求参数中是否必须提供此占位符。默认值: true。
-
代码
jsp
<!-- PathVariable注解--> <a href="fzk03/springmvcPathVariable/10">提交</a>
Controller类
@Controller @RequestMapping(path = "/fzk03") public class springmvcJava03 { @RequestMapping(path = "/springmvcPathVariable/{id}") public String springmvcPathVariable(@PathVariable(value = "id") String id){ System.out.println(id); return "springmvcJsp01"; } }
@RequestHeader
-
作用
- 获取指定请求头的值
-
属性:
- value: 请求头的名称
- required:请求参数中是否必须提供此消息头。默认值: true。
-
代码
jsp
<!-- RequestHeader注解--> <a href="fzk03/springmvcRequestHeader">提交</a>
Controller类
@Controller @RequestMapping(path = "/fzk03") public class springmvcJava03 { @RequestMapping(path = "/springmvcRequestHeader") public String springmvcRequestHeader(@RequestHeader(value = "Accept") String str){ System.out.println(str); return "springmvcJsp01"; } }
@CookieValue
-
作用
- 用于获取指定cookie的名称的值
-
属性:
- value: cookie的名称
- required:是否必须有此cookie。默认值: true。
-
代码
jsp
<!-- CookieValue注解--> <a href="fzk03/springmvcCookieValue">提交</a>
Controller类
@Controller @RequestMapping(path = "/fzk03") public class springmvcJava03 { @RequestMapping(path = "/springmvcCookieValue") public String springmvcCookieValue(@CookieValue(value = "JSESSIONID") String cookieValue){ System.out.println(cookieValue); return "springmvcJsp01"; } }
@ModelAttribute
- 作用
- 用于修饰方法和参数。
- 出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。它可以修饰没有返回值的方法,也可以修饰有具体返回的方法。
- 出现在参数上,获取指定的数据给参数赋值。
- 属性
- value: 用于获取数据的key。key 可以是POJO的属性名称,也可以是map结构的key
- 应用场景
- 当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。
方法一:有返回值
jsp
<!-- ModelAttribute注解 -->
<form action="fzk03/springmvcModelAttribute" method="post">
用户名:<input type="text" name="username" /> <br/>
密码:<input type="text" name="password" /> <br/>
<input type="submit" value="提交">
</form>
Controller类
@Controller
@RequestMapping(path = "/fzk03")
public class springmvcJava03 {
@RequestMapping(path = "/springmvcModelAttribute")
public String springmvcModelAttribute(User user){
System.out.println(user);
return "springmvcJsp01";
}
//模拟数据库
@ModelAttribute
public User testModelAttribute(User user){
return user;
}
}
方法二:没有返回值
jsp
<!-- ModelAttribute注解 -->
<form action="fzk03/springmvcModelAttribute" method="post">
用户名:<input type="text" name="username" /> <br/>
密码:<input type="text" name="password" /> <br/>
<input type="submit" value="提交">
</form>
Controller类
@Controller
@RequestMapping(path = "/fzk03")
public class springmvcJava03 {
@RequestMapping(path = "/springmvcModelAttribute")
public String springmvcModelAttribute(@ModelAttribute(value = "abc") User user){
System.out.println(user);
return "springmvcJsp01";
}
//模拟数据库
@ModelAttribute
public void testModelAttribute(User user, Map<String, User> map){
map.put("abc", user);
}
}
@SessionAttributes
-
作用
- 用于多次执行控制器方法间的参数共享
-
属性
- value : 用于指定存入的属性名称
- type: 用于指定存入的数据类型
-
代码
jsp
<!-- SessionAttributes注解--> <!-- 存入数据 --> <a href="fzk03/springmvcSessionAttributes">set</a> <!-- 获取数据 --> <a href="fzk03/springmvcGetSessionAttributes">get</a>
Controller类
@Controller @RequestMapping(path = "/fzk03") @SessionAttributes(value = "fzk", types = String.class) //存入的属性名称,数据类型 public class springmvcJava03 { //存入数据 @RequestMapping(path = "/springmvcSessionAttributes") public String springmvcSessionAttributes(Model model){ model.addAttribute("fzk", "123"); return "springmvcJsp01"; } //获取数据 @RequestMapping(path = "/springmvcGetSessionAttributes") public String springmvcGetSessionAttributes(Model model){ Object fzk = model.getAttribute("fzk"); System.out.println(fzk); return "springmvcJsp01"; } }
6、响应数据和结果视图
返回值分类
返回字符串
-
Controller方法返回字符串可以指定逻辑视图的名称,根据视图解析器为物理视图的地址
@Controller @RequestMapping(path = "/fzk04") public class springmvcJava04 { /** * 返回值:字符串(String) */ @RequestMapping(path = "/springmvcString") public String springmvcString(Model model){ //模拟数据库查询 User对象 User user = new User(); user.setUsername("fzk"); user.setPassword("123"); //model 对象 model.addAttribute("user", user); return "springmvcJsp01"; } }
springmvcJsp01.jsp
${user.username} ${user.password}
返回值是void (转发,重定向,直接相应)
-
可以使用请求转发或者重定向跳转到指定的页面
Controller类
@Controller @RequestMapping(path = "/fzk04") public class springmvcJava04 { /** * 返回值:void */ @RequestMapping(path = "/springmvcVoid") public void springmvcVoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { User user = new User(); user.setUsername("fzk"); user.setPassword("123"); //1、转发 request.getRequestDispatcher("/WEB-INF/springmvc/springmvcJsp01.jsp").forward(request, response); //2、重定向 response.sendRedirect(request.getContextPath() + "/fzk03.jsp"); //3、直接响应 response.getWriter().print("fzk"); } }
返回值是ModelAndView对象
-
ModelAndView对象是Spring提供的一个对象,可以用来调整具体的JSP视图
Controller类
@Controller @RequestMapping(path = "/fzk04") public class springmvcJava04 { @RequestMapping(path = "/springmvcModelAndView") public ModelAndView springmvcModelAndView(){ //模拟数据库查询 User对象 User user = new User(); user.setUsername("fzk"); user.setPassword("123"); //创建 ModelAndView对象 ModelAndView mv = new ModelAndView(); //把 User对象存储到 mv 中,也会把 user 对象存入到 request对象 mv.addObject("user", user); //使用视图解析器跳转到该页面 mv.setViewName("springmvcJsp01"); return mv; } }
springmvcJsp01.jsp
${user.username} ${user.password}
SpringMVC框架提供的转发和重定向
forward请求转发
-
使用:“forward:转发的JSP路径”
-
不走视图解析器了,所以需要编写完整的路径
Controller类
@Controller public class springmvcJava04 { @RequestMapping(path = "/test8") public String test11() { //转发 return "forward:WEB-INF/springmvc/success.jsp"; } }
redirect重定向
@Controller
public class springmvcJava04 {
@RequestMapping(path = "/test11")
public String test11() {
//重定向
return "redirect:index.jsp";
}
}
静态资源不过滤
-
DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img、css、js)也会被拦截到
-
设置静态资源不过滤
-
mvc:resources标签配置不过滤
- mapping:以 /css 开头的所有请求路径,如 /css/a 或者 /css/a/b
- location:webapp目录下的包下的所有文件
-
在springmvc.xml配置文件添加如下配置
<!-- 前端控制器,设置静态资源不过滤 --> <mvc:resources mapping="/css/" location="/css/**"></mvc:resources> <mvc:resources mapping="/js/" location="/js/**"></mvc:resources> <mvc:resources mapping="/image/" location="/image/**"></mvc:resources>
-
7、SpringMVC实现文件上传
- JSP文件格式:
- 1、form表单
- enctype:
- 取值必须是:multipart/ form-data(默认值是:application/x-www- form-urlencoded)
- enctype:是表单请求正文的类型
- enctype:
- 2、method 属性取值必须是Post
- 3、提供一个文件选择域<input type=“file” name="…" />
- 1、form表单
普通文件上传
导入文件上传的jar包
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
编写文件上传的JSP页面
<!-- 普通文件上传 -->
<form action="fzk05/springmvcFileUpload" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="fileupload"/><br>
<input type="submit" value="提交"/>
</form>
编写文件上传的Controller控制器
@Controller
@RequestMapping(path = "/fzk05")
public class springmvcJava05 {
/**
* 普通文件上传
*/
@RequestMapping(path = "/springmvcFileUpload")
public String springmvcFileUpload(HttpServletRequest request) throws Exception {
//获取上传的位置
String realPath = request.getSession().getServletContext().getRealPath("/fileupload/");
File file = new File(realPath);
//不存在该文件位置
if(!file.exists()){
file.mkdirs(); //创建该位置
}
//解析 request 对象,获取上传文件项
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
//解析 request
List<FileItem> fileItems = servletFileUpload.parseRequest(request);
//遍历
for(FileItem fileItem : fileItems){
//普通表单项
if (fileItem.isFormField()){
}else { //上传的文件项
//获取表单项的名称
String fileItemName = fileItem.getName();
//把文件名设为唯一值
String uuid = UUID.randomUUID().toString();
fileItemName = uuid + "_" + fileItemName;
//文件的上传
fileItem.write(new File(realPath, fileItemName));
//删除临时文件
fileItem.delete();
}
}
return "success";
}
}
SpringMVC文件上传
- SpringMVC框架提供了MultipartFile对象,该对象表示上传的文件
- 要求:变量名称必须和表单file标签的name属性名称相同
- MultipartFile upload 中的 upload 与 JSP 中的 <input type=“file” name=“upload” /> name属性名称相同
- 要求:变量名称必须和表单file标签的name属性名称相同
编写文件上传的Controller控制器
@Controller
@RequestMapping(path = "/fzk05")
public class springmvcJava05 {
/**
* SpringMVC 文件上传
* 在 springmvc01.xml 中配置文件解析器
* 使用 MultipartFile 对象
* 要保证 MultipartFile upload 中的 upload 与 JSP 中的 <input type="file" name="upload" /> name属性名称相同
*/
@RequestMapping(path = "/springmvcSpringMVCFileUpload")
public String springmvcSpringMVCFileUpload(HttpServletRequest request, MultipartFile upload) throws Exception {
//获取上传的位置
String realPath = request.getSession().getServletContext().getRealPath("/fileupload/");
File file = new File(realPath);
//不存在该文件位置
if(!file.exists()){
file.mkdirs(); //创建该位置
}
//解析 request 对象,获取上传文件项,在 springmvc01.xml 中配置文件解析器
//获取文件的名称
String fileItemName = upload.getOriginalFilename();
//把文件名设为唯一值
String uuid = UUID.randomUUID().toString();
fileItemName = uuid + "_" + fileItemName;
//文件的上传
upload.transferTo(new File(realPath, fileItemName));
return "success";
}
}
配置文件解析器对象
<!-- 配置文件解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"></property> <!-- value = 10M -->
</bean>
SpringMVC跨服务器文件上传
导入开发需要的jar包
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.19.4</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.19.4</version>
</dependency>
编写文件上传的JSP页面
<!-- 跨服务器文件上传 -->
<h3>跨服务器文件上传</h3>
<form action="fzk05/springmvcWebFileUpload" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="upload" /><br>
<input type="submit" value="提交"/>
</form>
编写文件上传的Controller控制器
@Controller
@RequestMapping(path = "/fzk05")
public class springmvcJava05 {
/**
* 跨服务器文件上传
*/
@RequestMapping(path = "/springmvcWebFileUpload")
public String springmvcWebFileUpload(HttpServletRequest request, MultipartFile upload) throws Exception {
//定义上传文件服务器的路径
String path = "http://localhost:9999/springmvcFileupload/fileupload/";
//解析 request 对象,获取上传文件项,在 springmvc01.xml 中配置文件解析器
//获取文件的名称
String fileItemName = upload.getOriginalFilename();
//把文件名设为唯一值
String uuid = UUID.randomUUID().toString();
fileItemName = uuid + "_" + fileItemName;
//创建客户端对象
Client client = Client.create();
//与图片服务器连接
WebResource webResource = client.resource(path + fileItemName);
//文件的上传
webResource.put(upload.getBytes());
return "success";
}
}
配置文件解析器对象
<!-- 配置文件解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"></property> <!-- value = 10M -->
</bean>
8、SpringMVC的异常处理
- Controller调用service,service调用dao,异常都是向上抛出的,最终有DispatcherServlet找异常处理器进
行异常的处理 - 抛出异常及异常处理器
Controller类
@Controller
@RequestMapping(path = "fzk06")
public class springmvcJava06 {
@RequestMapping(path = "springmvcSysException")
public String springmvcSysException() throws Exception {
System.out.println("springmvcSysException");
try {
//模拟异常
int i = 10 / 0;
} catch (Exception e) {
//打印异常消息
e.printStackTrace();
//抛出自定义异常
throw new SysException("查询信息出错");
}
return "success";
}
}
自定义异常类
public class SysException extends Exception {
private String message;
public SysException(String message) {
this.message = message;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
自定义异常处理器
public class SysExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
//获取异常对象
SysException e;
if(ex instanceof SysException){
e = (SysException) ex;
}else{
e = new SysException("系统正在维护");
}
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("error", e.getMessage());
modelAndView.setViewName("error");
return modelAndView;
}
}
配置异常处理器
<!-- 配置异常处理器 -->
<bean id="sysExceptionResolver" class="com.itfzk.exception.SysExceptionResolver"></bean>
9、SpringMVC框架中的拦截器
拦截器的概述
- SpringMVC框架中的拦截器用于对处理器进行预处理和后处理的技术。
- 可以定义拦截器链,连接器链就是将拦截器按着一定的顺序结成一条链,在访问被拦截的方法时,拦截器链中的拦截器会按着定义的顺序执行。
- 拦截器和过滤器的功能比较类似,有区别
- 过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术。
- 拦截器是SpringMVC框架独有的。
- 过滤器配置了/*,可以拦截任何资源。
- 拦截器只会对控制器中的方法进行拦截。
- 拦截器也是AOP思想的一种实现方式
- 想要自定义拦截器,需要实现HandlerInterceptor接口
自定义拦截器步骤
-
第一步:创建类,实现HandlerInterceptor接口,重写需要的方法
public class MyInterceptor01 implements HandlerInterceptor { /** * 预处理方法(运行 Controller 前执行) * @return true:放行, false:不放行 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle111"); //转发到其他页面后之前的页面将不再执行(配合 return false 使用) // request.getRequestDispatcher("/WEB-INF/springmvc/error.jsp").forward(request, response); return true; } /** * 后处理方法(运行 Controller 后执行) */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle111"); } /** * 最后执行方法(JSP 页面显示了再执行) */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion111"); } }
-
第二步:在springmvc.xml中配置拦截器类
<!-- 配置拦截器 --> <mvc:interceptors> <!-- 配置拦截器 --> <mvc:interceptor> <!-- 要拦截的方法 --> <mvc:mapping path="/fzk07/*"/> <!-- 不拦截的方法 <mvc:exclude-mapping path=""/> --> <!-- 拦截后的操作 --> <bean class="com.itfzk.interceptor.MyInterceptor01"></bean> </mvc:interceptor> </mvc:interceptors>
HandlerInterceptor接口中的方法
- preHandle方法是controller方法执行前拦截的方法
- 可以使用request或者response跳转到指定的页面
- return true放行,执行下一个拦截器,如果没有拦截器,执行controller中的方法。
- return false不放行,不会执行controller中的方法。
- postHandle是controller方法执行后执行的方法,在JSP视图执行前。
-
- 可以使用request或者response跳转到指定的页面
- 如果指定了跳转的页面,那么controller方法跳转的页面将不会显示。
- afterCompletion方法是在JSP执行后执行
- request或者response不能再跳转页面了
配置多个拦截器
-
第一步:编写两个拦截器的类
//第一个拦截器 public class MyInterceptor01 implements HandlerInterceptor { /** * 预处理方法(运行 Controller 前执行) * @return true:放行, false:不放行 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle111"); //转发到其他页面后之前的页面将不再执行(配合 return false 使用) // request.getRequestDispatcher("/WEB-INF/springmvc/error.jsp").forward(request, response); return true; } /** * 后处理方法(运行 Controller 后执行) */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle111"); } /** * 最后执行方法(JSP 页面显示了再执行) */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion111"); } } //第二个拦截器 public class MyInterceptor02 implements HandlerInterceptor { /** * 预处理方法(运行 Controller 前执行) */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle222"); return true; } /** * 后处理方法(运行 Controller 后执行) */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle222"); } /** * 最后执行方法(JSP 页面显示了再执行) */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion222"); } }
-
第二步:在springmvc.xml中配置拦截器类
<!-- 配置拦截器 --> <mvc:interceptors> <!-- 配置拦截器 --> <mvc:interceptor> <!-- 要拦截的方法 --> <mvc:mapping path="/fzk07/*"/> <!-- 不拦截的方法 <mvc:exclude-mapping path=""/> --> <!-- 拦截后的操作 --> <bean class="com.itfzk.interceptor.MyInterceptor01"></bean> </mvc:interceptor> <!-- 配置第二个拦截器 --> <mvc:interceptor> <!-- 要拦截的方法 --> <mvc:mapping path="/**"/> <!-- 不拦截的方法 <mvc:exclude-mapping path=""/> --> <!-- 拦截后的操作 --> <bean class="com.itfzk.interceptor.MyInterceptor02"></bean> </mvc:interceptor> </mvc:interceptors>