MVC模式
- MVC指的是模型(model)–视图(view)–控制器(controller),是一种用于设计web表现层的模式,使用它可以使业务逻辑,数据,界面显示代码分离开来。
- Model(模型):指的是数据模型,用于封装数据
- View(试图):用于数据显示
- Controller(处理器):用于程序处理逻辑
SpringMVC
- SpringMVC是spring产品对MVC模式的具体实现,它可以通过一套注解,加一个简单的Java类变成控制器,不需要实现任何接口,同时还支持restful风格
Spring入门
- 首先需要创建一个Web工程
在pom.xml文件中加入
<packaging> war </packaging>
- 导入坐标
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
- 加入SpringMVC的配置文件
<!--包扫描-->
<context:component-scan base-package="com.itheima.controller"/>
<!--配置三大组件-->
<!--注解驱动 就相当于配置了加强版的 处理器映射器 和 处理器适配器-->
<mvc:annotation-driven "/>
<!--视图解析器-->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--配置前缀和后缀 当控制器中返回页面时,要拼上前后缀才是真正的返回地址 return "fail";=====> /WEB-INF/fail.jsp -->
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
- 加入web.xml(配置前端控制器)
<!--前端控制器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--指定配置文件的位置-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<!--这代表默认配置 一旦配置了/ ,它会拦截除了jsp之外的所有请求-->
<url-pattern>/</url-pattern>
</servlet-mapping>
- 开发控制器
在类上加入注解
@Controller
在方法上加上注解
// @RequestMapping指定当前方法处理的url
@RequestMapping("/hello/demo")
在方法内部设置返回路径
return "路径";
- 部署
<!--添加tomcat7插件-->
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8888</port>
<uriEncoding>UTF-8</uriEncoding>
</configuration>
</plugin>
</plugins>
</build>
SpringMVC工作流程
1.用户通过浏览器发送请求至DispatcherServlet
2. DispatcherServlet收到请求调用HandlerMapping
3. HandlerMapping找到具体的处理器链返回给DispatcherServlet
4. DispatcherServlet会根据返回的处理器链调用HandlerAdapter
5. HandlerAdapter经过适配调用具体的Handler(controller)
6. Controller执行完成返回一个执行结果
7. HandlerAdapter将Handler的结果ModelAndView对象返回给DispatcherServlet
8. DispatcherServlet将ModelAndView对象传给ViewResolver
9. ViewReslover解析后得到具体View,并返回给DispatcherServlet
10. DispatcherServlet根据View进行视图渲染(即将模型数据填充至视图中)
11. DispatcherServlet会将渲染后的视图响应给浏览器
SpringMVC三大组件
- 处理器映射器(HandlerMapping)
根据URL寻找对应的方法 - 处理器适配器(HandlerAdapter)
真正的去调用我们自己写的处理器 - 试图解析器(ViewResolver)
将逻辑试图转换为物理视图
请求接收之参数限定
RequestMapping用于建立请求url和处理请求方法之间的对应关系,并可以通过它对请求的各种属性做出限制。
value:用于限制请求URL(和path作用一样)
method:用于限制请求类型.如果不限制,任何类型都可以访问
params:用于限制请求参数的条件
此注解可以标注在方法上,也可以标注在类上,标注在类上代表类中的所有方法都可以共用一段URL
- 限定请求路径
//一个方法处理多个url
@RequestMapping(value = {"/hello/demo2","/hello/demo3"})
public String demo2(){
return "路径";
}
- 限定请求类型
//method 用于限制请求类型(方式)支持数组形式
@RequestMapping(value = "/hello/demo4",method = {RequestMethod.GET, RequestMethod.POST})
- 限定请求参数
//params 用于限制前台的必传参数,支持数组,不写代表不做限制
@RequestMapping(value = "/hello/demo5", params = "name")
求情参数之参数封装
- 简单类型*
//只需要前台传递的参数名称与方法的形参名称保持一致
@RequestMapping(value = "/hello/demo6")
public String demo6(String name,Integer age){
System.out.println(name);
System.out.println(age);
return "success";
}
- 对象类型
//自己书写一个实体类
//后台 只需要保证前台传递的参数名称与pojo的属性名(set方法)一致就好
@RequestMapping("/hello/demo7")
public String demo7(User user) {
System.out.println(user);
return "success";
}
- 数组类型
只需要保证前端传递的参数名称跟方法中的数组形参名称一致就好
@RequestMapping(value = "/hello/demo8")
public String demo8(String[] names){
System.out.println(Arrays.toString(names));
return "success";
}
- 集合类型
//自己书写一个对象其中放入单列和多列集合
//获取集合参数时,要将集合参数包装到一个写好的对象中
- 日期类型
对于一些常见的类型,SpringMVC是内置了类型转换器的,但是对于一些格式比较灵活的参数(日期 时间),SpringMVC无法完成类型转换.这时候就必须自定义类型转换器
- 自定义日期类型转换器
//自定义日期类型转换器,实现一个接口Converter<源类型, 目标类型>
public class DateConverter implements Converter<String, Date> {
//自定义转换方法
public Date convert(String s) {
try {
//2019-10-16
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date date = format.parse(s);
return date;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
- 将这个类注册到SpringMVC转换服务中
<!--将我们开发的转换器添加到转换服务中-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.itheima.converters.DateConverter"/>
</set>
</property>
</bean>
- 将转换服务注册到注解驱动上
<mvc:annotation-driven conversion-service="conversionService"/>
- 后台直接用日期类型接收
请求参数之参数处理
中文乱码
SpringMVC在使用post提交请求时,对于中文参数是有乱码问题的,针对这种情况它提供了一个中文乱码过滤器,我们只需要进行配置一下就可以了.
- 配置中文乱码过滤器
<!--中文乱码过滤器-->
<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>
###### 默认值设置
@RequestParam标注在方法参数之前,用于对传入的参数做一些限制,支持三个属性:
value:默认属性,用于指定前端传入的参数名称
required:用于指定此参数是否必传
defaultValue:当参数为非必传参数且前端没有传入参数时,指定一个默认值
//@RequestParam 可以通过指定一个value值,将方法的参数和前台传入的参数做一个绑定
//@RequestParam 标注在参数之前,那么参数必须传递,可以通过required=false取消限定
//@RequestParam 如果前台没有传递参数,可以通过defaultValue设置默认参数
#### 请求接收之获取请求头信息
//@RequestHeader 可以获取一个map结构,里面是请求头信息
//@RequestHeader(key) 根据key获取map中的value值
//@CookieValue(key) 根据key从cookie中获取value
@RequestMapping("/hello/demo13")
public String demo13(@RequestHeader Map map,
@RequestHeader("cookie") String cookie,
@CookieValue("JSESSIONID") String jSESSIONID) {
System.out.println(map);
System.out.println(cookie);
System.out.println(jSESSIONID);
return "success";
}
请求接收之接收restful风格请求
- 什么是restful风格
REST是一种软件架构风格,或者说是一种规范,其强调HTTP应当以资源为中心。(建议URL中不要出现动词)
它规范了HTTP请求动作,使用四个词语分别表示对资源的CRUD操作:
GET(获取)、POST(新建)、PUT(更新)、DELETE(删除)
- 保存
前台
//表单提交方式为post提交
后台
@RequestMapping(value = "/user", method = RequestMethod.POST)
- 查询
前台
//正常get方式提交
后台
@RequestMapping(value = "/user", method = RequestMethod.POST)
public String findUserByUid(
@PathVariable("uid") String uids,
@PathVariable("age") String age) {
System.out.println(uids);
System.out.println(age);
return "success";
}
Servlet知识
-
路径匹配规则
1. 精确匹配 /abc/index.jsp /a/b.jpg /abc/a
2. 路径匹配 /abc/* /* [要求必须是/开头,以*结尾]
3. 扩展名匹配 *.jsp *.html .do [要求必须以.开头]
4. 默认(缺省)匹配
四种匹配方式的优先级:精确 > 路径 > 扩展名 > 默认 -
几个servlet的作用
default (可以定位静态资源css html image js等) / 默认匹配
jsp (可以解析jsp文件) *.jsp 扩展名匹配
dispatcherServlet(可以根据URL寻找控制器)
-
DispatcherServlet配置 / 和 /* 的区别
配置的是 /*
只有DispatcherServlet生效,这样所有的请求都会交给它处理,处理不了就报错
配置的是/
DispatcherServlet和jsp生效,而且jsp的优先级要高,也就是访问jsp的请求由jsp的servlet的处理,其它请求由DispatcherServlet处理,处理不了就报错
结论
当我们的 dispatcherServlet 配置为/的时候.css js image等静态资源访问不了了
请求接收之释放静态资源
- 方式一
<!--释放静态资源-->
<!--
dispatcher Servert 根据URL寻找方法[找不到就报错]
如果你配置了mvc:default-servlet-handler以后,
dispatcherServlet还是根据URL找方法,找不到交给外部的默认servlet处理
-->
<mvc:default-servlet-handler />
- 方式二
```java
<!--
mapping 用于匹配URL路径,
如果匹配成功,就不用再调用处理器映射器去寻找相应的方法了,
而是直接将URL请求定位到location指定的路径下去寻找一个静态资源
-->
<mvc:resources mapping="/images/*" location="/images/"/>