https://www.bilibili.com/video/BV1mW411M7YA?p=1
目录
三:使用 @RequestMapping 映射请求:(可以点注解进去,进行查看)
十六:在 Spring 的环境下 使用 SpringMVC:
处理JSON:使用 HttpMessageConverter:
一:SpringMVC 概述:
1)MVC 设计模式:
a:MVC 设计模式:是一种 分层架构 编程思想,目的是实现分层设计,提高代码可维护性和拓展性。
b:MVC设计模式认为,任何软件都可以分为三个部分:
* 控制程序流转的 控制器:(Controller)
* 封装数据,处理数据的 模型:(Model)
* 负责展示数据的 视图:(View)
c:并且 MVC 思想要求,这三个部分应该 相互独立,互不干扰,如果某一个模块发生变化,尽量不影响其他两个模块。
d:好处是:结构清晰,可读性强,利于后期拓展和维护,可以更好地实现复用。
2)Servlet 缺点:
a:通常情况下,一个Servlet类只负责处理一个请求,若项目中有成百上千个请求需要处理,就需要有成 百上千个Servlet类,这样会使得项目中Servlet类的个数暴增;
b:在Servlet3.0版本之前,每一个Servlet都需要在web.xml文件中至少做八行配置信息,配置内容多且繁琐。当Servlet特别多时,web.xml配置量太多,不利于团队开发;
c:当通过客户端提交参数到服务器,通过Servlet进行接收时,无论数据本身是什么格式,在Servlet中一律按照字符串进行接收,后期需要进行类型转换,复杂类型还需要特殊处理,特别麻烦!
d:servlet具有容器依赖性,必须放在服务器中运行,不利于单元测试;
3)SpringMVC 与 Struts2 区别?
我没使用过 Struts2 ,但是了解一些他们的区别?
a:相同点:
* 他们都是表现层框架,都是 基于 MVC 设计模式 编写的。
* 他们的底层 都离不开 servlet API
* 他们 处理请求的机制,都是一个核心控制器。
b:区别:
* Springmvc 入口是 Servlet 配置的 DispatcherServlet ,Struts2 入口是 Filter
* springmvc 性能和并发量,要高于 Struts2。
* springMVC 使用 和 spring 框架整合 更加简洁,
* Springmvc 支持 JSR303,处理 Ajax 请求更方便。
4)SpringMVC 执行流程:
5)面:谈谈你对 Spring mvc 框架的理解:
a:mvc是一种分层设计的思想,model,view,controller。
springMVC利用这种分层的思想,封装了Servler,极大的简化了取值和赋值的过程。
b:主要做的是:
将URL解析,映射到对应的类和方法
接收前端的数据
对前端数据操作
返回给前端数据
c:SpringmMVC执行流程
二:SpringMVC 的HelloWord:
https://www.jb51.net/article/192958.htm(新建项目)
1)加入 jar 包(log,aop,4个核心,web,webmvc)
2)在 web.xml 中配置 DispatcherServlet
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--配置 DispatcherServlet 初始化参数:配置Springmvc配置文件 和 名称-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
<!--这个 servlet 第一次加载时被创建,不是请求后被创建-->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 其中的斜杠(/)表示拦截所有请求(除JSP以外), 所有请求都要经过springmvc前端控制器 -->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
3)加入 SpringMVC 的配置文件
<!--配置扫描的包-->
<context:component-scan base-package="com.tedu.Controller"/>
4)放行 告诉 前端控制器,哪些资源不拦截
a:方式一:有选择放行
<!-- SpringMVC 引入 js 文件时,会被 前端控制器拦截,设置放行规则 -->
<!-- 放行 js -->
<mvc:resources mapping="/js/**" location="/WEB-INF/js/"/>
<mvc:resources mapping="/js/**" location="**/js/**"/>
b:方式二:全部放行:
<mvc:default-servlet-handler/>
c:方式三:引入js
<script type="text/javascript"
src="${pageContext.request.contextPath}/js/jquery.min.js"></script>
5)编写处理请求的处理器,并标识为处理器
@Controller
public class TestController {
/**
* 1.使用 @RequestMapping 注解,来映射请求的URL
* 2.返回值会通过,视图解析器,为实际的物理视图
*/
@RequestMapping(value = "/hello")
public String hello() {
System.out.println("hello,world");
return "seccess";
}
}
6)编写视图解析器:
<!--配置 视图处理器,目的是:把逻辑视图 转换为 物理视图-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
三:使用 @RequestMapping 映射请求:(可以点注解进去,进行查看)
1)RequestMapping:可以修饰方法,也可以修饰类。
a:使用 Value 属性:规定 访问的路径。
b:使用 method 属性:规定请求方法类型。
@RequestMapping(value = "/test",method = RequestMethod.POST)
c:使用 params 属性:规定必须包含某些参数、规定某些参数的值。
@RequestMapping(value = "/hello", params = {"name", "age=10", "sa!=200"})
d:使用 hearders 属性:规定 请求必须包含请求头。
@RequestMapping(value = "/test", headers = {"Accept"})
e:用 bean 接收去参数:前端传 级联属性 时,使用 user.address 方式进行传输。
f:List 和 Map 参数绑定:
2)@PathVariable 映射 URL 绑定的占位符
a:通过 @PathVariable 可以将:URL 中占位符参数,绑定到目标方法的参数中。
b:代码:
@RequestMapping(value = "/test_03/{id1}")
public String test_03(@PathVariable(value = "id") Integer id2) {
System.out.println("11"+id2);
return SECUESS;
}
3)REST :
a:REST 概念:
*(资源)表现层转化。是目前最流行的一种互联网软件架构。
* 它结构清晰,符合标准,易于理解,拓展方便,得到越来越多网站采用。
b:资源(Resources):
* 网络上的一个实体,或者说是网络上的一个具体资源。
c:表现层:
* 把资源 具体呈现出来的形式,叫做他的表现层。
d:状态转化:
* 请求路径相同,根据请求方法不同(可能拦截器转化)
* 执行不同的操作:
- GET --》获取
- POST --》新建
- PUT --》更新
- DELETE--》删除
四:映射请求参数 & 请求头:
1)映射请求参数:
a:@RequestParam:接收请求(非必须参数)
@RequestMapping(value = "/hello")
public String hello(
@RequestParam(value = "age") Integer age,
@RequestParam(value = "name", required = false, defaultValue = "张三") String name) {
return "secuess";
}
b:@RequestBody:接收请求体(表单提交)
//Content-Type: text/html;charset=UTF-8
@RequestMapping(value = "/hello", method = RequestMethod.POST)
public String hello(Teacher teacher) {
System.out.printf("Teacher : " + teacher);
return "secuess";
}
c:@RequestBody:接收 Ajax 传来的 json 参数:
* 使用前提:因为 将 json 转换为 bean 对象,
需要使用 FastJson ,所以需要引入 fastJson 依赖。
@ResponseBody
@RequestMapping(value = "/testFastJson",method = RequestMethod.POST)
public Teacher testFastJson(@RequestBody Teacher teacher) {
System.out.println(teacher);
return teacher;
}
d:@RequestHeader: 获取请求头的值。
public String hello(@RequestHeader(value = "Connection")String connection)
e:@CookieValue: 获取指定的 Cookie 值
public String hello(@CookieValue(value = "testCookie") String testCookie)
2)使用 POJO 对象,绑定请求参数值:
a:使用 POJO 对象:
* SpringMVC 会按请求参数名 和 POJO属性名,进行自动匹配,自动为该对象填充属性值,支持级联属性。
* 如:dept.deptId、dept.address.tel 等:
b:代码:
* 前端:
<form action="/hello" method="post">
username:<input type="text" name="username">
<br>
password:<input type="text" name="password">
<br>
stuUsername:<input type="text" name="student.stuUsername">
<br>
stuPassword:<input type="text" name="student.stuPassword">
<br>
<input type="submit" value="submit">
</form>
* 后端:
@RequestMapping(value = "/hello", method = RequestMethod.POST)
public String hello(Teacher teacher) {
System.out.printf("Teacher : " + teacher);
return "secuess";
}
3)使用 Servlet 原生 API 作为参数传入
a:可以使用 Servlet 原生的 API 作为方法的参数:
b:代码:
@RequestMapping(value = "/request",method = RequestMethod.POST)
public String test_06(HttpServletRequest request, HttpServletResponse response) {
String name = request.getParameter("name");
String password = request.getParameter("password");
System.out.println(name+password);
return SECUESS;
}
4)映射请求头:
a:@RequestHeader:映射请求头信息(了解)
@RequestMapping(value = "/test_04")
public String test_04(@RequestHeader(value = "Accept-Language")String al) {
System.out.println("name2:" + al);
return SECUESS;
}
b:CookieValue:映射请求Session
@RequestMapping(value = "/test_04")
public String test_04(@CookieValue(value = "JSESSIONID")String cookieId) {
System.out.println("name2:" + cookieId);
return SECUESS;
}
五:处理器模型数据:
SpringMVC 几种途径输出模型数据:
1)ModelAndView:
a:处理方法返回值类型为: ModelAndView时,
* 可以通过该对象添加 视图 和 模型数据,返回出去。
* springMVC 会把 ModelAndView 的 model 中数据放入到 request 域对象中。
* 获取方式:${requestScope.time }
b:代码:
@RequestMapping(value = "/test_06")
public ModelAndView testModelAndView() {
ModelAndView modelAndView = new ModelAndView(SECUESS);
modelAndView.addObject("time", "2020");
return modelAndView;
}
2)Map 及 Model:
a:作为入参时,Map中的数据,会自动添加到模型中。(可以是:Map,Model,ModelMap 等类型)
b:代码:
@RequestMapping(value = "/test_07")
public String testModel(Map<String,Object> map) {
map.put("names", Arrays.asList("tom", "jerry"));
return SECUESS;
}
c:代码:
@RequestMapping(value = "/test_06")
public String testModel(Model model) {
model.addAttribute("time", "2020");
return SECUESS;
}
3)@SessionAttributes:
a:将模型(Model)中的某个属性,暂存到 HttpSession 中,以便多个请求之间,共享这个模型属性数据。
允许我有选择的 将 model 中的 某些数据,存储到 HttpSession 对象中。
b:用于多次执行 控制器方法间的 参数共享:也就是用于方法之间数据的共享。第一个方法 存储在 Session 域中,第二个方法,从 Session 域中 取值。
c:代码:(只能声明在 在类上,不能声明在方法上)
@SessionAttributes(value = {"str"}, types = {String.class})
@Controller
public class TestSessionAttributes {
@RequestMapping(value = "/testSessionAttributes")
public String testSessionAttributes(Model model) {
model.addAttribute("str", "abc");
return "secuess";
}
}
d:代码解释:
* 目标方法中,将 str 以 key,value 的形式,存入到 Model 域对象中,
类上的 @SessionAttributes(value = {"str"}) 注解表示,将 str 又存入到 Session 域对象中 。
* 在整个类中,只要有 String 类型的数据,存到域中,就会自动存储到 Session 中。
e:其他方法从 Session 域中取值
@RequestMapping(value = "/testGetSessionAttributes")
public String testGetSessionAttributes(ModelMap modelMap) {
Object str = modelMap.get("str");
System.out.println(str);
return "secuess";
}
f:清除 Session 域
@RequestMapping(value = "/testDeleteSession")
public String testDeleteSession(SessionStatus sessionStatus) {
boolean complete = sessionStatus.setComplete();
return "secuess";
}
4)@ModelAttribute:
a:@ModelAttribute 修饰方法:
* 修饰的方法,会先于 @RequestMapping 方法 被 SpringMVC 调用:
该方法一般用于: 接收前台jsp页面传入的请求参数,然后将参数 封装到 Model 中。
* 代码:
@ModelAttribute
public void modelAttribute(@RequestParam(value = "name") String name, Model model) {
User user = new User();
user.setName(name);
model.addAttribute("user", user);
}
@RequestMapping(value = "/test011", method = RequestMethod.GET)
public String test01o(Model model) {
User user = (User) model.getAttribute("user");
System.out.println(user.toString());
return SECUESS;
}
* 应用场景:根据 id 修改 age,密码不能变,先在 modelAttribute 中,获取密码放到域对象中。
b:ModelAttribute 也可以来修饰 目标方法 POJO 类型的入参,获取指定的数据值。
* 其 value 属性值,有如下作用:(从 域 中取对象)
方法入参标注该注解后,入参的对象就会放到数据模型中。
Spring MVC 会使用 value 属性值,在 implicitmodel中查找对应的对象,
若存在,则直接传入到目标方法的入参中。
* 查找的 User user 方法入参,值为 用 @Modelattribute 修饰方法 ,map.put('user',user);
与 map 中的 key 相对应。
* 代码:
@ModelAttribute
public void testda(@RequestParam(value = "name1") String name1, Map map) {
User user = new User();
user.setName(name1);
map.put("aa", user);
}
//参数里的 @ModelAttribute 注解,value 从 Map 的 key 中取值。
@RequestMapping(value = "/test_005", method = RequestMethod.GET)
public String test_005(@ModelAttribute(value = "aa") User user) {
System.out.println(user.toString());
return SECUESS;
}
5)@ResponseBody:
a:相当于 servlet 里面:response.getWriter().print("123");
六:视图和视图解析器:
5)(spring-config.xml中配置):
<--
例如我有一个a.jsp 文件 位于WEB-INF 目录下 那么这个WEB-INF 就是前缀
这个jsp 就是后缀 这样我们在servlet中只需要返回a 就可以定位到a.jsp 这个文件了
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
</bean>
七:请求转发和请求重定向:
1)一般情况下,
a:控制器方法,返回字符串类型的值,会被当成逻辑视图名处理。
b:如果返回的字符串中,带 forward: 或者 redirect: 前缀时,SpringMVC 会对其特殊处理。
2)代码:
a:转 发:return "forward:/tt";
b:重定向:return "redirect:http://www.baidu.com";
八:RESTful CRUD:
九:SpringMVC 表单标签 & 处理静态资源:
1)<!--放行静态资源的访问-->
a:<mvc:default-servlet-handler/>
2)注解驱动
a:<mvc:annotation-driven/>
b:会自动注册:
--RequestMappingHandlerMapping
--RequestMappingHandlerAdapter
--ExceptionHandlerExceptionResolver 。三个 Bean
c:还会提供以下支持:
--支持使用 ConversionService 实例对表单参数进行类型转换
--支持使用 @NumberFormat、@DateTimeFormate 注解,完成数据类型格式化。
--支持使用 @Valid 注解,对 java bean 实例进行 JSR 303验证
--支持使用 @RequestBody 和 @ResponseBody 注解
十:数据转换 & 数据格式化 & 数据校验:
1)数据绑定原理:
a:Spring MVC 主框架将 ServletRequest 对象及目标方法的入参实例 传递给 WebDataBinderFactory 实例,以创建 DataBinder 实例对象
b:DataBinder 调用装配在 Spring MVC 上下文中的 ConversionService 组件进行数据类型转换、数据格式化工作。将 Servlet 中的请求信息填充到入参对象中
c:调用 Validator 组件对已经绑定了请求消息的入参对象进行数据合法性校验,并最终生成数据绑定结果 BindingData 对象
d:Spring MVC 抽取 BindingResult 中的入参对象和校验错误对象,将它们赋给处理方法的响应入参
e:图示:
Spring MVC 通过反射机制对目标处理方法进行解析,将请求消息绑定到处理方法的入参中。数据绑定的核心部件是 DataBinder,运行机制如下:
2)数据类型转换: /* 自定义日期转换格式 */
a:要想实现 数据类型转换,界必须实现 Converter<S,T> 这个接口。
spring 已经提供好,很多个 实现 Converter 接口的实现类。
例如:StringToBooleanConverter 实现类。
b:public String test_date(@RequestParam(value = "datee") Date date)
只支持 日期字符串 格式为:datee=2020/11/11。
c:解决办法,写一个 自定义类型转换器类,继承 Converter 接口,并实现方法。
-1.
@Override
public Date convert(String s) {
DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date parse = null;
try {
parse = simpleDateFormat.parse(s);
} catch (ParseException e) {
throw new RuntimeException("类型转换出现错误:" + e);
}
return parse;
}
-2.在 SpringMVC 配置文件中 注册 自定义类型转换器,:
<bean id="conversionServiceFactoryBean"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.tedu.controller.converter.MyConverterUtils"></bean>
</set>
</property>
</bean>
-3.
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean">
</mvc:annotation-driven>
d:public String test_date(@RequestParam(value = "datee") Date date)
只支持 日期字符串 格式为:datee=2020/11/11。
e:添加 自定义的 编辑器 转换数据。
-1.在 Controller 类里面,添加 InitBinder() 方法。
-2.由 @InitBinder 标识的方法,
可以对 WebDataBinder 对象进行初始化,用于完成,
表单字段到 JavaBean 属性的绑定。
-3.代码:
@InitBinder
public void test001(WebDataBinder webDataBinder) {
//在绑定过程中,设置哪一个注解,不进行赋值。
webDataBinder.setDisallowedFields("userName");
}
3)数据格式化:
a:传入数据,转换为 规定的 格式。
b:代码:
@DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss")
private Date birth;
@NumberFormat(pattern = "###,###,###.##")
private double salary;
c:如果转换出错,出错信息会存储到 BindingResult 对象里面。
4)数据校验:
c:数据校验有两种方法:
-1.Spring Validation 校验框架
-2.JSR303
b:Spring Validation 校验框架:
-1.重写 Validator 接口,重写接口方法,进行数据校验。
-2.@Repository("userValidator"):此注解 将 该对象实例,
注释为 Spring 容器中的一个实例。
c:JSR303:
如何校验?注解?
-1.加入 JSR303 jar包。加入 Hibernate validaor 验证框架。
-2.在 spring 配置文件中,添加对应的注解。加 <MVC driven注解>。
-3.在 Bean 对象属性中,添加相对应的注解。
@NotBlank(message = "登录名不能为空!")
private String userName;
@Email(message = "必须为合法的邮箱!")
private String email;
-4.通过处理方法 入参中标注,@valid 注解,可以让 springmvc 完成数据绑定后的校验工作。
-5.代码:
//特别注意, Bean对象入参 和 BindingResult result 之间,不能有任何参数。
public ModelAndView test_01(@Valid User user, BindingResult result,Map map)
c:验证出错,转到哪一个页面
-1.代码1:
if (result.getErrorCount()>0) {
System.out.println("出错了");
//若验证出错,则转向定制的页面:
return "index";
}
-2.代码2:
@RequestMapping(value = "/testFastJson2",method = RequestMethod.POST)
public String testFastJson2(@Valid Teacher teacher,Error error) {
if (error.hasErrors()) {
throw new RuntimeException("错误");
}
return "";
}
c:错误消息如何显示?如何把数据消息,进行国际化?
-1.如何在页面上显示错误消息。
-2.如何国际化。
5)错误信息封装:
public ModelAndView test_01(User user, BindingResult result)
十一:文件上传 和下载:
1)使用传统方式上传文件。
@RequestMapping(value = "/httpServletRequestFile")
public String httpServletRequestFile(HttpServletRequest request) throws Exception {
System.out.println("HttpServlet文件上传。");
//上传的位置。
String realPath = request.getSession().getServletContext().getRealPath("/upload/");
System.out.println("real: " + realPath);
//判断路径是否存在
File file = new File(realPath);
if (!file.exists()) {
System.out.println("创建文件。");
boolean mkdirs = file.mkdirs();
}
//解析 request 项,获取上传文件。
//创建磁盘文件项
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
//解析 request ,这里面全都是上传的文件项。
List<FileItem> fileItems = servletFileUpload.parseRequest(request);
for (FileItem fileItem : fileItems) {
//判断 当前 item 是否为 上传文件项
if (fileItem.isFormField()) {
System.out.println("这是普通表单项");
} else {
System.out.println("是上传文件项");
//完成文件上传
fileItem.write(new File(realPath, fileItem.getFieldName()));
//删除临时文件:
fileItem.delete();
}
}
return "secuess";
}
2)SpringMVC 跨服务器文件上传:
a:实际开发中,我们可能会有,处理不同功能的服务器。例如:
-1.应用服务器:负责部署我们的应用。
-2.数据库服务器:负责存储我们的数据。
-3.缓存和消息服务器:处理高并发的缓存和消息。
-4.文件服务器:负责存储用户 上传文件的服务器。
b:添加 支持跨服务器 的 jar 包:
jersey-client
jersey-core
c:代码:
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.19.4</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.19.4</version>
</dependency>
@RequestMapping(value = "/httpServletRequestFile")
public String httpServletRequestFile(MultipartFile file) throws Exception {
//定义上传文件服务器路径。
String path = "http://localhost:9090/uploads/";
//创建客户端的对象。
Client client = Client.create();
//和图片服务器进行连接
WebResource webResource = client.resource(path + "/" + "FileName");
//上传文件
webResource.put(file);
return "secuess";
}
5)Springmvc 可以直接进行文件的上传,是通过 MultipartResolve 实现的,
MultipartResolve 是一个接口。 默认情况下,
a:需要引入 依赖,
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
b:需要 在 spring 配置文件中 配置 CommonsMultopartResolver 实现类。
也就是配置 文件解析器 对象,id 必须为 multipartResolver。不能修改。
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--上传文件的最大大小,单位为字节 -->
<property name="maxUploadSize" value="17367648787"></property>
<!-- 上传文件的编码 -->
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
c:上传页面:注意:标签 必须为 enctype="multipart/form-data"。
<form action="acceptFile" enctype="multipart/form-data" method="post">
姓名:<input type="text" name="userName">
文件:<input type="file" name="upFile">
<input type="submit" value="提交">
</form>
d:请求接收:
@RequestMapping(value = "/acceptFile")
public String acceptFile(@RequestParam(value = "upFile") MultipartFile file,
Teacher teacher) {
System.out.println(file.getOriginalFilename());
System.out.println(teacher);
return "secuess";
}
5)文件下载:步骤:
a:获取要下载的 文件名。
b:读取 要下载的 文件内容。
c:把下载的 文件内容,回传给客户端。
d:在响应前,通过响应头,告诉客户端,返回数据的类型。
e:还要告诉客户端,收到的数据 是用于 下载使用。
@RequestMapping("/download")
public ResponseEntity<byte[]> download(HttpServletRequest request) throws Exception {
// 1.得到要下载文件的真实路径
String realPath = "D:\\总结归纳的笔记\\bili_尚硅谷\\01_java基础阶段\\java_基础教程\\tcp01.png";
File file = new File(realPath);
boolean exists = file.exists();
// 2.得到要下载的文件的流
FileInputStream is = new FileInputStream(file);
// 使用available获取的大小和文件大小相同
byte[] temp = new byte[is.available()];
is.read(temp);
is.close();
// 3.将要下载的文件流返回
// 自定义响应头
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set("Content-Disposition", "attachment;filename=jQuery-3.4.1.js");
return new ResponseEntity<byte[]>(temp, httpHeaders, HttpStatus.OK);
}
十二:使用拦截器、过滤器:
1)拦截器介绍:(Interceptor)
a:介绍:
-1.拦截器 :是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。
-2.Springmvc 的拦截器,类似于 Servlet 的 Filter,用于对 处理器进行 预处理和后处理。
-3.拦截器链:就是多个拦截器 按照一定顺序,被顺序调用。
a:过滤器 和 拦截器 区别:
-1.过滤器:
是 Servlet 规范中一部分,任何 JavaWeb 都可以使用。
过滤路径 :/* 规定了,对所有访问,进行资源拦截。
-2.拦截器:是 Springmvc 框架自己的,只有使用的 Springmvc 的程序才可以使用。
拦截器只会拦截,控制其方法,如果访问 JSP、JS等,不进行拦截。
2)使用步骤:
a:写 自定义拦截器 实现 HandlerIntercepter 接口。
b:实现接口的 三个 方法:
-1.preHandle():
该方法:在 目标方法之前被调用。return true,则会继续执行。
-2.postHandle()
该方法:在 目标方法代用之后,渲染视图之前被调用。
-3.afterCompletion()
该方法:在 渲染视图之后被调用。
c:在 springmvc 配置文件中,进行配置自定义拦截器:
-1.方式一:全部拦截
<mvc:interceptors>
<bean class="com.tedu.interceptor.FirstIntercepter"></bean>
</mvc:interceptors>
-2.方式二:部分拦截/部分不拦截
<mvc:interceptors>
<mvc:interceptor>
<!--配置 拦截路径 -->
<mvc:mapping path="/emps/**"/>
<bean class="com.tedu.interceptor.FirstIntercepter"></bean>
</mvc:interceptor>
</mvc:interceptors>
3)多个拦截器的 执行顺序:
去的时候,正序,回来的时候,反序执行。
类似于高速,去的时候,先路过的收费站,返回时,后路过。
4)过滤器:(Servlet 提供)(filter)(web.xml)
a:过滤器:是在javaweb中,你传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的action进行业务逻辑。 比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符.。
b:使用:
<!-- 自定义编码拦截器 也是spring为我们写好的 -->
<!-- 乱码处理过滤器 -->
<filter>
<filter-name>encodingFilter</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>encodingFilter</filter-name>
<!-- 指定拦截方式为拦截所有请求 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
十三:异常处理:
1)异常处理思路:
我们写程序时,Controller 调用 Service,Service 调用 Dao,异常都是向上抛出的,
最终 DispatcherServlet 找到异常处理器,进行异常的处理。
2)处理异常两种方式
方式一:实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器;
方式二:使用@ExceptionHandler注解实现异常处理;
3)方式一:使用步骤:
a:编写自定义异常的类(做提示信息的)
public class FirstException extends Exception {
private String message;
public FirstException() {
}
public FirstException(String message) {
this.message = message;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
b:编写异常处理器
c:配置异常处理器(跳转到提示页面)
public class FirstHandlerException implements HandlerExceptionResolver {
/**
* 处理异常的业务逻辑
*/
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response,
Object handler, Exception ex) {
if (ex instanceof FirstException) {
FirstException e = (FirstException) ex;
ModelAndView error = new ModelAndView("error");
error.addObject("message", e.getMessage());
return error;
FirstException firstException = new FirstException("系统正在维护!");
ModelAndView error = new ModelAndView("noerror");
error.addObject("message", "系统正在维护!");
return error;
}
}
}
d:在 sprignmvc 配置文件中,进行配置。
3)方式二:使用步骤:
@ControllerAdvice
public class ExceptionController11 {
@ExceptionHandler(value = {RuntimeException.class})
public ModelAndView pp(RuntimeException ex) {
System.out.println(ex);
ModelAndView noerror = new ModelAndView("noerror");
noerror.addObject("message", "出现错误!!!");
return noerror;
}
}