servlet笔记---day03

servlet笔记—day03

监听器与过滤器

过滤器

在开发过程中经常使用,它可以过滤数据,和生活中的过滤器类似,例如自来水的过滤。过滤器主要过滤请求,当前端请求过来时,如果没有过滤器,直接进入服务器servlet中,加入过滤器,前端请求过来,先进入过滤器,过滤器过滤之后,才进入服务器。

使用场景:在编码格式转换时可以使用,前端可能存在编码格式不一样的情况,这时在过滤器拦截所有请求,然后进行转码

代码实现的过程:

1.需要类去实现filter接口,里面有三个方法init(),doFilter(),destroy()

2.在xml文件中配置过滤器或者注解的方式,或者直接创建Filter

配置过滤器在xml文件注册时,filter放在servlet上面,或者把dtd约束干掉

//xml
<filter>
  <filter-name>UserFilter</filter-name>
  <filter-class>com.zll.filter.UserFilter</filter-class>
  </filter>
  <filter-mapping>
  <filter-name>UserFilter</filter-name>
  <url-pattern>/*</url-pattern>   //*代表过滤所有
  </filter-mapping>
//注解的方式
@WebFilter(filterName="UserFilter",urlPatterns={"/*"})

注意:过滤器在tomcat容器启动时就已经启动,servlet在请求过来时启动,过滤器不仅要过滤请求,还要过滤响应。启动时,filter先启动,servlet后启动。过滤器的销毁在tomcat关闭的时候执行,servlet先关闭,filter后关闭。

过滤器的本质是一个回调函数的使用,过滤器的实现也就是通过回调函数来实现

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		System.out.println("进入到过滤的方法,可以过滤请求");
		String priv=request.getParameter("priv");
		System.out.println(priv);
		if(priv.equals("hb")) {
			response.getWriter().print("你是高风险地区人员,请原路返回");//后面的代码就不执行了
		}else {
			chain.doFilter(request, response);//继续往后走的方法
		}
	}

使用过滤器:前后端编码格式不一样,造成的乱码问题。

使用post方式乱吗,get方式不乱码

原因:编码和解码方式不一致

tomcat版本:8.5及以上版本

get请求方式,request对象使用的字符集默认为utf-8

post请求方式:request对象使用的编码方式为ISO8859-1

public class Filter01 implements Filter{
	String encoding=null;
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		System.out.println("过滤器被创建,初始化方法被调用");
		encoding=filterConfig.getInitParameter("encoding");//获取xml中的编码格式
		System.out.println(encoding);
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		if(encoding!=null) {
			request.setCharacterEncoding(encoding);
			response.setCharacterEncoding(encoding);
			response.setContentType("text/html;charset="+encoding);
		}
		chain.doFilter(request, response);
		
	}

	public void destroy() {
		// TODO Auto-generated method stub
		System.out.println("过滤器被销毁");
	}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("请求已进入servlet");
		String user=request.getParameter("user");
		String password=request.getParameter("password");
		System.out.println(user+"\t"+password);
	}
<filter>
  <filter-name>Filter01</filter-name>
  <filter-class>com.zll.filter.Filter01</filter-class>
  <!-- 初始化时创建一个变量encoding,后面就可以直接使用-->
  <init-param>
  <param-name>encoding</param-name>
  <param-value>utf-8</param-value>
  </init-param>
  
  </filter>
  <filter-mapping>
  <filter-name>Filter01</filter-name>
  <url-pattern>/*</url-pattern>
  </filter-mapping>

监听器

监听器其实也是一个类,里面有8大接口,实现哪个接口就监听哪个内容,会监听各种内容。当你想要使用哪个监听器,直接选择即可,或者实现它的接口,也会在xml文件中注册
在这里插入图片描述

监听器的核心是观察者模式(就是一种设计模式)。

监听器的接口不一样,生命周期也不一样。例如ServletContextListener在tomcat启动时监听,tomcat关闭时销毁。ServletRequestListener在请求发送过来时监听,请求结束时销毁。

监听器的实现方式:

1.xml文件

2.注解

3.直接创建

<listener>
  	<listener-class>com.zll.filter.UserListener</listener-class>
  </listener>
        ServletContext application=this.getServletContext();
		application.setAttribute("username", "zll");//添加
		application.setAttribute("username", "lxy");//修改
		application.removeAttribute("username");//移除
public class UserListener implements ServletContextListener,ServletContextAttributeListener {

    public UserListener() {
        // TODO Auto-generated constructor stub
    }

    public void contextDestroyed(ServletContextEvent sce)  { 
         // TODO Auto-generated method stub
    	System.out.println("listener销毁");
    }

    public void contextInitialized(ServletContextEvent sce)  { 
         // TODO Auto-generated method stub
    	System.out.println("启动了");
    }

	public void attributeAdded(ServletContextAttributeEvent event) {
		// TODO Auto-generated method stub
		System.out.println("application中添加内容时触发");
	}

	public void attributeRemoved(ServletContextAttributeEvent event) {
		// TODO Auto-generated method stub
		System.out.println("application中移除内容时触发");
	}

	public void attributeReplaced(ServletContextAttributeEvent event) {
		// TODO Auto-generated method stub
		System.out.println("application中修改内容时触发");
	}
}

MVC模型

把项目进行划分

V—view,视图层,主要进行页面的展示

C—controller(控制),把所有的请求进行控制,进入到不同的方法中去执行

M—model(持久层),能够对数据库金星操作的内容就是持久层,进行数据库的连接,以及数据库的各种操作,都在里面写。

软件开发的过程中,除了使用MVC模型外,还有:

1.表示层(视图层——view):通过html,jsp等把数据进行页面的展示。

2.控制层(controller层):接收数据,处理数据,返回数据

3.业务层(service):通过控制层,进入到业务中

4.持久层(dao层):具体的数据库的操作

String日期转换为date类型

String date1=request.getParameter("date");
SimpleDateFormat simpleDeteFormat=new SimpleDateFormat("yyyy-MM-dd");
Date date=simpleDeteFormat.parse(date1);

session

session与cookie都是用来记录用户的信息的,比如用户登录成功之后,就可以把数据写入到session中,以后登录时判断有没有你的用户信息,有就直接登录,没有就重新登录。

session是一次会话,当前浏览器不关闭就一直存在,但是session有默认超时时间,一般为30分钟。当时间到期时,session就清除

服务器端为了保存用户的状态而创建的一个特殊的对象(即session对象)。

当浏览器第一次访问服务器时,服务器会创建session对象(该对象有一个唯一的id,一般称之为sessionId),接下来服务器会将sessionId以cookie的方式发送给浏览器。当浏览器再次访问服务器时,会将sessionId发送过来,服务器就可以依据sessionId找到对应sessinon对象。

设置超时时间:

1.session.setMaxInactiveInterval(30*60);//秒数,30分钟

2.xml文件中(分钟数)

 <session-config>
            <session-timeout>120</session-timeout>
 </session-config>

删除session

session.invalidate();

session中的数据都是存储在服务器中,当服务器超时,会清除session,重启服务器时,也会清除session

session优点:可以放入的数据比较多,存储在服务器中,安全。在本地服务器是没有数据的。每次请求过来之后都会让服务器创建session,如果数据多了,服务器的压力会过大。

请求转发之后的内容还会继续执行,重定向后面的内容不会继续执行

session中的数据有时间限制,可以当做缓存来用

超时时间:(优先级从高到低)

1.java代码中设置

2.当前项目的web.xml中设置

3.tomcat中设置

@WebServlet("/OrderServlet")
public class OrderServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	req.setCharacterEncoding("utf-8");
	int id=Integer.valueOf(req.getParameter("id"));
	String name=req.getParameter("name");
	int number=Integer.valueOf(req.getParameter("number"));
	double price=Double.valueOf(req.getParameter("price"));
	Order order=new Order(id, name, number, price);
	HttpSession session=req.getSession();
	session.setAttribute("order", order);
	session.setMaxInactiveInterval(30);
	req.getRequestDispatcher("/GetOrderServlet").forward(req, resp);//请求转发后面的内容还会执行
	resp.sendRedirect("GetOrderServlet");//重定向之后的数据不会继续执行
	System.out.println("*************");
	}
@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doGet(req, resp);
	}
}
@WebServlet("/GetOrderServlet")
public class GetOrderServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	HttpSession session=req.getSession();
	Order order=(Order) session.getAttribute("order");
	System.out.println(order.getId()+"\t"+order.getName()+"\t"+order.getNumber()+"\t"+order.getPrice());
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	doGet(req, resp);
    }
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<center>
	<h1>外卖订单</h1>
	<form action="OrderServlet" method="post">
	订单编号:<input type="text" name="id">
	订单名称:<input type="text" name="name">
	订单数量:<input type="text" name="number">
	订单价格:<input type="text" name="price">
	<input type="submit">
	</form>
</center>
</body>
</html>
public class Order {
	private int id;
	private String name;
	private int number;
	private double price;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getNumber() {
		return number;
	}
	public void setNumber(int number) {
		this.number = number;
	}
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
	public Order(int id, String name, int number, double price) {
		super();
		this.id = id;
		this.name = name;
		this.number = number;
		this.price = price;
	}
	public Order() {
		super();
	}
}

cookie

cookie和服务器有关系,它返回的sessionid是存储在cookie中的,但是把数据存储在客户端的浏览器中,它占用浏览器的空间,它的信息都在本地存储。cookie的功能类似于生活中的会员卡。

当浏览器访问服务器的时候,服务器会产生一个sessionid,这个sessionid就是我们存储会话的时候的那个id, 同时他也会把这个sesssionid发到客户端上,客户端把serssionid 存储到cookies里,当你下一次请求的时候,浏览器会带着这个sessionid 往上走。服务就会对比这个id,如果有就进行相关的操作。

类似我们在日常生活中使用的用户登录,用户登录判断是在服务端进行判断,返回一个sessionid给客户端浏览器中存储cookies, 过几天你又带着你的sessionid 到你的服务器,就可以直接登录。如果你换了机器,sessionid是没有的,需要你进行重新登录。

@WebServlet("/CookieServlet")
public class CookieServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("text/html");
		String uname=req.getParameter("uname");
		String password=req.getParameter("password");
		String ck=req.getParameter("ck");
		System.out.println(uname+"\t"+password+"\t"+ck);
		if("on".equals(ck)) {//记住密码被选中,写入数据到cookie
			Cookie cookie=new Cookie("users",uname+"--"+password);
			cookie.setMaxAge(60);//秒
			resp.addCookie(cookie);
		}
		
	}
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doGet(req, resp);
	}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
    
 <%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<%
String names="";
String pwd="";
//取出Cookie
Cookie [] c=request.getCookies();
for(int i=0;i<c.length;i++){
    if(c[i].getName().equals("users")){
        //存着数据(用户名+密码)
        names=c[i].getValue().split("--")[0];
        pwd=c[i].getValue().split("--")[1];
        
        //再一次的存起来(备用)
        request.setAttribute("xiaoming",names);
        request.setAttribute("mima", pwd);
    }
}
%>   
    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <form action="CookieServlet" method="post">
        用户名:<input type="text" name="uname" id="uname"  value=${xingming }><br>
        密码:<input type="password" name="password" id="password" value=${mima }><br>
    <input type="checkbox" name="ck">记住用户名和密码<br>
    <input type="submit" value="登录">
    </form>
  </body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值