文章目录
前言
作为Web前端框架的SpringMVC,是对Servlet的再封装,可以自动接收请求参数,提供了文件的上传与下载功能。作为SSM框架之一,SpringMVC封装了控制层,使前端与后端交互变得更为方便,提高了程序员的开发效率。
一、SpringMVC 概述
1.1 框架与设计模式
设计模式是对反复出现的问题的解决方案的描述,是一种思想
框架是已经用代码实现的,可以执行也可以复用
框架总是针对某一特定领域的,而设计模式则可以适用于各个应用
1.2 MVC设计模式
MVC设计模式是一种使用 Model View Controller( 模型-视图-控制器)设计创建 Web 应用程序的模式
1.Model(模型):
是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
2.View(视图):
是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。
3.Controller(控制器):
是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
使用的MVC设计模式的目的:它将这些对象、显示、控制分离以提高软件的的灵活性和复用性
1.3 SpringMVC框架概述
springMVC 是 spring 框架的一个模块,springMVC 和 spring 无需通过中间整合层进行整合。
springmvc 是一个基于 mvc 的 web 框架,方便前后端数据的传输
Spring MVC 拥有控制器,接收外部请求,解析参数传给服务层
1.4 SpringMVC运行流程
1. 用 户 向 服 务 器 发 送 请 求 , 请 求 被 Spring 前 端 控 制 Servelt DispatcherServlet 捕获;
2. 前端控制器DispatcherServlet接收请求后,调用处理器映射 HandlerMapping。 处理器映射器 HandlerMapping 根据请求的 url 找到处理该请求的处理器Handler(即Controller) , 将处理器Handler返回给前端控制器DispatcherServlet。
3. DispatcherServlet 根 据 获 得 的 Handler , 选 择 一 个 合 适 的 HandlerAdapter。
在填充 Handler 的入参过程中,根据你的配置,Spring 将 帮你做一些额外的工作:数据类型转换,数据封装
4.调用处理器相应的功能处理方法
5. Handler(自己的控制器)执行完成后,直接相应一个json格式的数据给用户(现在开发常用的做法)
二、搭建SpringMVC
2.1 导包
<!--springmvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
2.2 DispatcherServlet
<!--配置spring核心请求分发器-->
<servlet>
<servlet-name>application</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name> <!-- 找 web-inf/classes/配置文件 -->
<param-value>classpath:spring.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup> <!--启动服务器就创建-->
</servlet>
<!-- 请求映射 -->
<servlet-mapping>
<servlet-name>application</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
过滤静态资源文件:当 DispatcherServlet 的 url 配置为/时 需要添加此配置,能够访问静态资源
例如.jpg,.js,.css 带静态资源文件
<mvc:default-servlet-handler/>
2.3 开启 SpringMVC 注解
<!--开启springmvc注解-->
<mvc:annotation-driven></mvc:annotation-driven>
2.4中文乱码处理
我们发现在提交请求的时候,如果输入的是中文,处理器方法获取到之后是乱码。解决的方法就是添加一个过滤器,为 request 对象设置编码集,SpringMVC 中已经为我们提供了这 个过滤器,只需要在 web.xml 中配置好即可。
<!--添加 一个过滤器,为 request 解决中文乱码问题-->
<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>
2.5 控制器搭建
@Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象
@RequestMapping 注解是一个用来处理请求地址映射的注解,可用于类或方法上。
Spring 配置中指定了自动扫描的 basepackage 后(一般扫描整个项目所在的包),Spring 会扫描这些包以及子包中的使用了@Controller 标识的类,然后将类加入到 Spring IOC 容器中
**加粗样式** <!--开启注解扫描-->
<context:component-scan base-package="com.ffyc.ssm"></context:component-scan>
三、接收请求
3.1@RequestMapping
@RequestMapping 它的作用就是与请求相匹配,如果匹配上了,所修饰的方法才会被执行
@RequestMapping(“/login”)请求的路径为 “http://localhost:8080/login” , 请求方式没有限制,即可以是GET也可以是 POST,还能是其它的几个。
如果想限制请求方式可以使用@GetMapping, @PostMapping,指定请求方式为get或者post
3.2获取请求数据
1.如果请求参数的名称和处理器方法中的参数名称相同,可以写成
@RequestMapping(value ="/login")
public String login(String account, String password){
//执行操作
}
框架会自动把请求参数名为account和password的值封装到方法参数account和password中去
2.参数列表中还可以直接内置 HttpServletRequest,HttpSession,HttpServletResponse 等对象
@RequestMapping(value ="/login")
public CommonMessage login(HttpServletRequest request, HttpSession httpSession) {
//使用request和httpSession中的方法获得请求的参数
}
3.接下来介绍一种最重要也是最常用的一种做法, 如果请求参数比较多,通常是将这些参数放到一个实体中,然后只需要在处理器 方法上定义这个实体作为参数。
@RequestMapping(value ="/login")
public CommonMessage test(Manage manage) {
}
HandlerAdapter 会将这个对象的实例创建出来,然后从请求参数中取出这些参数然后放到实体对象中(数据封装)
注意:请求参数的名称要和实体类的属性名相同,且实体类中最好要添加属性的get和set方法
四、响应
4.1@responseBody
该注解的作用是将 controller 的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到 response 对象的 body 区,通常用来向异步请求返回 JSON 数据。
注意:在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中, 他的效果等同于通过 response 对象输出指定格式的数据。
4.2使用步骤
添加 jacksonjar包
<!-- json-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.1</version>
</dependency>
使用案例
@RestController
/*包含了@ResponseBody标签
* @ResponseBody:在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中, 他的效果等同于通过 response 对象输出指定格式的数据*/
@RequestMapping(value = "/login")
public class ControllerLogin {
@Autowired
LoginService loginService;
@RequestMapping(value ="/login")
public CommonMessage test(Manage manage, HttpSession httpSession) {
try {
Manage manageTemp = loginService.login(manage);
if (manageTemp != null) {
httpSession.setAttribute("manage", manageTemp);
return new CommonMessage<Manage>(200, "登录成功", manageTemp);
} else {
return new CommonMessage(300, "登录失败",(Manage)null);
}
} catch (Exception e) {
return new CommonMessage(301, "登录失败", (Manage)null);
}
}
}
五、文件上传
1.导入上传下载所需 jar 文件
<!--导入上传下载所需 jar 文件-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
2.文件解析器
在springMvc的配置文件中配置文件解析器
<!--文件解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<property name="maxUploadSize" value="10485760"></property>
</bean>
3.使用案例
@RequestMapping(value ="/fileUpload")
public CommonMessage fileUpLoad(@RequestParam("fileName") CommonsMultipartFile file,HttpSession httpSession){
Manage manage = (Manage) httpSession.getAttribute("manage");
File imagefile=new File("D:\\iconimages\\"+ manage.getAccount());
if(!imagefile.exists()){
imagefile.mkdir();
}
String newFileName=new StringUtil().newFileName(file.getOriginalFilename());
File imageFile2=new File(imageSfile,newFileName);
manage.setOldFileName(file.getOriginalFilename());
manage.setNewFileName(newFileName);
try {
loginService.updateUser(manage);
file.transferTo(imageFile2);
return new CommonMessage<Manage>(200, "上传成功", manage);
} catch (IOException e) {
e.printStackTrace();
return new CommonMessage<Manage>(300, "上传失败", (Manage) null);
}
}
后端提供了一个文件上传接口,当前端调用后端的接口上传文件时,先判断磁盘中中有没有该账号的文件夹,如果没有就创建一个,然后利用先前写好的StringUtil类,得到新文件名(当前时间加文件后缀名),把新文件名存入到数据库中,最后利file.transferTo(imageFile2) 把用户上传的文件存到文件夹中
六、 拦截器
5.1 实现HandlerInterceptor接口
SpringMVC 定义了拦截器接口 HandlerInterceptor 该接口中定义了三个方法,这三个方法的调用时在 SpringMVC 框架内部完成的, 调用这个三个方法的时候,其参数的值也是从框架内部传递进来的。
public class LoginInterceptor implements HandlerInterceptor {
/* 当请求到达控制器之前被执行 true--继续向下执行,到达下一个拦截器,或控制器 false--不会继续向下执行*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession httpSession=request.getSession();
Manage manage = (Manage) httpSession.getAttribute("manage");
if(manage !=null){
return true;
}else{
response.getWriter().println(203);
return false;
}
}
/*控制器方法执行之后执行*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
/*整个请求结束后执行*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
5.2注册拦截器
<!--注册拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--哪些请求进入拦截器-->
<mvc:mapping path="/**"/>
<!--哪些请求不进入拦截器-->
<mvc:exclude-mapping path="/login/login"/>
<mvc:exclude-mapping path="/**.html"/>
<mvc:exclude-mapping path="/css/**"/>
<mvc:exclude-mapping path="/images/**"/>
<mvc:exclude-mapping path="/js/**"/>
<bean id="loginId" class="com.ffyc.ssm.util.LoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
总结
本文主要介绍了SpringMVC的概述、运行流程、搭建以及接受请求和返回数据等内容。SpringMVC可以简化控制层的开发,使我们拜托手动获取请求参数的烦恼,极大的提高我们的开发效率。到此关于SSM三大框架的基本内容已经介绍完毕,在以后的学习中会把三个框架结合起来使用,使程序员可以专心于自己的业务代码。建议读者在练习中体会框架带来的便捷之处,同时深入学习框架的实现原理,加深理解。