MVC介绍
Model,模型层,工程中的javaBean,处理数据。
JavaBean分为两个类:
- 实体类Bean:专门存储业务数据的,eg:Student,User
- 业务处理Bean:指Service或Dao对象,处理业务逻辑和数据访问。
View:视图层,工程中的html或jsp页面。
Controller:控制层,指工作中的servlet,接受请求和相应浏览器。
工作流程:用户通过视图发出请求到服务器,服务器请求被Controller接收,Controller调用对应的Model层处理请求,处理完毕将结果返回到Controller,Controoler在将结果返回到view,渲染后相应给浏览器。
SpringMVC特点
基于原生的Servlet,通过功能强大的前端控制器DispatcherServlet,对请求和响应进行统一处理
适合现代大型,超大型互联网项目要求
应用
在使用SpringMVC时,需要引入依赖,其中scope中的使用是因为限制依赖范围,使用provided是依赖范围已被提供。
<!--ServletAPI-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
SpringMVC使用到的依赖
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.1</version>
</dependency>
<!--日志-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!--ServletAPI-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<!--thymeleaf与spring5整合-->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.12.RELEASE</version>
</dependency>
web.xml文件中设置注册servlet、注册过滤器、注册监听器。
在使用SpringMVC时,也需要配置web.xml。
浏览器不能直接访问到一个类,所以需要设置匹配路径,访问路径符合当前设置的匹配路径时,当前的请求可以被servlet处理。
servlet的默认配置
servlet的扩展配置
在resouce文件下创建一个名为springMVC配置文件。
设置配置文件的位置和名称
总结:浏览器发送的请求要统一交给控制器来处理,一个服务器就是一个servlet,想要通过servlet处理请求就需要在web.xml文件中进行注册。在注册的时候通过init-param来配置MVC配置文件的位置和名称。通过load-on-startup将初始化时间提前到服务器启动时。DispatcherServlet前端控制器能够处理的请求路径是上下文路径下的所有请求。
创建请求控制器
前端控制器对浏览器发送的请求进行了统一的处理,但是具体的请求有不同的处理过程,因此需要创建处理具体请求的类,即请求控制器。
请求控制器中每一个处理请求的方法成为控制器的方法。
SpringMVC的控制器由一个POJO(普通的Java类)担任,因此需要通过@Controlller注解将其标识为一个控制层组件,交给Spring的IoC容器管理,此时SpringMVC才能够识别控制器的存在。
四大组件:
- @Component 将类标识为一个普通的组件
- @Controller 将类标识为控制层组件
- @Service 将类标识为业务层组件
- @Repository 将类标识成持久层组件
扫描控制器
控制器被创建之后,需要被扫描后认定为IoC容器中的一个注解
在springMVC.xml配置文件中进行扫描
配置视图解析器(通用)
order:设置视图解析器的优先级
characterEncoding:编码格式
prefix:前缀
suffix:后缀
templateMode:视图模板模型
<!--配置Thymeleaf视图解析器-->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!--视图前缀-->
<property name="prefix" value="/WEB-INF/templates"/>
<!--视图后缀-->
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
注意:WEB-INF文件下的内容通过浏览器以及重定向都无法直接访问。只能通过转发。
扩展:
<!--处理静态资源,eg:html、js、css、jpg,若只设置该标签,则只能
访问静态资源,其他请求无法访问
此时必须设置<mv:default-servlet-handler/>-->
<mvc:default-servlet-handler/>
<!--开启mvc注解驱动-->
<mvc:annotation-driven>
<mvc:message-converters>
<!--处理响应中文内容乱码-->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="defaultCharset" value="UTF-8"/>
<property name="supportedMediaTypes">
<list>
<value>text/html</value>
<value>application/json</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
</beans>
编写请求控制器中的方法,完成index文件的映射。即可完成首页访问。
访问指定页面
<body>
<h1>首页</h1>
<!--以/开头的路劲是绝对路劲,绝对路径分为浏览器解析和服务器解析
超链接就是浏览器解析,/target标识localhost:8080下访问,缺少
上下文路劲。
可以直接加上,上下文路径,如下:/serenity/target。上下文路径就是tomcat中
配置的路径,此处使用了/serenity。但是在tomcat中上下文路径可更改,此处不能写
死,使用thymeleaf。-->
<a href="/target">访问目标页面target.html</a>
</body>
使用thymeleaf需要加上th,使用thymeleaf后,检测到此路径为绝对路径,会自动添加上下文。
<a th:href="@{/target}">访问目标页面target.html</a>
编写Controller中的方法控制跳转:
总结
- 浏览器发送请求,请求地址符合前端控制器的url-pattern,该请求就被前端控制器(DispatcherServlet)处理。
- 前端控制器读取SpringMVC的核心配置文件,通过扫描器找到控制器,将请求地址和控制器中@RequestMapping注解的value属性值进行匹配。
- 匹配成功,该注解所标识的控制器方法就是处理请求的方法
- 处理请求的方法需要返回一个字符串类型的视图名称。
- 视图名称会被视图解析器解析,加上前缀和后缀组成视图的路径。
- 通过Thymeleaf对视图进行渲染,最终转发到视图所对应页面。
@RequestMapping注解
功能
@RequestMapping注解主要是将请求和处理请求的控制器方法关联起来,简历映射关系,SpringMVC接收到指定 的请求,就会来找到映射关系中对应的控制器方法来处理这个请求。
位置
标识类:设置映射请求的请求路径的初始信息
标识方法:设置映射请求路径的具体信息
eg:标识类/admin 标识方法:/login
那么在请求方法时就是:加上上下文,然后/admin/login
在html文件中填写地址时,需要加上方法上的映射地址:
<a th:href="@{/admin/success}"></a>
在设置请求地址时,注意映射地址需要唯一。
代码编写:
前端注意地址映射
Value属性
@RequestMapping注解中的value通过当前请求的请求地址来匹配请求。
value属性是一个字符串类型的数组,表示该请求映射能够匹配多个请求地址所对应的请求
测试:虽然请求地址不同,但是最终跳到同一个界面。
method属性
@RequestMapping注解中的method通过请求的请求方式(get或post)来匹配请求映射。
method属性是一个RequestMethod类型的数组,表示该请求映射能够匹配多种请求方式的请求。
当前请求的请求地址满足映射的value值,但请求方式不满足method属性,则会出现405错误。
- get请求:提交请求参数时,该参数会拼接在地址(以?进行拼接),请求参数名=请求参数值,表单元素中的name=value。
- post请求:提交请求参数后,参数存放在请求体中
- post相对安全,但get传输速度快,post传输的数据量大
满足value,不满足method时,请求出现错误。
RequestMapping未设置Method的值时,默认的请求是Get请求,在html中任何请求方式都能匹配,不以method请求方式为条件。
对于处理指定方式的控制反复,SpringMVC中提供了@RequestMapping的派送注解
- 处理get请求的映射->@GetMapping
- 处理post请求的映射->@PostMapping
- 处理put请求的映射->@PutMapping
- 处理delete请求的映射->@DeleteMapping
常见的请求方式有get、post、put、delete
目前浏览器只支持get和post,若在from表单提交时,为method设置了其他请求方式的字符串(put或delete),根据默认get请求方式处理。如下,会提示错误。
params
通过请求的请求参数来匹配请求映射。
@RequestMapping注解的params属性时一个字符串类型的数组,可以通过四种表达式设置请求参数和请求映射的匹配关系。
- params:要求请求映射所匹配的请求必须携带param请求参数
- !params:要求请求映射所匹配的请求必须不能携带param请求参数
- params=value:请求映射所匹配的请求必须携带param请求参数且param=value
- params!=value:请求映射所匹配的请求必须携带param请求参数但是param!=value
以问号传参时,可以用小括号代替
headers
通过请求头信息来匹配请求。与params类似,编写格式一致,不过这个是键值对
当前请求满足value和method属性,但是不满足headers属性,此时页面显示404错误,即资源未找到。
SpringMVC支持ant风格的路径
?表示任意的单个字符
*表示任意的0个或多个字符
**表示任意的一层或多层目录
在使用**时,只能使用/**/xxx的方式
SpringMVC支持路径中的占位符
原始方式:/deleteUser?id=1
rest方式:/deleteUser/1
SpringMVC路径中的占位符常用于restful风格中,当请求路径中将某些数据通过路径的方式传输到服务器中,就可以在相应的@ReauestMapping注解的value属性中通过占位符{xxx}表示传输的数据,在通过@PathVariable注解,将占位符所表示的数据赋值给控制器方法的形参。
SpringMVC获取请求参数
通过ServletAPI获取
将HttpServletRequest作为控制器方法的形参,此时HttpServletRequest类型的参数表示封装了当前请求的请求报文的对象。
通过控制器方法的形参获取请求参数
在控制器方法的形参位置,设置和请求参数同名的形参,当浏览器发送请求,匹配到请求映射时,在DispatcherServlet中就会将请求参数赋值给相应的形参。
使用表单提交数据
多请求参数中出现多个同名的请求参数,可以在控制器方法的形参位置设置字符串类型或字符串数组来接收请求参数。
若使用字符串类型的形参,最终结果为请求参数的每一个值之间使用逗号进行拼接
@RequestParam请求参数的注解
将请求参数与形参创建关系,
@RequestParam的值,value是参数名字,required=true是,需要传输的值必须符合前后端一致,必须要传(没有传会报400错误),required=false时,可以不传。defaultValue默认值,不传参数的时候或传输的是空字符串时,给形参赋一个默认值
@RequestHeader
是将请求头信息和控制器方法的形参创建映射关系
该注解一共有三个属性,value,required,defaultValue,用法与@RequestParam相同
@CookieValue
是将cookie数据和控制器方法的形参创建映射条件
该注解一共有三个属性,value,required,defaultValue,用法与@RequestParam相同
通过POJO获取请求参数
在控制器方法的形参位置设置一个实体类类型的形参,此时若浏览器传输的请求参数的参数名和实体类中的属性名一致,那么请求参数就会为此属性赋值。(下面这个例子在实体类中文件写sex属性了,所以输出的user中没有sex属性值,)
解决获取请求参数的乱码问题
Get请求的乱码是Tomcat造成的,
可以通过在Tomcat的conf配置文件中添加URIEncoding="UTF-8"。
POST请求的乱码
配置过滤器,因为处理乱码,需要在Servlet之前。
<!--配置过滤器-->
<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>