Spring MVC介绍
Spring MVC是Srping提供给Web应用的框架设计。SpringMVC是一个典型的教科书式的MVC框架,不像Struts等都是变种或者不是完全基于mvc系统的框架。
Spring MVC角色划分清晰,分工明细,并且和Spring框架无缝结合。作为当今业界最主流的Web开发框架,Spring MVC 已经成为当前最热门的开发技能,同时也广泛用于桌面开发领域。
MVC设计不仅限于java Web应用,还包括许多引用,比如前端、PHP、.NET等语言,之所以这样做的原因在于解耦各个模块。
MVC是Model、View和Conntroller的缩写,分别代表Web应用程序中的3种职责。
-
Model (模型):用于存储数据以及处理用户的请求业务逻辑
-
View (试图): 向控制器提交数据,显示模型中的数据
-
Conntroller (控制器):根据视图提出的请求判断将请求提交给哪个模块进行处理,将处理过后的有关结果交给哪个视图更新显示
基于Servlet的MVC模式的具体实现如下:
-
模型:一个或多个JavaBean对象,用于存储数据(实体模型,由JavaBean类创建)和处理业务逻辑(业务模型,由一般的java类创建)
-
视图:向控制器提交数据和为模型显示数据,JSP页面主要使用HTML标记和JavaBean标记来显示数据
-
控制器:一个或多个Servlet对象,根据视图提交的请求进行控制,即将请求转发给业务逻辑部的javaBean,并将处理结果存放到实体模型javaBean中,输出给视图显示。
MVC的特征与优势
-
让我们能非常简单的设计出干净的Web层和薄薄的Web层;
-
天生与Spring框架集成(如IOC容器、AOP等);
-
提供强大的约定大于配置的契约式编程支持;
-
能简单的进行Web层的单元测试;
-
支持灵活的URL到页面控制器的映射;
-
非常容易与其他视图技术集成;
-
非常灵活的数据验证、格式化和数据绑定机制;
-
更加简单的异常处理;
-
对静态资源的支持;
-
支持Restful风格。
SpringMVC 工作流程
-
用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获;
-
DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;
-
DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(…)方法)
-
提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
- HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
- 数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
- 数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
- 数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
-
Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
-
根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;
-
ViewResolver 结合Model和View,来渲染视图
-
将渲染结果返回给客户端。
Spring MVC工作流程说明
- 首先用户发送请求给前端控制器,前端控制器根据请求信息(如URL)来决定选择哪一个页面控制器进行处理并把请求委托给它,即以前的控制器的控制逻辑部分;图中的1、2步骤;
- 页面控制器接收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,这个对象在Spring Web MVC中叫命令对象,并进行验证,然后将命令对象委托给业务对象进行处理;处理完毕后返回一个ModelAndView(模型数据和逻辑视图名);图中的3、4、5步骤;
- 前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的视图进行渲染,并把模型数据传入以便视图渲染;图中的步骤6、7;
- 前端控制器再次收回控制权,将响应返回给用户,图中的步骤8;至此整个结束。
### Spring MVC开发步骤
- 在项目中配置Tomcat
- 添加Spring以及Spring Web MVC的Maven依赖库
- 配置DispatcherServlet
- 配置applicationContext.xml
- 定义控制器Controller
- 定义JSP
Maven依赖库
-
spring-core
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.1.RELEASE</version> </dependency>
-
spring-context
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.1.RELEASE</version> </dependency>
-
spring-context-support
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.3.1.RELEASE</version> </dependency>
-
spring-aspects
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.3.1.RELEASE</version> </dependency>
-
**spring-webmvc **
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.1.RELEASE</version> </dependency>
-
jstl
<dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency>
-
commons-logging
<dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency>
DispatcherServlet
-
DispatcherServlet
-
Spring MVC的前端中央控制器,所有的请求都先集中到这里以便后续处理,比如选择映射的Controller进行请求处理
-
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> <!--为什么叫MvcServlet,因为这里叫 如果这里叫 XX ,那么dispatcherServlet的配置文件就叫 xx-servlet.xml--> <servlet> <servlet-name>MvcServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>xx</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
解决乱码
-
web.xml
<filter> <filter-name>encode</filter-name> <filter-class>org.springfiramework.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>encode</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
在applicationContext.xml中配置ViewResolver
-
配置ViewResolver
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property> <property name="prefix" value="/WEB-INF/jsp/"></property> <property name="suffix" value=".jsp"></property> </bean>
InternalResourceViewResolver: 用于支持Servlet、JSP视图解析;
viewClass: JstlView表示JSP模板页面需要使用JSTL标签库,classpath中必须包含jstl 的相关jar包;
prefix和suffix: 查找视图页面的前缀和后缀(前缀[逻辑视图名]后缀),比如传进来的逻辑视图名为hello,则该该jsp视图页面应该存放在“WEB-INF/jsp/hello.jsp”;
在applicationContext.cml中配置<mvc:annotation-driven>
零配置
-
使用注解
<context:component-scan base-package="com.trkj"/> <!--自动扫描类--> <mvc:annotation-driven/> <!--启用mvc注解-->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 开启自动扫描--> <context:component-scan base-package="com.trkj" /> <!--视图解析--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property> <property name="prefix" value="/WEB-INF/jsp/"></property> <property name="suffix" value=".jsp"></property> <!-- http://localhost:8080/con/index--> <!-- 得到的是index,在他的前面加 /WEB-INF/jsp/ ,后面加 .jsp。这就是拼好了--> <!-- /WEB-INF/jsp/index.jsp--> </bean> <!--开启注解--> <mvc:annotation-driven /> </beans>
@Controller和@RequestMapping
@Controller
将Bean声明为Controller控制器
@RequestMapping
-
定义Controller
可以为不同的方法指定不同的访问路径,从而实现一个Controller处理多个不同的请求
-
method = RequestMethod.GET | POST
定义请求类型
控制器注解实现
访问
http://localhost:8089/yf02702jpa_war_exploded/wa/hello
@Controller
@RequestMapping("/wa")//窄化映射,作为访问路径的前缀,可以省略
public class WorldController{
@RequestMapping("/hello")//访问路径
public ModelAndView hello(){
System.out.println("进入Controller");
ModelAndView mv = new ModelAndView();
mv.addObject("attr1","株洲");
mv.addObject("attr2","许仙");
mv.setViewName("hello");
return mv;
}
}
Controller接收请求参数
- 方法的参数就是请求参数
- 自动类型转换
- 默认情况下,请求参数和方法参数名一致
- @RequestParam用于指定请求参数名称
@Controller
@RequestMapping("/xuxiang")//窄化映射,作为访问路径的前缀,可省略
public class WorldController{
@RequestMapping("/world")
public ModelAndView world(@ReuqestParam("aa") int a, int b){
System.out.println(a + "," + b);
return null;
}
}
访问 http://localhost:8089/SpringMVC3/wa/world?aa=10&b=20
完整文件夹
Spring MVC整合Swagger
Swagger 概述
Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化RESTful风格的Web服务。
在开发的过程中如果没有一个良好的开发规范,可能就会发生修改代码后但是没有能及时更新文档,前端不能及时获取最新的接口。
Swagger 可以很好的解决,它可以动态生成Api接口文档,减低沟通成本,促进项目高效开发。Swagger2它作为一个规范和完整的框架,可以用于生成、调用、描述和可视化RESTful风格的Web服务。其优点如下:
1. 及时性:接口变更后,能够及时准确的通知前后端开发人员。
2. 规范性:并且保证接口的规范性,如接口的地址,请求方式,参数及响应格式和错误信息。
3. 一致性:接口信息一致,不会出现因 开发人员拿到的文档版本不一致而出现分歧。
4. 可测性:直接在接口文档上进行测试,以方便理解业务。
在pox.xml中添加依赖
依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>
<!--因为swagger需要jackson支持,故pom.xml中需要引入jackson关联的包-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
添加swaggerConfig
在目录下创建config目录,目录下添加SwaggerConfig.java
/**
* @author XuLuBao
* @version V1.0
* @Package com.trkj.config
* @date 2021/4/20 9:04
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurationSupport {
@Bean
public Docket createRestApi(){
Docket docket = new Docket(DocumentationType.SWAGGER_2);
//调用apiInfo方法,创建一个ApiInfo实例,
//里面是展示在文档里面信息内容
docket.apiInfo(apiInfo())
.enable(true)
.select()
//控制暴露出去的路径下的实例
//如果某个接口不想暴露,可以使用一下注解
.apis(RequestHandlerSelectors.basePackage("com.trkj.controller"))
.paths(PathSelectors.any())
.build();
return docket;
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
//页面标题
.title("SpringMVC swagger案列")
.description("Controller 接口测试")
.contact(new Contact("联系我们","http://www.baidu.com","2324962847@qq.com"))
.version("1.1")
.build();
}
}
MvcServlet-servlet.xml配置
在原来的MVCservlet-servlet.xml内添加
<!-- swagger2静态资源映射-->
<mvc:resources mapping="/swagger-ui/**" location="classpath:/META-INF/resources/webjars/springfox-swagger-ui"/>
<mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/"/>
Controller
-
类名上添加Api
@Api(value = "IndexController",tags = {"功能模块一 示例"})
-
方法
-
没有参数
@ApiOperation(value = "跳转致index主页面",notes="index",httpMethod = "GET")
-
有参数
@ApiOperation(value="注册用户,成功后进入show页面,显示用户信息",notes = "注册",httpMethod = "GET") @ApiImplicitParams(value = {@ApiImplicitParam(name="name",value="姓名",required = true,dataType = "String"), @ApiImplicitParam(name="sex",value = "性别",required = true,dataType = "String"), @ApiImplicitParam(name="age",value = "年龄",required = true,dataType = "String")})
-
测试 Swagger
启动服务器,访问地址如下:
http://localhost:8080/mvcPart1/swagger-ui/index.html