XML
DTD
语法自成一派, 早起就出现的。 可读性比较差。
- 引入网络上的DTD
- 引入本地的DTD
- 直接在XML里面嵌入DTD的约束规则
<!DOCTYPE stus [
<!ELEMENT stus (stu)>
<!ELEMENT stu (name,age)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
]>
<!ELEMENT stus (stu)> : stus 下面有一个元素 stu , 但是只有一个
<!ELEMENT stu (name , age)> stu下面有两个元素 name ,age 顺序必须name-age
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ATTLIST stu id CDATA #IMPLIED> stu有一个属性 文本类型, 该属性可有可无
元素的个数:
+ 一个或多个
* 零个或多个
? 零个或一个
属性的类型定义
PCDATA : 属性是普通文字
ID : 属性的值必须唯一
<!ELEMENT stu (name , age)> 按照顺序来
<!ELEMENT stu (name | age)> 两个中只能包含一个子元素
约束的引入方式:
<!DOCTYPE stus SYSTEM "stus.dtd" >
<!DOCTYPE stus PUBLIC "stus.dtd" >
xml的约束
1. DTD约束 :文档内约束、本地系统引入、网络引入
2. Schema约束
意义:约束xml元素的书写规范,保证数据的安全性和有效性
用java 解析 xml
Schema
其实就是一个xml , 使用xml的语法规则, xml解析器解析起来比较方便 , 是为了替代DTD 。
但是Schema 约束文本内容比DTD的内容还要多。 所以目前也没有真正意义上的替代DTD
约束文档:
<!-- xmlns : xml namespace : 名称空间 / 命名空间
targetNamespace : 目标名称空间 。 下面定义的那些元素都与这个名称空间绑定上。
elementFormDefault : 元素的格式化情况。 -->
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.whxh.com/teacher"
elementFormDefault="qualified">
<element name="teachers">
<complexType>
<sequence maxOccurs="unbounded">
<!-- 这是一个复杂元素 -->
<element name="teacher">
<complexType>
<sequence>
<!-- 以下两个是简单元素 -->
<element name="name" type="string"></element>
<element name="age" type="int"></element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
实例文档:
<?xml version="1.0" encoding="UTF-8"?>
<!-- xmlns:xsi : 这里必须是这样的写法,也就是这个值已经固定了。
xmlns : 这里是名称空间,也固定了,写的是schema里面的顶部目标名称空间
xsi:schemaLocation : 有两段: 前半段是名称空间,也是目标空间的值 , 后面是约束文档的路径。
-->
<teachers
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.whxh.com/teacher"
xsi:schemaLocation="http://www.whxh.com/teacher teacher.xsd"
>
<teacher>
<name>zhangsan</name>
<age>19</age>
</teacher>
<teacher>
<name>lisi</name>
<age>29</age>
</teacher>
<teacher>
<name>lisi</name
<age>29</age>
</teacher>
</teachers>
XML 解析
DOM
SAX
针对这两种解析方式的API
一些组织或者公司, 针对以上两种解析方式, 给出的解决方案有哪些?
jaxp sun公司。 比较繁琐
jdom
dom4j 使用比较广泛
Dom4j 基本用法
element.element("stu") : 返回该元素下的第一个stu元素
element.elements(); 返回该元素下的所有子元素。
- 创建SaxReader对象
- 指定解析的xml
- 获取根元素。
- 根据根元素获取子元素或者下面的子孙元素
- try {
- //1. 创建sax读取对象
- SAXReader reader = new SAXReader(); //jdbc -- classloader
- //2. 指定解析的xml源
- Document document = reader.read(new File("src/xml/stus.xml"));
- //3. 得到元素、
- //得到根元素
- Element rootElement= document.getRootElement();
- //获取根元素下面的子元素 age
- //rootElement.element("age")
- //System.out.println(rootElement.element("stu").element("age").getText());
- //获取根元素下面的所有子元素 。 stu元素
- List<Element> elements = rootElement.elements();
- //遍历所有的stu元素
- for (Element element : elements) {
- //获取stu元素下面的name元素
- String name = element.element("name").getText();
- String age = element.element("age").getText();
- String address = element.element("address").getText();
- System.out.println("name="+name+"==age+"+age+"==address="+address);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
SaxReader 创建好对象 。
Document Element
- 看文档
- 记住关键字 。
- 有对象先点一下。
- 看一下方法的返回值。
- 根据平时的积累。 getXXX setXXX
Dom4j 的 Xpath使用
dom4j里面支持Xpath的写法。 xpath其实是xml的路径语言,支持我们在解析xml的时候,能够快速的定位到具体的某一个元素。
- 添加jar包依赖
jaxen-1.1-beta-6.jar
- 在查找指定节点的时候,根据XPath语法规则来查找
- 后续的代码与以前的解析代码一样。
- //要想使用Xpath, 还得添加支持的jar 获取的是第一个 只返回一个。
- Element nameElement = (Element) rootElement.selectSingleNode("//name");
- System.out.println(nameElement.getText());
- System.out.println("----------------");
- //获取文档里面的所有name元素
- List<Element> list = rootElement.selectNodes("//name");
- for (Element element : list) {
- System.out.println(element.getText());
- }
Cookie
应用场景
自动登录、浏览记录、购物车。
为什么要有这个Cookie
http的请求是无状态。 客户端与服务器在通讯的时候,是无状态的,其实就是客户端在第二次来访的时候,服务器根本就不知道这个客户端以前有没有来访问过。 为了更好的用户体验,更好的交互 [自动登录],其实从公司层面讲,就是为了更好的收集用户习惯[大数据].
Cookie怎么用
- 添加Cookie给客户端
- 在响应的时候,添加cookie
Cookie cookie = new Cookie("aa", "bb");
//给响应,添加一个cookie
response.addCookie(cookie);
2.客户端收到的信息里面,响应头中多了一个字段 Set-Cookie
3.获取客户端带过来的Cookie
示例
在浏览器客户端存入用户名和密码
设置cookie
@WebServlet(urlPatterns = "/setCookie")//注册service
public class SetCookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String uname = req.getParameter("uname");
String pwd = req.getParameter("pwd");
// 1.创建一个Cookie实例
Cookie cookie = new Cookie("loginUser",uname+"#"+pwd);
// cookie的相关api
cookie.setMaxAge(3600); //设置cookie的时效性:int expiry负数(表示浏览器已关闭则cookie失效) 正数(表示保持的有效性时间s 60*60*24*7) 0(清除cookie)
// cookie.setDomain("www.lxyk.com"); // 设置cookie的访问域名
// cookie.setPath("/setCookie"); // 设置cookie只有在访问该路径时有效
// cookie.setValue("fgh,pwd"); // 设置或修改cookie中的值
resp.addCookie(cookie);//response.addCookie(c);添加cookie到服务器端,发送给浏览器
resp.setContentType("text/html;charset=utf8");
resp.getWriter().write("<h3><font color='red'>服务器添加cookie成功!!</font></h3>");
}
}
获取cookie
工具类:
public class CookieUtil {
public static Cookie findCookie(Cookie[] cookies, String loginUser) {
if (cookies==null||loginUser==null||"".equals(loginUser)){
return null;
}
//遍历拿到的cookie并拿到所需要的cookie
//cookie.getName():得到此cookie对象的名字
//忽略大小写比较
for (Cookie ck:cookies) {
if (loginUser.equalsIgnoreCase(ck.getName())){
return ck;
}
}
return null;
}
}
@WebServlet(urlPatterns = "/getCookie")
public class GetCookieSevrlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取客户端请求过来的带有的cookie信息
Cookie[] cookies = req.getCookies();
//遍历这个cookies并且从中找到所需要的cookie,CookieUtil是工具类
Cookie loginUser = CookieUtil.findCookie(cookies, "loginUser");
System.out.println(loginUser.getName() + "::" + loginUser.getValue());
}
}
启动tomacat
案例:显示最经访问的时间
- 判断账号是否正确
- 如果正确,则获取cookie。 但是得到的cookie是一个数组, 我们要从数组里面找到我们想要的对象。
- 如果找到的对象为空,表明是第一次登录。那么要添加cookie
- 如果找到的对象不为空, 表明不是第一次登录。
前端页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
form{
text-align: center;
margin: 50px auto;
border: 3px solid red;
width: 450px;
height: 300px;
}
h3{
text-align: center;
}
p:nth-of-type(1){
margin-top: 86px;
}
</style>
</head>
<body>
<h3>登陆页面</h3>
<!-- 在tomcat中配置访问项目的路径时你带了项目名称,而这里/test访问是根路径为参照的-->
<form action="/loginCookie" method="post">
<p>用户名:<input type="text" name="uname" /> </p>
<p>密 码:<input type="password" name="pwd" /> </p>
<p><input type="submit" value="登录" /></p>
</form>>
</body>
</html>
cookie类具体实现
@WebServlet(urlPatterns = "/loginCookie")
public class LoginCookie extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//思路 将本次登陆的时间记录在cookie中 下次登陆的时候从cookie中获取上次登陆的时间并将本次登陆的时间再次存入cookie中
Cookie[] cookies = req.getCookies();
Cookie findCookie = CookieUtil.findCookie(cookies, "last_login");
if (findCookie == null) {//找不到最后登录的cookie证明是第一次登录
String curr=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
Cookie c=new Cookie("last_login",curr);
c.setMaxAge(3600);
resp.addCookie(c);
resp.setContentType("text/html;charset=utf8");
resp.getWriter().write("<h3><font color='blue'>您是第一次登陆</font></h3>");
}else{//用户上次登录过,在客户端已经有了记录登录的cookie信息
String lastTime=findCookie.getValue();//获取上次的登陆时间
String currl=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
findCookie.setValue(currl);
findCookie.setMaxAge(3600);
resp.addCookie(findCookie);
resp.setContentType("text/html;charset=utf8");
resp.getWriter().write("<h3><font color='blue'>您上次登陆的时间是:"+lastTime+"</font></h3>");
}
}
}
启动tomacat 报错:java.lang.IllegalArgumentException: Cookie值中存在无效字符[32]
解决办法j在tomcat的根目录的conf目录context.xml加上下面的代码即可解决问题
<!-- 解决Cookie中不允许出现非法字符-->
<CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" />
Cookie总结
-
什么是cookie
HTTP协议本身是无状态的。什么是无状态呢,即服务器无法判断用户身份。Cookie实际上是一小段的文本信息(key-value格式)。客户端向服务器发起请求,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。
打个比方,我们去银行办理储蓄业务,第一次给你办了张银行卡,里面存放了身份证、密码、手机等个人信息。当你下次再来这个银行时,银行机器能识别你的卡,从而能够直接办理业务。
-
cookie机制
当用户第一次访问并登陆一个网站的时候,cookie的设置以及发送会经历以下4个步骤:
客户端发送一个请求到服务器 --> 服务器发送一个HttpResponse响应到客户端,其中包含Set-Cookie的头部 --> 客户端保存cookie,之后向服务器发送请求时,HttpRequest请求中会包含一个Cookie的头部 -->服务器返回响应数据
Session
会话 , Session是基于Cookie的一种会话机制。 Cookie是服务器返回一小份数据给客户端,并且存放在客户端上。 Session是,数据存放在服务器端。
Cookie JSESSIONID=sessionid
- 常用API
//得到会话ID
String id = session.getId();
//存值
session.setAttribute(name, value);
//取值
session.getAttribute(name);
//移除值
session.removeAttribute(name);
// 判断会话是否是一次新的会话 :true,表示建立新的会话;false,表示维持之前的会
boolean isnew = session.isNew();
Session何时创建 , 何时销毁?
Cookie的安全问题。
由于Cookie会保存在客户端上,所以有安全隐患问题。 还有一个问题, Cookie的大小与个数有限制。 为了解决这个问题 ---> Session .
什么是Session?
服务器为了保存用户状态而创建的一个特殊的对象。
当浏览器第一次访问服务器时,服务器创建一个session对象(该对象有一个唯一的id,一般称之为sessionId),服务器会将sessionId以cookie的方式发送给浏览器。当浏览器再次访问服务器时,会将sessionId发送过来,服务器依据sessionId就可以找到对应的session对象。
2)如何获得session对象?
方式一 HttpSession s = request.getSession(boolean flag);
方式二 HttpSession s = request.getSession();
购物车案例
前端页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>商品列表页面</h3>
<p><a href="cartServlet?pid=0">红米note7</a> </p>
<p><a href="cartServlet?pid=1">华为7</a> </p>
<p><a href="cartServlet?pid=2">苹果7</a> </p>
<p><a href="cartServlet?pid=3">魅族7</a> </p>
</body>
</html>
servlet
@WebServlet(urlPatterns = "/cartServlet")
public class cartServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**
* 将前端页面提交过来的商品加入到购物车中存储起来
* 设计一个购物车(容器-->集合(商品名称,商品数量))Map<String,Integer>
* 可以考虑将购物车存入到Session中,这样子在各个页面都可以获取到
*/
/**
* 获取商品pid
*/
String pid=req.getParameter("pid");
String[] products={"红米note7","华为7","苹果7","魅族7"};
/**
* 获取Session中的购物车
* 没有(第一次购物)创建一个购物车Map<String,Integer>
* 有:开始存入购物车
* 购物车中有此商品 数量+1
* 购物车中没有此商品 数量=1
* 将添加了商品的购物车再次存入session
*/
//创建session
HttpSession session= req.getSession();
//获取购物车
Map<String,Integer> cart=(Map<String, Integer>) session.getAttribute("cart");
int index=Integer.parseInt(pid);
String pName =products[index];
//第一次
if (cart==null){
cart=new LinkedHashMap<>();
cart.put(pName,1);
}else {
//判断有没有此商品
if (cart.containsKey(pName)){
cart.put(pName,cart.get(pName+1));
}else {
cart.put(pName,1);
}
}
/**
* 跳转到中间页面等待下一步客户端的用户的处理
*/
resp.setContentType("text/html;charset=utf8");
PrintWriter out= resp.getWriter();
out.write("<h3><font><a href='/product.html'>继续购物</a></font></h3>");
out.write("<h3><font><a href='/cart.jsp'>去购物车结算</a></font></h3>");
}
}
Filter
一、Filter简介
Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,如下所示:
Filter生命周期
1、Filter接口中三个重要的方法
init()方法:初始化参数,在创建Filter时自动调用,当我们需要设置初始化参数的时候,可以写到该方法中。
doFilter()方法:拦截到要执行的请求时,doFilter就会执行。这里面写我们对请求和响应的预处理
destory()方法:在销毁Filter时自动调用
Filter对象 - FilterConfig
用户在配置filter时,可以使用<init-param>为filter配置一些初始化参数,当web容器实例化Filter对象,调用其init方法时,会把封装filter初始化参数的FilterConfig对象传递进来。
通过filterConfig对象的方法,可以获得:
String getFilterName():得到filter名称
String getInitParameter(String name):返回在部署描述中指定名称的初始化参数的值,如果不存在返回null
Enumeration getInitParameterNames():返回过滤器的所有初始化参数的名称的枚举集合
public ServletContext getServletContext():返回Servlet上下文对象的引用
用户在配置filter时,可以使用<init-param>为filter配置一些初始化参数,当web容器实例化Filter对象,调用其init方法时,会把封装filter初始化参数的FilterConfig对象传递进来。
通过filterConfig对象的方法,可以获得:
String getFilterName():得到filter名称
String getInitParameter(String name):返回在部署描述中指定名称的初始化参数的值,如果不存在返回null
Enumeration getInitParameterNames():返回过滤器的所有初始化参数的名称的枚举集合
public ServletContext getServletContext():返回Servlet上下文对象的引用
过滤器链 - FilterChain
一组过滤器对某些web资源进行拦截,那么这组过滤器就成为过滤链。过滤器的执行顺序和<filter-mapping>有关
举例(非注解方式)
需要web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<welcome-file-list>
<welcome-file>login.html</welcome-file>
</welcome-file-list>
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>fiter.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>
</web-app>
注解方式
/**
* 定义一个编码过滤器:对所有的请求进行编码拦截处理
*/
@WebFilter(urlPatterns = "/*",initParams = {@WebInitParam(name = "encoding",value = "utf8")})
public class CharacterEncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println(" CharacterEncodingFilter被创建了");
}
/**
*
* @param servletRequest:请求对象
* @param servletResponse:响应对象
* @param filterChain:过滤器链
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("CharacterEncodingFilter执行了编码拦截");
HttpServletRequest request= (HttpServletRequest) servletRequest;
HttpServletResponse response= (HttpServletResponse) servletResponse;
//request中的中文编码
//使用包装模式解决中文乱码的请求对象
MyRequest myRequest=new MyRequest(request);
//过滤器链放行请求和响应对象
filterChain.doFilter(myRequest,response);
}
@Override
public void destroy() {
System.out.println(" CharacterEncodingFilter被销毁了");
}
}
/**
* 包装代理类
*/
class MyRequest extends HttpServletRequestWrapper{
private HttpServletRequest request;
private boolean hasEcode;
public MyRequest(HttpServletRequest request) {
super(request);
this.request=request;
}
@Override
public Map<String, String[]> getParameterMap() {
String method = request.getMethod();
try {
if ("post".equalsIgnoreCase(method)){
request.setCharacterEncoding("utf8");
return request.getParameterMap();
}else if ("get".equalsIgnoreCase(method)) {
if (!hasEcode) {
//获取中文乱码问题中的数据
Map<String, String[]> pmap = request.getParameterMap();
//对请求的键值对数据中的值进行手动转码
Collection<String[]> values = pmap.values();
for (String[] vals : values) {
for (int i = 0; i < vals.length; i++) {
vals[i] = new String(vals[i].getBytes("iso-8859-1"), "utf8");
}
}
}
hasEcode=true;
return request.getParameterMap();
}else { return super.getParameterMap();
}
}catch (UnsupportedEncodingException e){
e.printStackTrace();
}
return null;
}
@Override
public String getParameter(String name) {
String[] vals = this.getParameterMap().get(name);
if (vals == null) {
return null;
}
return vals[0];
}
@Override
public String[] getParameterValues(String name) {
return this.getParameterMap().get(name);
}
}
前端页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
form{
text-align: center;
margin: 50px auto;
border: 3px solid red;
width: 450px;
height: 300px;
}
h3{
text-align: center;
}
p:nth-of-type(1){
margin-top: 86px;
}
</style>
</head>
<body>
<h3>登陆页面</h3>
<!-- 在tomcat中配置访问项目的路径时你带了项目名称,而这里/test访问是根路径为参照的-->
<form action="/loginCookie" method="post">
<p>用户名:<input type="text" name="uname" /> </p>
<p>密 码:<input type="password" name="pwd" /> </p>
<p><input type="submit" value="登录" /></p>
</form>>
</body>
</html>
若是有多个Filter则按字典顺序排序
若是用的xml注册则按照注册顺序排序
@WebFilter(urlPatterns = "/*",filterName = "a")
public class FilterA implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("FilterA be执行了拦截请求");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("FilterA af执行了拦截请求");
}
@Override
public void destroy() {
}
}
启动tomacat
Listener
监听器
1.能做什么事?
监听某一个事件的发生。 状态的改变。
监听器就是监听某个对象的的状态变化的组件
监听器的相关概念:
事件源:被监听的对象 ----- 三个域对象 request session servletContext
servletContext:
1. 是一个域对象
2. 可以读取全局配置参数
3. 可以搜索当前工程目录下面的资源文件
4. 可以获取当前工程名字(了解)
监听器:监听事件源对象 事件源对象的状态的变化都会触发监听器 ---- 6+2
注册监听器:将监听器与事件源进行绑定
响应行为:监听器监听到事件源的状态变化时 所涉及的功能代码 ---- 程序员编写代 码
2.监听器有哪些?
第一维度:按照被监听的对象划分:ServletRequest域 HttpSession域 ServletContext域
第二维度:监听的内容分:监听域对象的创建与销毁的 监听域对象的属性变 化的
Web监听器
总共有8个 划分成三种类型
- 定义一个类,实现接口
- 注册 | 配置监听器
/**
* 三域生死监听器
* 在恰当的时机出发对应域的函数,程序员就可以在该函数中去做相应的业务逻辑
*/
public class MyServletListener implements ServletRequestListener, HttpSessionListener, ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("contextScope init listening");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("contextScope destroy listening");
}
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("requestScope init listening");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("requestScope init listening");
}
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
HttpSession session = httpSessionEvent.getSession();
System.out.println("requestScopr created listening"+session.getId());
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
}
}
使用过滤器和监听器完成统计访问登陆app的用户的IP和访问的次数案例
前端页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div style="text-align: center;width: 300px;margin: 50px auto">
<a href="/test/countServlet">点击查看成功登录的次数</a>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>错误页面</title>
</head>
<body>
<h3 style="color: red;text-align: center">错误页面</h3>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
form{
text-align: center;
margin: 50px auto;
border: 3px solid red;
width: 450px;
height: 300px;
}
h3{
text-align: center;
}
p:nth-of-type(1){
margin-top: 86px;
}
</style>
</head>
<body>
<h3>登陆页面</h3>
<!-- 在tomcat中配置访问项目的路径时你带了项目名称,而这里/test访问是根路径为参照的-->
<form action="/test/longinServlet" method="post">
<p>用户名:<input type="text" name="uname" /> </p>
<p>密 码:<input type="password" name="pwd" /> </p>
<p><input type="submit" value="登录" /></p>
</form>>
</body>
</html>
实现类
@WebServlet(urlPatterns = "/test/longinServlet",initParams = @WebInitParam(name = "count",value = "0"))
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求过来的用户名和密码数据
String uname = req.getParameter("uname");
String pwd = req.getParameter("pwd");
/**
* user=service>dao>db
*
*/
ServletContext sc = req.getServletContext();
if ("abcde".equals(uname)&&"123456".equals(pwd)){
//成功登录,计数
//int count=Integer.parseInt(this.getServletConfig().getInitParameter("count"));
//count++;
Object count = sc.getAttribute("count");
if (count==null){
sc.setAttribute("count",1);
}else {
sc.setAttribute("count",(Integer)count+1);
}
resp.sendRedirect(sc.getContextPath()+"/html/count.html");
}else {
//错误
resp.sendRedirect(sc.getContextPath()+"/html/error.html");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
@WebServlet(urlPatterns = "/test/countServlet")
public class countServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取登陆成功的次数
ServletContext sc = req.getServletContext();
int count = (Integer) sc.getAttribute("count");
PrintWriter out = resp.getWriter();
resp.setContentType("text/html;charset=utf8");
out.write("<h3><font color='blue'>longin sucess"+count+"times!!</font></h3>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}