MVC
什么是MVC?
MVC是一种软件设计规范:模型(Model)、视图(View)、控制器(Controller)的简写。
是用将业务逻辑、数据、显示分离的方法来组织代码。
MVC不是一种设计模式,而是一种架构模式。当然不同的MVC存在差异。
MVC主要作用是降低视图与业务逻辑间的双向耦合。
**Model(模型):**数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或 JavaBean组件(包含数据和行为),不过现在一般都分离开来:Value Object(数据 Dao)和服务层(行为 Service)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。
View(视图):负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。
Controller(控制器):接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示。也就是说控制器做了个调度员的工作。
最典型的MVC就是JSP + servlet + javabean的模式。
时代发展
1、Model1时代
- 在web早期的开发中,通常采用的都是Model1。
- Model1中,主要分两层,视图层和模型层。
优点:架构简单,比较适合小型项目开发。
缺点:JSP职责不单一,职责过重,不便于维护。
2、Model2时代
Model2把一个项目分成三部分。包括视图、控制、模型。
- 用户发请求
- Servlet接收请求数据,并调用对应的业务逻辑方法
- 业务处理完毕,返回更新后的数据给servlet
- servlet转向到JSP,由JSP来渲染页面
- 响应给前端更新后的页面
职责分析:
Controller(控制器):
- 取得表单数据
- 调用业务逻辑
- 转向指定的页面
Model(模型):
- 业务逻辑
- 保存数据的状态
View(视图):
- 显示页面
总结:Model2这样不仅提高了代码的复用率与项目的扩展性,且大大降低了项目的维护成本。Model1模式的实现比较简单,适用于快速开发小规模项目,Model1中JSP页面兼View和Controller两种角色,将控制逻辑和表现逻辑混杂在一起,从而导致代码的重用性比较低,增加了应用的扩展性和维护的难度。Model2消除了Model1的缺点。
SpringMVC
一:概述
1、什么是SpringMVC?
- SpringMVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。
- 是在Spring3.0后发布的。
- springmvc内部是使用mvc架构模式。
- SpringMVC 是一个容器, 管理对象的,使用IoC核心技术。 springmvc管理界面层中的控制器对象。
- SpringMVC底层也是Servlet。 以Servlet为核心, 接收请求,处理请求。 显示处理结果给用户。
特点:
- 约定优于配置
Spring的web框架围绕DispatcherServlet(调度Servlet)设计。
DispatcherServlet的作用是将请求分发到不同的处理器。从Spring 2.5开始,使用Java5或者以上版本的用户可以采用基于注解形式进行开发,十分简洁。
2、SpringMVC优点
-
基于 MVC 架构
- 功能分工明确。解耦合,
-
轻量级,简单易学
- SpringMVC 也是轻量级的, jar 很小。不依赖的特定的接口和类。
-
作为 Spring 框架一部分,能够使用 Spring 的 IOC 和 Aop。方便整合 Strtus,MyBatis,Hiberate,JPA 等其他框架。
-
功能强大:RESTful、数据验证、格式化、本地化、主题等
3、中心控制器
-
Spring的web框架围绕DispatcherServlet设计。DispatcherServlet的作用是将请求分发到不同的处理器。从Spring 2.5开始,使用Java5或者以上版本的用户可以采用基于注解的controller声明方式。
-
SpringMVC框架像许多其他MVC框架一样,以请求为驱动,围绕一个中心Servlet分派请求及提供其他功能,DispatcherServlet实际上是一个Servlet(它继承自HttpServlet基类)。
SpringMVC的原理如下图所示:
当发起请求时被前置的控制器拦截到请求,根据请求参数生成代理请求,找到请求对应的实际控制器,控制器处理请求,创建数据模型,访问数据库,将模型响应给中心控制器,控制器使用模型与视图渲染视图结果,将结果返回给中心控制器,再将结果返回给请求者。
4、SpringMVC执行流程
实线表示SpringMVC框架提供的技术,不需要开发者实现,虚线表示需要开发者实现。
简要分析执行流程:
- DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispathcerServlet接收请求并拦截请求。
- 我们假设请求的url为:http://localhost:8080/SpringMVC/hello
- 如上url拆分成三部分:
- http://localhost:8080 服务器域名
- SpringMVC 部署在服务器上的web站点
- hello 表示控制器
- 通过分析,如上url表示为:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器。
- HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。
- HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello。
- HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。
- HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。
- Handler让具体的Controller执行。
5、SpringMVC配置流程
SpringMVC用到的依赖:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
配置:
-
配置DispatcherServlet。(在web.xml中配置)如:
... <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- DispatcherServlet要绑定spring-mvc的配置文件(也就是Spring的配置文件) --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:路径名(如:spring-mvc.xml)</param-value> <!-- 在tomcat启动后,创建Servlet对象 load-on-startup:表示tomcat启动后创建对象的顺序,它的值是大于0的整数,数值越小,tomcat创建对象的时间越早。 --> <load-on-startup>1</load-on-startup> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 注意: 在SpringMVC中,/ /*的区别: /:只匹配所有的请求,不会去匹配jsp页面 /*:匹配所有的请求,包括jsp页面 --> ...
-
配置spring-mvc.xml文件
... <!-- 开发中可省(开启注解驱动后会自动配置) --> <!-- 处理器映射器 --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> <!-- 处理器适配器 --> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> <!-- 开发中不可省(因为有数据需动态修改)--> <!-- 视图解析器:有第三方库:模板引擎 Thymeleaf Freemarker ... 我们把所有的视图都存放在/WEB-INF/目录下,这样可以保证视图安全,因为这个目录下的文件,客户端不能直接访问。 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver"> <!-- 前缀 --> <property name="prefix" value="/WEB-INF/jsp/"/> <!-- 后缀 --> <property name="suffix" value=".jsp"/> </bean> <!-- 请求映射,配合处理器映射器使用 --> <!-- BeanNameUrlHandlerMapping:Bean --> <bean id="/hello" class="HelloController"/> ...
-
写Controller控制器处理请求
//可以用注解简化开发,这里是不用注解的例子。 public class HelloController implements Controller { //会根据ModelAndView处理业务逻辑并实现视图跳转 public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { ModelAndView mv = new ModelAndView(); //业务代码 //视图跳转 return mv; } }
二:基于注解开发
1、基本配置(流程)
-
引入相关的依赖:主要有Spring框架核心库、Spring MVC、servlet、JSTL等。
-
配置web.xml。
- 注意web.xml版本问题,要用最新版
- 配置DispathcerServlet
-
添加Spring MVC配置文件:
-
让IOC的注解生效
-
静态资源过滤:HTML、JS、CSS、图片、视频 ……
-
MVC的注解驱动
-
配置视图解析器
<!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 --> <context:component-scan base-package="需扫描的包的路径"/> <!-- 让Spring MVC不处理静态资源 --> <mvc:default-servlet-handler /> <!-- 支持MVC注解驱动: 在spring中一般采用@RequestMapping注解来完成映射关系 要想使用@RequestMapping注解生效 必须向上下文注册DefaultAnnotationHandlerMapping 和一个AnnotationMethodHandlerAdapter实例 这两个实例分别在类级别和方法级别处理。 而annotation-driven配置帮助我们自动完成上述两个实例的注入。 --> <mvc:annotaion-driven /> <!-- 第二种处理静态资源的方式: mvc:resources 加入后框架会创建 ResourceHttpRequestHandler这个处理器对象。 让这个对象处理静态资源的访问,不依赖tomcat服务器。 mapping:访问静态资源的url地址,使用通配符 ** location:静态资源在你的项目中的目录位置。 <mvc:resources mapping="/images/**" location="/images/"/> -->
-
-
处理请求:编写Controller或Servlet
-
Servlet方式:@WebServlet。举例:
@WebServlet(name = "helloServlet", value = "/hello-servlet") public class HelloServlet extends HttpServlet { private String message; public void init() { message = "Hello World!"; } public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("text/html"); // Hello PrintWriter out = response.getWriter(); out.println("<html><body>"); out.println("<h1>" + message + "</h1>"); out.println("</body></html>"); } public void destroy() { } }
-
2、Controller编写
2.1 常见注解
@RequestMapping
@Target({ElementType.TYPE, ElementType.METHOD})//说明此注解可以在类上也可以在方法上,两种情况作用域不一样。
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
-
@RequestMapping 注解用于映射url到控制器类或一个特定的处理程序方法。可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
@RequestMapping(...) /* 参数(可选): 1、value:String型,作为请求路径名。 2、method:约束请求的类型。默认是GET类型。有给定的属性可选 RequestMethod.GET等。 public enum RequestMethod { GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE; private RequestMethod() { } } 3、produces:可以设置文本类型。 */
-
示例:
/** value值为字符串类型,表路径,开头可以加/,也可不加,都是拼接在当前工程根路径下。 */ @Controller @RequestMapping("system") public class SystemController { @RequestMapping(value = "/index", method = RequestMethod.GET) public String index() { return "system/index"; } }
-
所有的地址栏请求默认都会是HTTP GET类型的。
-
方法级别的注解变体有如下几个:组合注解
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
如 @GetMapping 扮演的是 @RequestMapping(method = RequestMethod.GET)的一个快捷方式。
@ResponseBody
-
@ResponseBody 注解能让方法或类,不走视图解析器,直接返回数据至前端。
-
@RestController:标在类上,让类里所有的请求都不走视图解析器,直接返回至前端页面。
-
标注以上注解的方法的返回值会以json格式返回到页面,所以要注意引入json依赖。
2.2 结果跳转方式
2.2.1 ModelAndView
设置ModelAndView对象,根据view的名称,和视图解析器跳到指定的页面。
页面:{视图解析器前缀} + viewName + {视图解析器后缀}
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀:视图文件的路径-->
<property name="prefix" value="/WEB-INF/view/"/>
<!--后缀:视图文件的扩展名-->
<property name="suffix" value=".jsp" />
</bean>
对应的Controller类
public class ControllerTest1 implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//返回一个模型视图对象
ModelAndView mv = new ModelAndView();
mv.addObject("msg", "ControllerTest1")
mv.setViewName("test")
return mv;
}
}
2.2.2 ServletAPI
通过设置ServletAPI,不需要视图解析器。
- 通过HttpServletResponse进行输出
- 通过HttpServletResponse实现重定向
- 通过HttpServletResponse实现转发
@Controller
public class ResultGo {
@RequestMapping("/result/t1")
public void test1(HttpServletRequest req, HttpServletResponse rsp) throws Excepiton {
rsp.getWriter().println("Hello, Spring BY servlet API");
}
@RequestMapping("/result/t2")
public void test2(HttpServletRequest req, HttpServletResponse rsp) throws Excepiton {
rsp.sendRedirect("/index.jsp");
}
@RequestMapping("/result/t3")
public void test3(HttpServletRequest req, HttpServletResponse rsp) throws Excepiton {
//转发
req.setAttribute("msg", "/result/t3");
req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req, rsp);
}
}
2.2.3 SpringMVC
通过SpringMVC来实现转发和重定向。(无需视图解析器)
- 返回值类型为String。返回转发或重定向的路径
@Controller
public class ResultSpringMVC {
@RequestMapping("/rsm/t1")
public String test1() {
//转发
return "/index.jsp";//有视图解析器时更简便,直接 return "index"
}
@RequestMapping("/rsm/t2")
public String test1() {
//转发二
return "forward:/index.jsp";
}
@RequestMapping("/rsm/t3")
public String test1() {
//重定向(注意路径问题)
return "redirect:/index.jsp";
}
}
2.3 数据处理
2.3.1 处理提交的数据
-
提交的域名称和处理方法的参数名一致
例:
-
提交数据:http://localhost:8080/hello?name=kuangshen
-
处理方法:
@RequestMapping("/hello") public String hello(String name) { System.out.println(name); return "hello"; }
- 后台输出:kuangshen
-
-
提交的域名称和处理方法的参数名不一样
-
提交数据:http://localhost:8080/hello?username=kuangshen
-
处理方法:
//@RequestParam("username") username是提交的域的名称,还可以加参数 required 是一个boolean,默认是true表示请求中必须包含此参数 @RequestMapping("/hello") public String hello(@RequestParam("username") String name) { System.out.println(name); return "hello"; }
-
后台输出:kuangshen
-
-
提交的是一个对象
-
要求提交的表单域和对象的属性名一致,参数使用对象即可。
-
实体类:
public class User { private int id; private String name; private int age; ... }
-
提交数据:http://localhost:8080/user?name=kuangshen&id=1&age=15
-
处理方法:
@RequestMapping("/user") public String user(User user) { System.out.println(user); return "hello"; }
-
后台输出:User{id=1, name=‘kuangshen’, age=15}
-
说明:
- 如果使用对象的话,前端传递的参数名和对象名必须一致,否则就是null。框架会创建形参的Java对象,给属性赋值。请求中的参数是name,框架会调用setName()
-
2.3.2 数据显示到前端
第一种:通过ModelAndView
public class ControllerTest1 implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//返回一个模型视图对象
ModelAndView mv = new ModelAndView();
mv.addObject("msg", "ControllerTest1")
mv.setViewName("test")
return mv;
}
}
第二种:通过ModelMap
@RequestMapping("/hello")
public String hello(@RequestParam("username") String name, ModelMap model) {
//封装要显示到视图中的数据
//相当于req.setAttribute("name", name);
model.addAttribute("name", name);
System.out.println(name);
return "test";
}
第三种:通过Model
@RequestMapping("/ct2/hello")
public String hello(@RequestParam("username") String name, Model model) {
//封装要显示到视图中的数据
//相当于req.setAttribute("name", name);
model.addAttribute("msg", name);
System.out.println(name);
return "test";
}
对比
- Model 只有寥寥几个方法,只适合用于储存数据,简化了新手对于Model对象的操作和理解。
- ModelMap 继承了LinkedMap,除了实现了自身的一些方法,同样的继承了LinkedMap的方法和特性。
- ModelAndView 可用在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。
2.3.3 乱码解决
以前乱码问题通过过滤器解决,而SpringMVC给我们提供了一个过滤器,可以在web.xml中配置。
<filter>
<filter-name>encoding</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>encoding</filter-name>
<url-pattern>/</url-pattern><!-- 注意/和/*的区别 -->
</filter-mapping>
有些极端情况下,filter对get方法不支持。
其他解决方法:
-
修改tomcat配置文件:设置编码。
<Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1" connectionTimeout="2000" redirectPort="8443" />
-
自定义过滤器
2.3.4 Controller返回JSON数据
-
Jackson 应该是目前比较好的json解析工具了
-
当然工具不止这一个,比如还有阿里巴巴的 fastjson等等。
-
使用 Jackson,需要导入jar包
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency>
乱码问题
1、@RequestMapping配置
@RequestMapping(..., produces="application/json;charset=utf-8")
2、SpringMVC配置处理json乱码问题:
<mvc:annotation-driven>
<mvc:message-converters register-default="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
3、异常处理
SpringMVC 框架处理异常的常用方式:使用==@ExceptionHandler== 注解处理异常。
@ExceptionHandler 注解
- 使用注解@ExceptionHandler 可以将一个方法指定为异常处理方法。
- 该注解只有一个可选属性 value,为一个 Class数组,用于指定该注解的方法所要处理的异常类,即所要匹配的异常。
- 对于异常处理注解的用法,也可以直接将异常处理方法注解于 Controller 之中。
不过,一般不这样使用。而是将异常处理方法专门定义在一个类中,作为 全局的异常处理类。 需要使用注解@ControllerAdvice,字面理解就是“控制器增强”,是给 控制器对象增强功能的。使用@ControllerAdvice 修饰的类中可以使用 @ExceptionHandler。 当使用@RequestMapping 注解修饰的方法抛出异常时,会执行 @ControllerAdvice 修饰的类中的异常处理方法。 @ControllerAdvice 是使用@Component 注解修饰的,可以 扫描到@ControllerAdvice 所在的类路径(包名), 创建对象
三:Controller
Controller(控制器)
- 控制器负责提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现。
- 控制器负责解析用户的请求并将其转换为一个模型。
- 在Spring MVC中一个控制器类可以包含多个方法。
- 在Spring MVC中,对于Controller的配置方式有很多种。
方式一:实现Controller接口
Controller是一个接口,在 org.springframework.web.servlet.mvc包下,接口中只有一个方法。
//实现该接口的类获得控制器功能
public interface Controller {
//处理请求且返回一个模型与视图对象
ModelAndView handleRequest(HttpServletRequest var1, HttpServletResponse var2) throws Exception;
}
(代码实现跟上面配置里的一样,这里不写了)
说明:
- 实现接口Controller定义控制器是比较老的办法。
- 缺点是:一个控制器吧中只有一个方法,如果要多个方法则需要定义多个Controller;定义的方式比较麻烦。
方式二:使用注解
@Controller 用于声明Spring类的实例是一个控制器。配合Spring的扫描机制使用。
被这个注解的类,中的所有方法的返回值,会被视图解析器解析。
@Controller
public TestController {
@RequestMapping("/t1")
String test1(Model model) {
……
return 'test'
}
@RequestMapping("/t2)
String test1(Model model) {
……
return 'test'
}
}
/**
发现:
这种情况下,发送上述两个请求发现
两个请求都可以指向同一个视图,但是页面结果的内容是一样的,从这里可以看出视图是被复用的,而控制器与视图之间是弱耦合关系。
*/
四:拦截器
1、概述
SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。
**过滤器和拦截器的区别:**拦截器是AOP思想的具体应用。
过滤器:
- servlet规范中的一部分,任何java web工程都可以使用
- 在 url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截
拦截器:
- 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
- 拦截器只会拦截访问的控制器方法,如果访问的是 jsp/html/css/image/js 是不会进行拦截的
2、自定义拦截器
想要自定义拦截器,必须实现 HandlerInterceptor 接口。
public class MyInterceptor implements HandlerInterceptor {
//在请求处理的方法之前执行
//如果返回true执行下一个拦截器
//如果返回false就不执行下一个拦截器
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return false;
}
//在请求处理方法执行之后执行
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
//在dispatcherServlet处理后执行,做清理工作
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
springMVC配置:
<!--拦截器配置-->
<mvc:interceptors>
<mvc:interceptor>
<!--包括这个请求下面的所有的请求 / -->
<mvc:mapping path="/**"/>
<!-- 用于指定排除的 url-->
<mvc:exclude-mapping path=""/>
<bean class="自定义拦截器的全类名"/>
</mvc:interceptor>
</mvc:interceptors>
五:文件上传
1、准备工作
文件上传是项目开发中最常见的功能之一,springMVC可以很好地支持文件上传,但是SpringMVC上下文中默认没有装配MultipartResolver,因此默认情况下其不能处理文件上传工作。如果想使用Spring的文件上传功能,则需要在上下文中配置MultipartResolver。
前端表单要求:为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器:
对表单中的 enctype属性做个详细的说明:
- application/x-www=form-urlencoded:默认方式,只处理表单域中的value属性值,采用这种编码方式的表单会将表单域中的值处理成URL编码方式。
- multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数中,不会对字符编码。
- text/plain:除了把空格转换为“+”号外,其他字符都不做编码处理,这种方式适用直接通过表单发送邮件。
<form action="" enctype="multipart/form-data" method="post">
<input type="file" name="file"/>
<Input type="submit"/>
</form>
一旦设置了enctype为multipart/form-data,浏览器即会采用二进制流的方式来处理表单数据,而对于文件上传的处理则涉及在服务器端解析原始的HTTP响应。在2003年,Apache Software Foundation发布了开源的Commons FileUpload组件,其很快成为Servlet/JSP程序员上传文件的最佳选择。
- Servlet3.0规范已经提供方法来处理文件上传,但这种上传需要在Servlet中完成。
- 而SpringMVC则提供了更简单的封装。
- SpringMVC为文件上传提供了直接的支持,这种支持是即插即用的MultipartResolver实现的。
- SpringMVC适用Apache Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver。因此,SpringMVC的文件上传还需要依赖Apache Commons FileUpload的组件(要引入依赖包)。
2、文件上传
1、导入文件上传的jar包,commos-fileupload,Maven会自动帮我们导入它的依赖包:commons-io包。
<!-- 文件上传 -->
<dependecy>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependecy>
2、配置bean:multipartResolver
注意:这个bean的id必须为:multipartResolver,否则上传文件会报400的错误!
<!--文件上传配置-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--请求的编码格式,必须和jsp的pageEncoding属性一致,以使正确读取表单的内容,默认为ISO-8859-1 -->
<property name="defaultEncoding" value="utf-8"/>
<!--上传文件大小上限,单位为字节(10485760=10M) -->
<property name="maxUploadSize" value="10485760"/>
<property name="maxInMemorySize" value="40960"/>
</bean>
CommonsMultipartFile 类的常用方法:
- String getOriginalFilename():获取上传文件的原名
- InputStream getInputStream():获取文件流
- void transferTo(File dest):将上传文件保存到一个目录文件中
扩展
Restful风格
概念
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
功能
资源操作
在SpringMVC中应用
在SpringMVC中可以使用 @PathVariable 注解,让方法参数的值对应绑定到一个URL模板变量上。
//映射访问路径
@RequestMapping("/commit/{p1}/(p2)")
public String index(@PathVariable int p1, @PathVariable int p2, Model model) {
……
}