【web基础】servlet进阶
2018-02-21 12:02
190 查看
1.过滤器
Servlet和JSP中的过滤器都是Java类,它们存在的目的如下:在请求访问后端资源时拦截它
管理从服务器返回给客户端的响应
常用的过滤器类型:
认证过滤器
数据压缩过滤器
加密过滤器
触发资源访问事件的过滤器
图像转换过滤器
登录和验证过滤器
MIME类型链过滤器
令牌过滤器
转换XML内容的XSL/T过滤器
过滤器将会被插入进web.xml文件中,然后映射servlet、JSP文件的名字,或URL模式
当JSP容器启动网络应用程序时,它会创建每一个过滤器的实例,这些过滤器必须在部署描述文件web.xml中声明,并且按声明的顺序执行。
Servlet过滤器方法
一个过滤器就是一个Java类,它实现了javax.servlet.Filter 接口。
javax.servlet.Filter接口定义了三个方法:
public void doFilter (ServletRequest, ServletResponse, FilterChain)
每当 request/response要通过过滤链时容器会调用这个方法,因为客户端请求链尾的资源
public void init(FilterConfig filterConfig)
容器调用这个方法来表明一个过滤器被安置在服务中
public void destroy()
容器调用这个方法来表明一个过滤器正在从服务中移除
过滤器示例
类似servlet写法,这里只示例注解实现了
package com.huawei.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebFilter(filterName = "FirstFilter", urlPatterns = "/*") public class FirstFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { System.out.println("Filter starts..."); HttpServletRequest request = (HttpServletRequest) req; H 4000 ttpServletResponse response = (HttpServletResponse) resp; resp.setContentType("text/html;charset=utf-8"); PrintWriter out = resp.getWriter(); if(1!=1){ out.println("IP is illegal"); }else{ out.println("Ip is 合法"); chain.doFilter(req, resp); } } public void init(FilterConfig config) throws ServletException { System.out.print("初始化filter..."); } }
多个过滤器应用顺序
在web.xml中元素的映射顺序决定了容器应用这些过滤器的顺序。要反转应用的顺序,您只需要反转web.xml中元素的定义顺序就行了。
2.监听器
什么是监听器servlet规范当中一个特殊的类,可以监听容器中产生的一些事件并做相应的处理。Listener 对应观察者模式,事件发生的时候会自动触发该事件对应的Listeer。Listener 主要用于对 Session、request、context 进行监控。
8种监听器可以分为三类:
第一大类:监听 Session、request、context 的创建与销毁
HttpSessionLister、ServletContextListener、ServletRequestListener
第二大类:监听对象属性变化
HttpSessionAttributeLister、ServletContextAttributeListener、ServletRequestAttributeListener
第三大类:监听Session 内的对象
HttpSessionBindingListener、HttpSessionActivationListener
与上面六类不同,这两类 Listener 监听的是Session 内的对象,而非 Session 本身,不需要在 web.xml中配置
监听器加载顺序
启动服务器->监听器->过滤器->servlet
Web服务器按照web.XML中注册顺序来加载Servlet事件监听器
Web应用程序中只会为每个事件监听器类创建一个实例对象,在编程中可能出现多个线程同时调用一个事件监听器的情况,要注意监听器对象共享同步问题。
监听器的实现
<!--wweb.xml配置--> <!--一般放在servlet之前--> <listener> <listener-class>com.huawei.listener.FirstListener</listener-class> </listener>
下面用注解方式写
package com.huawei.listener; import javax.servlet.*; import javax.servlet.annotation.WebListener; import javax.servlet.http.*; @WebListener() public class FirstListener implements ServletContextListener, HttpSessionListener,ServletRequestListener { public FirstListener() { } //加载context public void contextInitialized(ServletContextEvent sce) { ServletContext servletContext = sce.getServletContext(); System.out.println("即将启动"+servletContext.getContextPath()); } //写在context public void contextDestroyed(ServletContextEvent sce) { ServletContext servletContext = sce.getServletContext(); System.out.println("即将关闭"+servletContext.getContextPath()); } //创建session public void sessionCreated(HttpSessionEvent se) { HttpSession session = se.getSession(); System.out.println("新创建一个session"+session.getId()); } //销毁session public void sessionDestroyed(HttpSessionEvent se) { HttpSession session = se.getSession(); System.out.println("销毁一个session"+session.getId()); } //创建request public void requestInitialized(ServletRequestEvent req){ HttpServletRequest request = (HttpServletRequest) req.getServletRequest(); String uri = request.getRequestURI(); uri = request.getQueryString() == null ? uri : (uri + "?" + request.getQueryString()); request.setAttribute("dateCreated", System.currentTimeMillis()); System.out.println("IP " + request.getRemoteAddr() + " 请求 " + uri); } //销毁request public void requestDestroyed(ServletRequestEvent req){ HttpServletRequest request = (HttpServletRequest) req.getServletRequest(); long time = System.currentTimeMillis() - (Long) request.getAttribute("dateCreated"); System.out.println(request.getRemoteAddr() + "请求处理结束, 用时" + time + "毫秒. "); } }
3.AJAX
什么是AJAXAJAX = Asynchronous Javascript And Xml(异步的JavaScript和xml)
是一种用于改善用户体验度的技术,实质上是利用浏览器内置对象 (XMLHttpRequest,一般称为ajax对象)向服务器发送异步请求,服务器接收到请求之后处理数据,处理完之后,返回结果,浏览器利用这结果数据部分更新页面,整个过程当中,页面无刷新,不会打断用户的操作。
AJAX对象在向服务器发送请求时,浏览器不会销毁当前页面,用户可以在页面中继续其他的操作
创建XMLHttpRequest对象——ajax基础
<script> var xhr; if(window.XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject("Microsoft.XMLHTTP"); } </script>
原生js实现ajax
方法 | 描述 |
---|---|
open(method,url,async) | 规定请求的类型、URL 以及是否异步处理请求。 ● method:请求的类型; ● GET 或 POST url:文件在服务器上的位置 ● async:true(异步)或 false(同步) |
setRequestHeader(header,value) | 向请求添加 HTTP 头。 ● header: 规定头的名称 ● value: 规定头的值 |
send(string) send() | 将请求发送到服务器。 ● string:仅用于POST请求 |
GET 还是 POST?
与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。然而,在以下情况中,请使用 POST 请求:无法使用缓存文件(更新服务器上的文件或数据库)
向服务器发送大量数据(POST 没有数据量限制)
发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
下面是 XMLHttpRequest 对象的三个重要的属性:
属性 | 描述 |
---|---|
onreadystatechange | 存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。 |
readyState | 存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。 0: 请求未初始化 1: 服务器连接已建立 2: 请求已接收 3: 请求处理中 4: 请求已完成,且响应已就绪 |
status | 200: "OK" 404: 未找到页面 |
<script type="text/javascript"> //get异步请求 function change(v1){ var xhr = getXhr(); //添加随机数避免浏览器调用缓存不刷新 xhr.open("get","tajax?t="+Math.random(),true); xhr.onreadystatechange = function(){ if(xhr.readyState==4){ var map = xhr.responseText; document.getElementById("div1").innerHTML = map; } } xhr.send(); } //post异步请求 function testajax() { var postData = {"name1":"value1","name2":"value2"}; xhr.open("post","tajax",true); //这个就照着写吧0.0,设置http消息头 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xhr.onreadystatechange = function () { if(xhr.readyState == 4){ var map = xhr.responseText; document.getElementById("div1").innerHTML = map; } } xhr.send(postData); } </script>
jQuery堆ajax的支持
$.ajax(options); options:是一些键值对{key:value,ke:value},其中的回调函数的入参也是可选的 url:请求地址 type:请求方式get/post data:请求参数 "username=zs&age=10" {"username":"zs","age":10} dataType:服务器返回的数据类型 html,text,xml,js,json等 success:请求成功回调函数 function(data,textStatus){ data:服务器返回的数据 textStaus:服务器返回的状态 } error:请求失败回调函数 function(xhr,e){ xhr:ajax对象 e:服务器返回的状态 }
$.ajax({ "url":"loadCourse.do", "cache":false, "type":"post", "dataType":"json", "success":function(data){ for(i=0;i<data.length;i++){ var c = data[i]; var $a = $("<a href='javascript:;' id='"+c.id+"'>"+c.courseName+"</a>"); $a.click(clickCourse); $("#course").append($a); $("#course").append(" "); } $("#course").children('a').first().trigger('click'); }, "error":function(){ alert("错误"); } });
4.servlet线程安全问题
servlet线程安全问题产生的原因在默认的情况下,容器只会为每一个servlet类创建唯一的一个实例,当请求到达容器时,就有可能有多个线程同时访问同一个实例。
如何解决
加锁(可以对整个service方法加锁,也可以对某一个代码块加锁。建议使用后者。)
让servlet实现SingleThreadModle接口容器会为该servlet创建多个servlet对象,每启动一个线程为其分配一个servlet对象。
servlet属性尽量设置成可读的,不要去修改。final
相关文章推荐
- Java Web基础知识之Servlet容器初始化(无web.xml)
- Java Web基础知识之Servlet(2):深入Servlet——HttpServlet
- WEB_基础_servlet工作原理_待
- Javaweb基础_servlet开发(一)
- JAVA基础(三) web.xml 中的listener、 filter、servlet 加载顺序及其详解
- Java Web基础:第七讲 Servlet运行原理
- 10005---JavaWeb基础--HttpServletRequest
- Web基础之Servlet深入
- javaweb_关于Servlet一些基础知识笔记
- JSP&Servlet学习笔记(1)Web开发基础理论
- Servlet基础---- web.xml配置
- 电商之梳理servlet知识---javaweb基础
- tomcat javaweb开发基础(10servlet(3))
- [Java拾遗四]JavaWeb基础之Servlet_Request&&Response
- JavaWeb基础—HttpServletResponse
- Web前端基础(七):CSS选择器进阶
- JavaWeb基础知识点之Servlet
- Java Web基础知识之Servlet(1):初识Servlet
- Servlet基础知识(二)——web.xml文件的作用
- javaweb基础学习(一)<ServletConfig与ServletContext对象详解>