Filter:
1.组件:
Servlet:小应用程序,在JavaWeb中主要作为控制器来使用 可以处理用户的请求并且做出响应 实现接口:javax.servlet.Servlet
Filter:过滤器,对用户发送或相应进行集中处理,实现请求的拦截 实现接口:javax.sevlet.Filter
Listener:监听器,在Web执行过程中,监听一些事件,相当于事件发生时,进行处理,javax.servlet.XxxxListener每个时间有一个接口
Filter的应用场景:登录验证,统一编码处理,敏感字符过滤
过滤器API介绍(Filter表示一个过滤器接口,自己定义的类实现该接口就要实现他的所有方法,其实JDK1.8以后他里面除了一个doFilter方法以外其他的方法都用了defult修饰了表示不用必须重写):
1:void init(FilterConfig filterConfig) 过滤器对象创建的时候调用的方法
2:void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 执行过滤的方法,每次访问被拦截的资源都会执行该方法
3:void destory() 过滤器销毁的时候调用的方法
其中doFilter的方法中第三个参数FilterChain有一个方法也是doFilter,但是他的参数是resquest和response这两个参数,表示放行,如果没有这个方法就不放行,如果有这个方法就放行
Filter过滤器接口的:
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
参数:
request:表示请求对象,不满足http协议
response:表示响应对象,不满足http协议
chain:属于FilterChain的接口,表示过滤器链。
FilterChain接口中具有一个放行方法:
void doFilter(ServletRequest request, ServletResponse response)
如果放行,希望浏览器可以访问拦截的资源则执行该方法
如果不放行,不希望浏览器访问拦截的资源则不执行该方法
代码的实现:
package com.itheima.sh.b_filter_01;
import javax.servlet.*;
import java.io.IOException;
//1.自定义过滤器类实现过滤器接口Filter
public class MyFilter implements Filter{
//2.在自定义类中实现过滤器接口Filter中的所有抽象方法
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
//3.在doFilter方法体中书写拦截资源的代码
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("执行过滤器了...");
//不放行
/*
Filter过滤器接口的:
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
参数:
request:表示请求对象,不满足http协议
response:表示响应对象,不满足http协议
chain:属于FilterChain的接口,表示过滤器链。
FilterChain接口中具有一个放行方法:
void doFilter(ServletRequest request, ServletResponse response)
如果放行,希望浏览器可以访问拦截的资源则执行该方法
如果不放行,不希望浏览器访问拦截的资源则不执行该方法
*/
//放行
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
拦截器有两种方式:一种是在Web.xml核心配置文件中配置,如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--配置过滤器-->
<!--表示关联的过滤器类-->
<filter>
<filter-name>myFilter</filter-name>
<!--过滤器类的全路径,底层获取这里使用反射技术调用无参构造方法创建过滤器类的对象-->
<filter-class>com.itheima.sh.b_filter_01.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<!--配置被拦截的资源-->
<url-pattern>/filter01.html</url-pattern>
</filter-mapping>
</web-app>
第二种是注解版本:
@WebFilter("/filter01.html")
Filter的生命周期:指的是一个对象丛生(创建)到死(销毁)的一个过程
// 初始化方法
//服务器启动项目加载,创建filter对象,执行init方法(只执行一次)
public void init(FilterConfig config);
// 执行拦截方法
//用户访问被拦截目标资源时,执行doFilter方法
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain);
// 销毁方法
//服务器关闭时,销毁filter对象,执行destroy方法(只执行一次)
public void destroy();
Filter的拦截路径:
这个一共有四种:
1:精准匹配:用户访问指定目标资源(/demo01.html)时,过滤器进行拦截
2:目录匹配:用户访问指定目录下(/user/*)所有资源时,过滤器进行拦截
3:后缀匹配:用户访问指定后缀名(*.html)的资源时,过滤器进行拦截,不能加/
4:匹配所有:用户访问该网站所有资源(/*)时,过滤器进行拦截
过滤器链:有一次请求中,若我们匹配到了多个filter,通过请求就相当于把这些filter串起来了,形成了过滤器链。。如果匹配到的每个过滤器都是匹配的相同路径,那么他们的执行顺序就是根据该类的名字的顺序,按照首字母abcd来匹配,如果他们的首字母一样那么就根据第二个字母。
1.如果同一个包下,多个过滤器拦截同一个资源,那么按照过滤器类的名字字母升序来依次执行
AFilter ---- BFilter
2.执行完拦截资源后依次在按照相反顺序执行
3.如果是xml配置方式,那么按照从上往下配置的顺序执行
Filter统一解决post请求乱码问题
可以使用所有路径@WebFilter("/*"),然后每个网页都会进来这个拦截器,然后在这个拦截器中解决乱码,代码如下:
package com.itheima.sh.c_filter_test_03;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
/*表示拦截当前项目中所有的资源路径
解决全站乱码问题
*/
@WebFilter("/*")
public class EncodingFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//解决请求乱码
request.setCharacterEncoding("utf-8");
//解决响应乱码
response.setContentType("text/html;charset=utf-8");
//your code....
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig config) throws ServletException {
}
}
Listener:就是监听
1.ServletContext 表示上下文对象,属于接口,代表整个web项目,可以使用方法获取当前web项目的所有文件的MIME类型
2.之前学习能够共享数据的对象:
1)request: 只能在一次请求一次响应中进行数据的共享
2)session:只能在一次会话过程中,可以有多次请求和响应,
3)ServletContext:只要项目存在就可以共享数据,多次会话,多次请求和响应都可以共享数据:操作整个项目的配置文件
范围大小: ServletContext > session > request# 监听
1. 设置监听器的人
2. 监听器
2. 监听器目标: 被监听的对象
3. 监听器工作: 被监听的对象执行某种行为,监听器就开始工作# web里面
1. 雇佣人 : web程序开发者
2. 监听器例子A
1). 监听器A: ServletContextListener ****
2). 目标 : ServletContext对象
3). 执行 : 监听ServletContext对象创建和销毁
3. 监听器例子B
1). 监听器A: HttpSessionListener
2). 目标 : HttpSession对象
3). 执行 : 监听HttpSession对象创建和销毁
4. 监听器例子C
1). 监听器A: HttpRequestListener
2). 目标 : HttpRequest对象
3). 执行 : 监听HttpRequest对象创建和销毁
5. 监听器例子D
1). 监听器A: ServletContextAttributeListener ****
2). 目标 : ServletContext对象
3). 执行 : 监听ServletContext对象增删改数据 (add,remove) 当我们向ServletContext对象中添加数据(setAttribute())和删除数据(removeAttribute())就会被ServletContextAttributeListener监听器监听
HttpSessionAttributeListener HttpRequestAttributeListener
意思就是比如想要监听上下文本创建和销毁就实现ServletContextListener,如果想要看上下文本的增删改那么实现 ServletContextAttributeListener
SPring框架就是有使用监听SercletContextListener,然后它里面有一个方法contextInitializad(SercletContextEvent sce)这个方法是tomcat启动就创建,然后可以使用参数sce.getInitParater();这个方法得到web.xml的值,启动的时候就读取了配置框架,
其实就是比如Spring里面有properties.properties或者properties.yml这个文件就是配置Spring的一些配置,所以个人理解就是启动的时候就把这些配置文件就这样读取了然后就配置
@WebListener
public class ServletContextTest01Listener implements ServletContextListener {
/*
需求:可以在项目启动时读取配置文件。获取配置文件的名字。
分析:
项目启动就会创建上下文ServletContext对象,然后就会被监听器ServletContextTest01Listener监听到,并执行上下文初始化方法
:contextInitialized,然后我们可以使用该方法的参数ServletContextEvent对象调用方法:ServletContext getServletContext()
最后使用上下文对象调用ServletContext中的方法: String getInitParameter(String name) 就可以获取配置文件的的名字了
*/
@Override
public void contextInitialized(ServletContextEvent sce) {
//1.获取上下文对象
ServletContext servletContext = sce.getServletContext();
//2.使用上下文对象调用方法获取数据
/*
<context-param>
<param-name>jdbc</param-name>
<param-value>jdbc.properties</param-value>
</context-param>
*/
String jdbc = servletContext.getInitParameter("jdbc");
System.out.println("jdbc = " + jdbc);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
FastJSON:
json的语法有两个:对象:{} 数组:[]
#json的语法主要有两种:
1. 对象 { }
2. 数组 [ ]
1. 对象类型
{name:value,name:value}
2. 数组类型
[
{name:value,name:value},
{name:value,name:value},
{name:value,name:value}
]
3. 复杂对象
{
name:value,
wives:[{name:value},{},{}],
son:{name:value}
}
#注意:
1. 其中name必须是string类型
json在js中,name的双引号可以省略
2. value必须是以下数据类型之一:
字符串
数字
对象(JSON 对象)
数组
布尔
Null
3. JSON 中的字符串必须用双引号包围。(单引号不行!)
添加依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
具体的代码如下:
package com.itheima.test;
import com.alibaba.fastjson.JSON;
import com.itheima02.json.User;
import org.junit.Test;
import java.util.ArrayList;
/*
TODO 需求:
java对象或集合 转换成 json格式字符串
json格式字符串 转换成 java对象或集合
*/
public class JsonDemo {
@Test
public void method01(){
//json格式字符串转化为集合
String s= "[\"password\",\"1234\",\"username\",\"浩哥\"]";
List<String> list = JSON.parseArray(s, String.class);
System.out.println(list);
}
@Test
public void method02(){
//java对象转json格式字符串
User user = new User("ls", "123");
//{"password":"123","username":"ls"}
String s = JSON.toJSONString(user);
System.out.println(s);
}
@Test
public void method03(){
//java集合转json格式字符串
User user1 = new User("ls", "123");
User user2 = new User("ww", "110");
ArrayList<User> list = new ArrayList<>();
list.add(user1);
list.add(user2);
//[{"password":"123","username":"ls"},{"password":"110","username":"ww"}]
String s = JSON.toJSONString(list);
System.out.println(s);
}
@Test
public void method04(){
//json格式字符串转java对象
String json = "{\"password\":\"123\",\"username\":\"ls\"}";
/*
ORM: object relationship mapping 对象关系映射
1. 体现: 一条数据映射成一个java对象
2. 原理: 反射
1). 首先解析json字符串,变成map
2). 然后遍历map
key 对应 value
username ls <-
password 123
3). 反射操作对象
// User类的Class对象
Class clazz = User.class;
// 使用User类的空参构造创建实例
User user = clazz.newInstance();
//获取类中方法
// 方法名的推断: set + map中的key
Method method = clazz.getMethod("setUsername",String.class);
//调用方法 user.setUsername("ls");
method.invoke(user,"ls")
*/
//User{username='ls', password='123'}
User user = JSON.parseObject(json, User.class);
System.out.println(user);
}
}
一般来说只要是属于对象的都可以使用JSON.toJSONString(对象);转化为json
是json的转化为对象可以 JSON.parseObject(json字符串,对象名.class),具体原理上边也有