MVC全名是Model View Controller,是模型(model)-视图(view)-控制器 (controller)的缩写. 它是一种软件设计典范,是一种软件架构设计分层模式。 Model(模型)是应用程序中用于 处理应用程序数据逻辑 的部分。(完成业务逻辑:有javaBean构成,service+dao+entity) View(视图)是应用程序中处理 数据显示 的部分。( 做界面的展示 jsp,html……) Controller(控制器)是应用程序中处理 界面交互(前端与后端) 的部分(接收请求—>调用模型—>根据结果派发页面) 最典型的MVC就是JSP + servlet + javabean的模式。
springMVC=struts2+spring,springMVC就相当于是Struts2加上sring的整合. Spring 配备构建Web 应用的全功能MVC框架。Spring可以很便捷地和其他MVC框架集成,如Struts,Spring 的MVC框架用控制反转把业务对象和控制逻辑清晰地隔离。它也允许以声明的方式把请求参数和业务对象绑定。 spring mvc是一个基于mvc的web框架。spring mvc是spring框架的一个模块 ,springmvc和spring无需通过中间整合层进行整合。
在Spring整体框架的核心概念中,容器是核心思想,就是用来管理Bean的整个生命周期的, 而在一个项目中,容器不一定只有一个,Spring中可以包括多个容器,而且容器有上下层关系 ,目前最常见的一种场景就是在一个项目中引入Spring和SpringMVC这两个框架,它其实就是两个容器,Spring是父容器,SpringMVC是其子容器,并且在Spring父容器中注册的Bean对于SpringMVC容器中是可见的,而在SpringMVC容器中注册的Bean对于Spring父容器 中是不可见的,也就是子容器可以看见父容器中的注册的Bean,反之就不行。
springmvc工作流程
1、用户发起请求到前端控制器(DispatcherServlet) 2、前端控制器请求处理器映射器(HandlerMappering)去查找处理器(Handle):通过xml配置或者注解进行查找 3、找到以后处理器映射器(HandlerMappering)像前端控制器返回执行链(HandlerExecutionChain) 4、前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)去执行处理器(Handler) 5、处理器适配器去执行Handler 6、Handler执行完给处理器适配器返回ModelAndView 7、处理器适配器向前端控制器返回ModelAndView 8、前端控制器请求视图解析器(ViewResolver)去进行视图解析 9、视图解析器像前端控制器返回View 10、前端控制器对视图进行渲染 11、前端控制器向用户响应结果
spring工作原理图
组件名称 | 作用 |
---|---|
前端控制器DispatcherServlet | 接收请求,响应结果,相当于转发器,中央处理器。有了dispatcherServlet减少了其它组件之间的耦合度。用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性。 |
处理器映射器HandlerMapping | 根据请求的url查找HandlerHandlerMapping负责根据用户请求找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。 |
处理器适配器HandlerAdapter | 按照特定规则(HandlerAdapter要求的规则)去执行Handler通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。 |
处理器Handler | 编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行HandlerHandler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理。由于Handler涉及到具体的用户业务请求,所以一般情况需要工程师根据业务需求开发Handler。 |
视图解析器View resolver | 进行视图解析,根据逻辑视图名解析成真正的视图(view)View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。 springmvc框架提供了很多的View视图类型,包括:jstlView、freemarkerView、pdfView等。 |
视图View | View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf…) |
使用SpringMVC在原有Spring jar包基础上又导入哪些Spring 的如下jar包 1、spring-webmvc.jar 这个 jar 文件包含 Spring MVC 框架相关的所有类。 2、spring-web.jar 这个jar 文件包含Web 应用开发时,用到Spring 框架时所需的核心类,包括自动载入Web Application Context 特性的类、Struts 与JSF 集成类、文件上传的支持类、Filter 类和大量工具辅助类。平时用到RequestMapping就是来自这个包的. 3、spring-context.jar 这个 jar 文件为 Spring 核心提供了大量扩展。可以找到使用 Spring ApplicationContext 特 性时所需的全部类, JDNI 所需的全部类, UI 方面的用来与模板 (Templating) 引擎如 Velocity、 FreeMarker、JasperReports 集成的类,以及校验 Validation 方面的相关类。
1、导入jar包 2、配置web.xml,注册SpringMVC前端控制器(中央调度器) 3、编写SpringMVC后端控制器 4、编写springmvc配置文件,注册后端控制器(注意id写法格式) 5、编写跳转资源页面
1.、在web.xml配置资源放行的servlet映射文件
<!-- 静态资源无法访问的第一种解决方案 -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
2、在springmvc中添加默认的处理器
<!-- 静态资源无法访问的第二种解决方案 -->
<mvc:default-servlet-handler />
3、在springmvc中对相关的静态资源一一放行
<!-- 静态资源无法访问的第三种解决方案 -->
<mvc:resources location="/images/" mapping="/images/**"></mvc:resources>
“ / ”:拦截全部请求,包括静态资源,如果配置成“/”,需要设置静态资源放行。如果需要实现RESTFUL风格,必须使用该拦截路径。
“ /* ”:拦截所有请求,错误的设置方法,它会把控制器返回的视图jsp页面也拦截,程序会循环执行。 “.do”:只会拦截以.do结尾的请求,不会拦截到静态资源。
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"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.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">
<!-- 注册后端控制器 -->
<bean id="/my.do" class="com.bjsxt.handlers.MyController"></bean>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>springmvc-01-primary</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 注册springmvc前端控制器(中央调度器) -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定springmvc配置文件的路径以及名称 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
public class MyController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv = new ModelAndView();
System.out.println("进入到后端控制器方法!");
mv.addObject("msg", "Hello SpringMVC!");
mv.setViewName("/jsp/welcome.jsp");
return mv;
}
}
< context:component-scan/> 扫描指定的包中的类上的注解,常用的注解有:
注解名称 | 作用 |
---|---|
@Controller | 注解一个类表示控制器,Spring MVC会自动扫描标注了这个注解的类 |
@Service | 声明Service组件 ,业务层实现类使用 |
@Repository | 声明Dao组件,dao层实现类使用 |
@Component | 泛指组件, 当不好归类时. |
@RequestMapping("/{page}") | 请求路径映射,可以标注类,也可以是方法,可以指定请求类型,默认不指定为全部接收。method属性:指定请求方式时get还是post |
@PathVariable | 路径绑定变量,用于绑定restful路径上的变量。 |
@RequestParam | 对参数进行矫正, 让注解外的形参可以接收注解内的参数. 三个属性: value指定接收的参数名,defaultValue设置默认值,required是否必须接收该参数,默认为true |
@Resource | 用于注入, 默认按名称装配,@Resource(name=“beanName”) |
@Autowired | 用于注入,(srping提供的) 默认按类型装配 ; 可以注入service层和dao层的接口类 |
@ResponseBody | 此方法将返回的数据转换成json格式并返回到响应体中。用于ajax请求,返回json数据。一般用于方法上面 |
@RequestBody | 将响应头中json格式对象转换成实体,一般用于方法体中形参类型的前面 |
@RestController | 这个是Controller和ResponseBody的组合注解,表示@Controller标识的类里面的所有返回参数都放在response body里面。相当于在该Controller类下的每个方法都加了/@ResponseBody,返回json格式数据 |
@Scope(“prototype”) | 设定bean的作用域 |
@CookieValue | 放在方法参数前,用来获取request header cookie中的参数值。 |
使用注解时需要在springmvc配置文件中添加如下代码
<!-- 注册组件扫描器 -->
<context:component-scan base-package="使用注解的类的包名"></context:component-scan>
<!-- 注册注解驱动 -->
<mvc:annotation-driven></mvc:annotation-driven>
spring.mvc
<?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"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.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.bjsxt.handlers"></context:component-scan>
<!-- 注册注解驱动 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 静态资源无法访问的第二种解决方案 -->
<mvc:default-servlet-handler />
<!-- 静态资源无法访问的第三种解决方案 -->
<!-- <mvc:resources location="/images/" mapping="/images/**"></mvc:resources> -->
</beans>
wem.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>springmvc-01-primary</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 静态资源无法访问的第一种解决方案 -->
<!-- <servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping> -->
<!-- 注册springmvc前端控制器(中央调度器) -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定springmvc配置文件的路径以及名称 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
@org.springframework.stereotype.Controller //作用:将当前类交给spring容器管理
@RequestMapping("/springmvc") //该注解起到限定范围的作用
public class MyController{
@RequestMapping("/handleRequest")
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv = new ModelAndView();
System.out.println("进入到后端控制器方法!");
mv.addObject("msg", "Hello world!");
mv.setViewName("/jsp/welcome.jsp");
return mv;
}
}
主机名:tomcat端口号/虚拟项目名/类体上的注解/方法上的注解 例如: http://localhost:8080/springmvc-03-annotation-primary/springmvc/handleRequest
视图解析器,可以令我们直接返回jsp的名称,而不需要加前缀和后缀 prefix : 前缀 suffix : 后缀
例:
<!-- 注册视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
若控制器方法中:retrun "welcome"; 则返回的是/jsp/welcome.jsp
默认情况下,.setting及其他以.开头的文件都是默认隐藏的。为了显示这两个文件,我们可以在Package Explorer右侧的view Menu(倒三角图标)的下拉视图菜单中选择Filters,在Java Element Filters对话框中,取消选中.* resources过滤器 ,修改名称为context-root的作用域的value即可,修改的名称即为新的虚拟项目名
<!-- 配置编码方式过滤器,注意一点:要配置在所有过滤器的前面(display-name之前) -->
<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>
@Controller
@RequestMapping("/springmvc")
public class MyController{
@RequestMapping("/hello")
public ModelAndView hello(String username,int age){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("username", username);//接收用户名数据
modelAndView.addObject("age", age);//接收年龄数据
modelAndView.setViewName("welcome");//设置响应地址
return modelAndView;
}
}
注:@RequestParam(“username”)String name,int age),可以令我们即使在形参没有对上的情况下也能获取用户名数据
通过将要接收的普通类型数据和引用类型数据封装成一个实体类,通过实体类的对象获取
实体类
//get. set 方法省略
public class star {
private String username;
private int age;
//与属性/对象属性
private Partener partener;
}
public class Partener {
private String name;
}
jsp页面
<form action="springmvc/hello" method="POST">
用户名:<input type="text" name="username"></br>
年 龄: <input type="text" name="age"></br>
伴侣名称: <input type="text" name="partener.name"></br>
<input type="submit" value="提交">
</form>
控制层代码
/**
*控制层
*/
@Controller //该注解表将当前类交给spring容器管理
@RequestMapping("/springmvc") //该注解起到限定范围的作用
public class MyController{
@RequestMapping("/hello")
public ModelAndView hello(star star){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("username", star.getUsername());
modelAndView.addObject("age", star.getAge());
modelAndView.addObject("partenername", star.getPartener().getName());
modelAndView.setViewName("welcome");
return modelAndView;
}
}
回显界面
<!-- 此处接受的是MyController中addObject的属性 -->
用户名:${username}<br/>
年 龄:${age}<br/>
伴侣名称:${partenername}
前端form表单
<body>
<form action="springmvc/hello" method="POST">
<input type="checkbox" name="interest" value="a1">a1</br>
<input type="checkbox" name="interest" value="a2">a2</br>
<input type="checkbox" name="interest" value="a3">a3</br>
<input type="submit" value="提交">
</form>
</body>
//后端控制器
@Controller //该注解表将当前类交给spring容器管理
@Scope("prototype")
@RequestMapping("/springmvc") //该注解起到限定范围的作用
public class MyController{
//数组接收参数的两种方法
//方法一,使用数据接收
@RequestMapping("/hello")
public void hello(String[] interest){
for (String string : interest) {
System.out.println(string);
}
}
//方法二,使用集合接收,需要用RequestParam矫正集合类型
@RequestMapping("/hello")
public void hello1(@RequestParam List<String> interest){
for (String string : interest) {
System.out.println(string);
}
}
}
restful风格传参 : 将参数作为路径变量的一部分的传参
@Controller //该注解表将当前类交给spring容器管理
@Scope("prototype")
@RequestMapping("/springmvc") //该注解起到限定范围的作用
public class MyController{
//restful风格传参
@RequestMapping("/{name}/{age}/hello")
public void hello1(@PathVariable String name,@PathVariable int age){
System.out.println(name+age);
}
}
访问路径:http://localhost:8080/springmvc-09-recieveParameter-restful/springmvc/chy/23/hello
控制台打印:chy23
需要导jquery文件, jackson的jar包
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
$(function(){
$("#myButton").click(function(){
var data1={username:"woailuo",age:23};
$.ajax({
url:"${pageContext.request.contextPath}/springmvc/hello",
type: "POST",
contentType:"application/json",
data:JSON.stringify(data1),
})
})
})
</script>
<title>Insert title here</title>
</head>
<body>
<button id="myButton">点击即可发送json类型数据</button>
</body>
</html>
@Controller //该注解表将当前类交给spring容器管理
@Scope("prototype")
@RequestMapping("/springmvc") //该注解起到限定范围的作用
public class MyController{
//接收json字符串并封装成对象
@RequestMapping("/hello")
public void hello1(@RequestBody Star star){//@RequestBody 将请求体里面的数据拿出来,封装成star类型字符串
System.out.println(star);
}
}
注意绝对路径的书写方式:"${pageContext.request.contextPath}/springmvc/hello"
@Controller //该注解表将当前类交给spring容器管理
@Scope("prototype")
@RequestMapping("/springmvc") //该注解起到限定范围的作用
public class MyController{
//接收json字符串并封装成对象
@RequestMapping("/hello")
public void hello1(@RequestHeader String host,@RequestHeader String cookie){
System.out.println(host + " ----------"+cookie);
}
}
1 HttpServletRequest 2 HttpServletResponse 3 HttpSession 4 用于承载数据的Model、Map、ModelMap 5 请求中所携带的请求参数
1 ModelAndView ----既要传递数据,又要跳转资源 2 String ----跳转导某个资源 3 void 4 Object(涉及注解@ResponseBody ,注册mvc注解驱动,导入jackson2.5包
见上面代码
string资源跳转,如果需要携带参数,需要在后面添加承载数据的对象,model,Map,ModelMap
@Controller //该注解表将当前类交给spring容器管理
@Scope("prototype")
@RequestMapping("/springmvc") //该注解起到限定范围的作用
public class MyController{
@RequestMapping("/hello")
public String hello1(String username,int age,Model model,Map<String, Object> map,ModelMap modelMap){
System.out.println(username + " ----------"+age);
model.addAttribute("username", username);
map.put("age", age);
modelMap.addAttribute("gender", "female");
return "welcome";
}
}
@Controller //该注解表将当前类交给spring容器管理
@Scope("prototype")
@RequestMapping("/springmvc") //该注解起到限定范围的作用
public class MyController{
//接收json字符串并封装成对象
@RequestMapping(value="/hello",produces="text/html;charset=utf-8")
public void hello1(HttpServletResponse response) throws IOException{
String json="{\"name\":\"weilong\",\"flavor\":\"hot\"}";
response.getWriter().print(json);
}
}
<script type="text/javascript">
$(function(){
$("#myButton").click(function(){
$.ajax({
url:"${pageContext.request.contextPath}/springmvc/hello",
type: "POST",
success: function(data){
/* 将接受到的字符串转换成json对象 */
var data1 = eval("("+data+")");
alert(data1.flavor);
}
})
})
})
</script>
在springmvc中使用ajax时,需要 加注解------@ResponseBody ,将当前方法的返回值放到响应体中,并且转换成json格式 导jar包----- jackson json格式转换的支持jar包
@Controller //该注解表将当前类交给spring容器管理
@Scope("prototype")
@RequestMapping("/springmvc") //该注解起到限定范围的作用
public class MyController{
@RequestMapping(value="/hello",produces="text/html;charset=utf-8")
@ResponseBody //将当前方法的返回值放到响应体中,并且转换成json格式
public Object hello1(){
return "aaa";
}
}
请求转发/重定向到一个jsp页面
1、默认情况,采取请求转发,配置视图解析器后,采取逻辑视图名
//modelAndView.setViewName("welcome");
//页面回显,根据属性名直接获取
用户名:${username}<br/>
年 龄:${age}
2、采取重定向方式,配置视图解析器后,仍采取物理视图名
//modelAndView.setViewName("redirect:/jsp/welcome.jsp");
//页面回显,需要加param
用户名:${param.username}<br/>
年 龄:${param.age}
重定向到另一个方法(同一个controller)
@Controller //该注解表将当前类交给spring容器管理
@RequestMapping("/springmvc") //该注解起到限定范围的作用
public class MyController{
@RequestMapping("/hello")
public ModelAndView hello(String username,int age){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("username", username);
modelAndView.addObject("age", age);
//modelAndView.setViewName("welcome");//默认情况为请求转发
//重定向
modelAndView.setViewName("redirect:some");//不要以斜杠开头
return modelAndView;
}
//请求转发到另一个jsp页面
@RequestMapping("/some")
public ModelAndView some(String username,int age){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("welcome");//默认情况为请求转发
return modelAndView;
}
}
重定向到另一个方法(不同controller)
//如果从一个controller跳转到另一个则需要加斜杠,并且能够携带参数
@RequestMapping("/addReply")
public String findAllReply(Reply reply,Model model) {
System.out.println(reply);
this.replyService.Inser(reply);
return "redirect:/topic/showOne?topic_id="+reply.getTopic_id();
}
总结(千万注意): 1、在同一个controller进行跳转到另一个方法,不需要加斜杠,在不同controller则需要加斜杠,斜杠代表根目录 2、在不使用 redirect 或者 forward 的情况,默认使用视图解析器,将逻辑视图转为物理视图,并使用请求转发的方式,响应给客户端浏览器。 3、在使用 redirect 或者 forward 的情况,不会使用视图解析器,而是将 String 类型方法中返回的字符串当做SpringMVC 处理器的请求路径,交给其他 SpringMVC 处理器处理该请求。
1 .导入相关jar包(fileupload的jar,io的jar),或者添加相关坐标 2. 修改form表单的属性,使其能够上传图片enctype=“multipart/form-data”,而且表图片的类型也为file而不是image 3. 注册文件上传解析器,解决照片名称为中文的乱码问题,设置默认编码 4. 对新创建的文件目录进行静态资源放行
<!-- 文件上传组件 -->
<!-- 有parent项目 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>${commons-net.version}</version>
</dependency>
<!-- 文件上传组件 -->
<!-- 无parent项目 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.3</version>
</dependency>
单个文件上传
@RequestMapping("/addGoods")
public String addGoods(MultipartFile file,Goods goods,Model model,HttpSession session) {
//通过session获取绝对路径,方法内部加上/WEB-INF/images,表示在项目的images目录下,需要创建该文件夹并进行静态资源放行
String path=session.getServletContext().getRealPath("/WEB-INF/images");
String fileName = file.getOriginalFilename();//这个就是文件的路径
File file2 = new File(path, fileName );
try {
file.transferTo(file2);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//将文件的路径放到类属性中,修改此处
goods.setPicture(fileName);
}
form表单
<form action="springmvc/addGoods" method="POST" enctype="multipart/form-data">
<input type="file" name="file"></br>
<input type="submit" value="上传">
</form>
注意: 文件上传的name的名字要与上传Controller中方法的参数(MultipartFile file )一致,不然会接收不到请求
springmvc配置文件
<!-- 注册文件上传解析器,并解决中文乱码问题 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
</bean>
<!-- 放行images文件夹的静态资源 -->
<mvc:resources location="/WEB-INF/images/" mapping="/images/**"/>
文件回显,通过所设置的图片路径访问即可
<img alt="" src="${good.picture }">
多文件上传
@Controller //该注解表将当前类交给spring容器管理
@Scope("prototype")
@RequestMapping("/springmvc") //该注解起到限定范围的作用
public class MyController{
@RequestMapping("/fileUpload")
public String fileUpload(@RequestParam MultipartFile[] imgs,HttpSession session){//@RequestParam修正参数,否则包初始化异常
//通过session获取绝对路径 D:\Program Files\apache-tomcat-7.0.69\webapps\springmvc-19-fileUpload-multiple/
String path=session.getServletContext().getRealPath("/");
for (MultipartFile img : imgs) {
String fileName = img.getOriginalFilename();
File file = new File(path, fileName );
try {
img.transferTo(file);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return "welcome";
}
<form action="springmvc/fileUpload" method="POST" enctype="multipart/form-data">
<input type="file" name="imgs"></br>
<input type="file" name="imgs"></br>
<input type="file" name="imgs"></br>
<input type="file" name="imgs"></br>
<input type="submit" value="上传">
</form>
配置文件中无需添加其他东西,直接编写控制层代码即可
@Controller //该注解表将当前类交给spring容器管理
@Scope("prototype")
@RequestMapping("/springmvc") //该注解起到限定范围的作用
public class MyController{
@RequestMapping("/fileDowload")
public ResponseEntity<byte[]> dowload() throws IOException{
//指定下载文件
File file = new File("f:/ybl.png");
InputStream is = new FileInputStream(file);
//创建字节数组,并且设置数组大小为预估的文件字节数
byte[] body = new byte[is.available()];
//将输入流中字符存储到缓存数组中
is.read(body);
//获取下载显示的文件名,并解决中文乱码
String name = file.getName();
String downLoadFileName = new String(name.getBytes("UTF-8"),"ISO-8859-1");
//设置Http响应头信息,并且通知浏览器以附件的形式进行下载
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Content-Disposition", "attachment;filename="+downLoadFileName);
//设置Http响应状态信息
HttpStatus status = HttpStatus.OK;
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(body, httpHeaders, status);
return responseEntity;
}
}
拦截器是屏蔽掉相关的页面或者方法 , 过滤器是将相关页面方法保留下来 , 二者作用相反 步骤 1 定义一个类实现HandlerInterceptor接口 2 在配置文件中注册拦截器 注:多重拦截器拦截循序与他在配置文件中注册的顺序相同
public class FirstInterceptor implements HandlerInterceptor {
//该方法执行时机,所有工作处理完成之后执行
@Override
public void afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("FirstInterceptor.afterCompletion()");
}
//该方法执行时机,处理器方法之后执行
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, ModelAndView arg3) throws Exception {
System.out.println("FirstInterceptor.postHandle()");
}
//该方法执行时机,处理器方法之前执行
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2) throws Exception {
System.out.println("FirstInterceptor.preHandle(拦截器方法的执行)");
return true;//false拦截之后,不再继续执行
}
}
<!-- 注册拦截器(拦截所有) -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclu-mapping path="/springmvc/hello"/>
<bean id="" class="com.bjsxt.handlers.FirstInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>