`
qepipnu
  • 浏览: 74785 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论
阅读更多
Servlet JSP
配置tomcat:
Tomcat有zip包和exe版,本配置针对非安装zip包使用:
1 在myEclipse中加载Tomcat

2 选择tomcat的安装路径,并选择服务器Enable此时会在myEclipse中多一个图标

3选择tomcat对于的jdk


4 启动Tomcat


5 添加一个J2EE的配置工程


每次修改web.xml后重新配置tomcat

Web-inf 站点内容 web.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
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_2_5.xsd">
 
  <servlet>
  <!-- name写的只自己命名的一个servlet,可以不是那个servlet类名 -->
<servlet-name>MyServlet</servlet-name>
<!-- servletd类名,注意加上完整的包名 -->
    <servlet-class>ServletDemo</servlet-class>
  </servlet>
<servlet-mapping>
  <!-- name写的只自己命名的一个servlet,可以不是那个servlet类名 ,注意与上面的要一致-->
    <servlet-name>MyServlet</servlet-name>
     <!--这是一个虚拟路径 -->
    <url-pattern>/Servlet/web</url-pattern>
</servlet-mapping>
<welcome-file-list>
  <!-- 这里放的是页面html,包括具体的路径,这个顺序是文件在-->
  <!-- 当用http://127.0.0.1:8080/html(html是该项目名称)打开时 -->
  <!-- 将会出现下面的第一个html的界面 -->
    <welcome-file>right.html</welcome-file>
    <welcome-file>Form.html</welcome-file>
  </welcome-file-list>
</web-app>
Lib:存放所以的包文件
Class存放所有的类文件
配置tomcat环境,启动在bin,配置在config





















Servlet做好配置,本身是一个基本java类,只有再继承了httpservlet才能称为servlet,这样才有可能响应页面的请求(比如接受页面数据)

Response可以想象为通向页面的一个socket,可以通过其方法获得一些IO流
 Servlet中访问报头
 HTTP报头,提交请求和服务器向客户端做出响应时 ,浏览器和服务器都会再请求和响应后自动添加的一些附加信息,这些附加信息称之为报头,这些都是浏览器自动附加上去的,用户并不知道!
 报头分类
 请求报头
 应用:反爬虫系统:首先查看报头信息,比如User-Agent(请求的浏览器或者其他客户程序),如果能够识别某些报头那么则是正常的浏览器访问,否则就是爬虫来获得信息,予以制止。
 应用:国际化使用:对于不同的范围浏览器给予不同的反映页面,这是可以获得accept-lanugae,通过判断这个语言从而给于不同的反映。
 响应报头
 如何设置编码和解码格式;request.setcharactset()…..
 CGI变量
 它是传统的CGI编程中常用的,汇集了各种信息,如来自于HTTP命令和请求头,Socket本身等的信息。
 Request.get…( )方法
 Servlet生命周期(servlet是单例的,并且是多线程并发)
 第一次被访问时:
 产生实例(调用构造函数)
 初始化(调用init函数)
 然后自动调用service()方法,并去执行doget或者dopost方法
 我们可以重写这些方法,已获得自己的一些效果。。。。。这些方法都由tomcat自动调用。。。。
 以后被访问时:
 以后同一个实例启动多个线程执行用户操作(首先调用service函数,然后由service函数根据请
 求类型决定调用doGet函数或doPost函数)
 这时多个并发线程共享servelet的成员变量,因此对于这样的数据注意使用线程锁。
 站台被重新部署等时候,调用destroy函数或者Tomcat关机的时候关闭
 配套的HTML文件
 JSP
 Jsp机制
 所有JSP页面,在执行的时候都会被服务器端的JSP引擎转换为Servelet(.java),然后又由JSP引擎调用Java编译器,将Servelet(.java)编译为Class文件(.class),并由Java虚拟机(JVM)解释执行。同时在%CATALINA_HOME%\work\Catalina\localhost下多出两个文件:_Test_jsp.java和_Test_jsp.class,他们分别就是Servelet和Class文件。
 然后由Servlet产生HTML页面传回客户端以供显示
 在D:\tomcat6\work\Catalina\localhost路径下可以看到被tomcat解释的java文件
 JSP组成:
 声明:
 <%!     %>中间的部分。
 这里申明的变量,将成为Jsp生成的对应的类的成员变量
 这里申明的函数,将成为Jsp生成的对应的类的成员函数
 JSP执行
 <%     %>中间的部分。
 这里的代码会在Jsp页面显示的同时被执行,如同写在main函数里的代码一样。
 JSP表达式
 <%=   %>中间的部分
 取得某个变量的值。
 在页面显示部分直接使用表达式,即为直接显示某个变量的值。
 JSP注释
 两种注释方式:
 <%-- 客户端的源码看 不 见我 --%>
 <!-- 客户端的源码看 得 见我 -->
 俗称:在Html里写Java代码
<%@ page language="java" import="java.util.Date" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  </head>
 
  <body>
      <%-- 这是JSP注释 ,好像不能嵌套啊! --%>
      <%-- 这时JSP申明部分 --%>
    <%!
  String myDate = null;
  String path = null;
  String basePath = null;
  void getDate(){
  Date  my = new Date();
  this.myDate = my.toLocaleString();
  }
    %>
    <%--这是JSP执行部分 --%>
    <%
       this.getDate();
    %>
        欢迎光临,今天是:<%= this.myDate %><br>
  </body>
</html>
在IE上直接运行:http://127.0.0.1:8080/项目名/**.jsp即可

08.12.23  JSP高级应用  Jsp和Servlet联合应用 web高级应用
 JSP高级应用
 Jsp指令-page
 <%@ page import="java.util.*" %>
 <%@ page session=”false" %>
 <%@ page errorPage=”error.jsp" %>
 JSP指令 - page的错误处理方案
 解决办法
 在可能发生异常的页面添加
 <%@ page errorPage="error.jsp" %>
 在显示错误信息的页面添加
 <%@ page isErrorPage="true" %>
 在显示错误信息的页面获取异常
 通过JSP的隐含exception直接获得异常(这里的exception是jsp的内置对象)象征着从其他页面传递过来的异常实例。
 <%
    String e = exception.getMessage();
 %>
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%-- 异常错误重定向 --%>
<%@ page errorPage="./Error.jsp" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>   
    <title>My JSP 'index.jsp' starting page</title>
  </head>
    <body>
    <%!
       int i;
       int j;
     %>
     <%
        i = 0;
        j = 7/i;
      %>
  </body>
</html>
Error.jsp
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%@ page isErrorPage = "true" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>   
   
    <title>My JSP 'Error.jsp' starting page</title>   

  </head>
 
  <body>
    <%
      String msg = exception.getMessage();
     %>
  </body>
</html>
 JSP指令 - include
 功能:嵌入外部页面,用来把子页面引入母页面
 <%@ include file="head.jsp" %>
 应用:一个jsp放框架模板,而其他的jsp放一些具体内容,则可以在框架jsp中用include引入其他的内容jsp即可实现复杂的页面。
 <a href = “#”> 这里的#表示当前页面
 这样一个页面就由三个人处理,而这三个人都可以分开处理:首先由模板工程师定义模板,由美工通过css来处理,内容由内容工程师自行完成,并通过include指令加载到框架中。
 JSP动作 - include
 功能:嵌入外部页面,实现的效果和jsp的include指令一致。
 <jsp:include flush="true" page="head.jsp"  / >
 JSP动作 - forward
 功能:跳转到其他页面
 <jsp:forward page="welcome.jsp" />
 使用:目前是一种过期技术,用处不大,在早期使用较多。
 JSP动作 - param
 功能:在跳转的页面间传递数据
 <jsp:forward page="welcome.jsp">
     <jsp:param name="user_name" value="Eric"/>
 </jsp:forward>
 JSTL
 引入:一个jsp含有html标签,也有java代码,让谁来维护呢?如果不想增加谁的负担,解决办法是:在jsp页面只实现一些逻辑顺序,并且把java的一些逻辑用类似于xml的标签的形式表达,这样美工易于理解和掌握。
 JSP 标准标记库(JSP Standard Tag Library,JSTL)是一个实现 Web 应用程序中常见的通用功能的定制标记库集,这些功能包括迭代和条件判断、数据管理格式化、XML 操作以及数据库访问。
 具体而言就是能实现一些java的操作,但是有不出现真正的java代码,而是用一些标签来表示java的操作。
 但是目前在表现层又不使用:访问数据库,解析xml这些功能了,放到后面的持久层等。目前已被后面的东东标记库所逐渐替代。
 JSTL的意义
 为了方便网页设计师,他们即使没有学过Java,也可以轻松处理应用程序数据。
 主要功能:
 访问存储对象
 简化JavaBean的访问方式
 对集合的简化访问
 简单运算符
 条件输出
 JSP与Servlet联合
 JSP的隐含对象
 Request(当前人当前请求的线程)
 session(针对某个具体客户使用,所以的线程使用,比如判断某人是否登陆)
 exception
 Application(针对任何人,任何线程共享使用,比如网站浏览计数)
 Page
 Out
 Out:直接应用在jsp页面中(<% out.();%>),往页面输出数据。
 JSP(表现层)与Servlet(控制层)间数据传递
 从JSP到Servlet
 从JSP发送数据:
 通过form提交,一旦一个form被submit则数据自动从jsp传递到Servlet中
 在Servlet中接收数据:
 String userName = request.getParameter( "userName" );
 “userName”为Jsp中form对应的标签的name属性
 从Servlet到JSP
 要主动的在Servlet中传,要在jsp中主动的去接受数据。
 从Servlet发送数据:
 // 将数据作为attribute存入request中
 request.setAttribute( "user_name", userName );//这里的user_name仅仅是一个标记
 // 跳转到指定页面并传递数据
 RequestDispatcher rd = request.getRequestDispatcher( "../shu_ju_chuan_di/Welcome.jsp" );
 rd.forward( request, response );
 这两语句仅仅是进行保存,等全部语句执行完毕后,Servlet就会检查post是否有保存东西和foword东西,如果有就进行重定向,因此在一个forward后面不要再有其他的forward方法了。
 再次注意:requset里的保存和重定向得到的数据都是单线程使用的,不能被其他线程共享。如果要实现多个线程中数据的共享需要使用application对象。
 在JSP中接收数据:
 String userName = ( String )request.getAttribute( "user_name" );
 //这个user_name就是前面的setAttribute中的标记。
 session
 访问范围
 当前客户的所有组件
 请参照配套登录实例
 用同一个浏览器多次访问
 用不同浏览其多次访问
 HttpSession se = request.getSession();
 Se.setAttribute();
 application
 访问范围
 这是一个全局单例共享空间
 服务器上所有组件
 请参照配套登录实例
 用同一个浏览器多次访问
 用不同浏览其多次访问
 在servlet中用:ServletContext application = this.getServletContext()
 在jsp中用application

 Web中文显示问题
 解决页面显示中文问题
 <%@ page language="java" import="java.util.*" pageEncoding=“UTF-8"%>
 解决request传递中文问题
 request.setCharacterEncoding( "UTF-8" );
 在接受数据之前使用上述语句
 并且页面表单使用form中的post方法,而不用get方法,使用get时其提交的信息会出现在IE中,需要进行特殊的处理才能正常显示中文。
 JSP动态显示table方案
WebDemoServlet.java
import java.io.IOException;
import java.util.Hashtable;
import java.util.Map;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class WebDemoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
//准备接受数据,为了实现中文传递,向先定义解码方式
request.setCharacterEncoding("UTF-8");
//如果是发送的话,那么也要设置其字符格式
resp.setCharacterEncoding("UTF-8");
//通过 request.getParameter()方法接受数据,
//下面方法中的"userName"对于表单中的文本框的名字
String userName = request.getParameter("userName");
String passWord = request.getParameter("passWord");
//以上就是从jsp中得到的各个数据,可以直接打印处理
System.out.println(userName + "-" + passWord);

//下面的部分实现将从Jsp读来的数据发送到另外一个Jsp页面中去
//第一步:将数据作为attribute存入request中
//下面的语句表示将userName保存在代号为USER_NAME的requset中
request.setAttribute("USER_NAME", userName);
request.setAttribute("PASSWORD", passWord);

//下面练习关于session的使用,使用范围是当前客户的所有组件,这是系统通过
//关于http报头和CGI变量来识别的
HttpSession  hs =  request.getSession();
//下面这句话和requset类似,就是把username保存到一个session里面,这个
//session的名字是"USER_NAME_SESSION",这样在其他的jsp里面就可以用到这个session的值了
//似乎这种数据的保存方式有点像Map
hs.setAttribute("USER_NAME_SESSION", userName);

//下面是关于全局变量application的使用
//因为用到的是全局变量,因此用到this,这里也不是直接说applicaton,而是context
ServletContext sc = this.getServletContext();
//这里的count用来计数,并且表面值为0
sc.setAttribute("COUNT", 0);

//下面演示动态table的形成,其实这表达了jsp编程的灵活性,
//对此的理解关键是要知道jsp的机制,其是被tomcat翻译成一个Servlet,
Map<String,Integer> list = new Hashtable<String,Integer>();
list.put("zheng", 25);
list.put("zhu", 25);
list.put("ma", 26);
//将这个数据用reques传递到jsp中去
request.setAttribute("LIST", list);
//采用request进行数据传递的时候一定要把他放到跳转的页面的前面。跳转到哪里,就到哪里去接受!

//第二步:跳转到指定页面并传递数据,制定转到当前路径的reslult.jsp文件中
//注意在使用相对路径的时候,这里的相对指得是Servlet与要转向的文件之间的相对性

RequestDispatcher rd = request.getRequestDispatcher("../Result.jsp");
rd.forward(request, resp);
}
}
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
   
    <title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">   
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
  </head>
 
  <body>
    <!-- 下面通过表单实现从Jsp向Servlet进行数据传递,主要是通过request -->
    <!-- 当选择submit时,自动的将表单的各个数据向Servlet发送 -->
    <h2 >用户登陆</h2>
    <form action = "./Servlet/web" method = "post">
    请输入用户名:
    <input type = "text" name ="userName" ><br>
    请输入密码:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <input type = "password" name ="passWord" ><br><br><br>
    <input type = "submit" value = 确认>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <input type = "reset" value = 重写>
    </form>
  </body>
</html>
Result.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>     
    <title>My JSP 'Result.jsp' starting page</title>   
  </head> 
  <body>
     <%!
         String userName;
         int count;
      %>
    <%
    userName = (String)request.getAttribute("USER_NAME");
    String passWord = (String)request.getAttribute("PASSWORD");
    %>
    用户名为:<%= userName %><br><!-- 这是jsp表达式 -->
    密码为:<% out.print(passWord); %><!-- 这是jsp的执行部分 -->
    采用session的方式得到用户名为:<br>
    <%
    userName = (String)session.getAttribute("USER_NAME_SESSION");
    out.println(userName);
    %>
    <%
count =(Integer) application.getAttribute("COUNT");
count++;
out.println("您是第" +count +"人访问该网站");
application.setAttribute("COUNT",count);
   
    %>
    <br>
    下面的部分接受Servlet传来的数据,并进行动态的表格打印
    <table border = 1>
    <tr>
    <th>姓名</th>
    <th>年龄</th>
    </tr>
    <%
       Hashtable<String,Integer> list =(Hashtable<String,Integer>) request.getAttribute("LIST");
       Set<String > nameSet = list.keySet();
       for(String name:nameSet){
       int age = list.get(name);
      %>
      <tr>
      <td>
      <%= name %>
       </td>
       <td>
       <%= age %>      
       </td>
       </tr>
          <%
          }
          %>   
    </table>
  </body>
</html>
SessionTest.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>  
    <title>My JSP 'SessionTest.jsp' starting page</title>
   </head>
 
  <body>
    <%!
       String userName;
       int count;
     %>
      <%
      userName = (String )session.getAttribute("USER_NAME_SESSION");
      out.println("这是第二个浏览器访问的情况,但是可以用同一个session<br>");
      out.println("用户名为:" + userName);
      %>
      <br>
       <%
count =(Integer) application.getAttribute("COUNT");
count++;
out.println("您是第" +count +"人访问该网站");
application.setAttribute("COUNT",count);
%>

  </body>
</html>
堆栈和队列容器的实现
容器 保存(堆栈,队列),最大长度,为空(等待再来拿,类似池的概念),多个堆栈,多个队列

类加载: 第一:如果要new一个子类,则JVM会先new一个父类(调用其默认构造器)。
    第二:如果父类没有默认构造器(无参构造器)那么子类必须明确的用super来指明调用父类的那个构造器。

注意系统的结构良好性:可重用!,可读性好!(利用继承和多态减少代码的重复)
项目实施过程:功能(一期工程),安全(二期工程),性能(三期工程)
内核(关键的东西)+外壳(相当于一个工厂):这样可以降低模块之间的耦合度,提高模块的独立性,可以任意修改内核的东西,而不会影响外壳的东西。

Container.java
package container;
/**
* 这是一个容器类的父类,该容器主要是为了实现队列,堆栈等存储方式
* @author
*
*/
import java.util.List;
import java.util.Vector;
import util.DataManager;
public  class Container{
//容器的最大容量
protected int containerSize;
//当存入数据时的最大尝试次数
protected int popRetryTime;
//当存入数据时的每次尝试等待时间
protected int popWaitTime;
//当读数据时的最大尝试次数
protected int pushRetryTime;
//当读数据时的每次尝试等待时间
protected int pushWaitTime;
private String curContainerType;

//这里用了Vector主要是考虑线程安全的问题
public List dataList = new Vector();

//构造函数,因为后面的队列和堆栈都要传递参数,因此写在父类的构造器里面
//以免代码重复
public Container(int containerSize,int popRetryTime,int popWaitTime,int pushRetryTime,int pushWaitTime,String containerType){
this.containerSize = containerSize;
this.popRetryTime = popRetryTime;
this.popWaitTime = popWaitTime;
this.pushRetryTime = pushRetryTime;
this.pushWaitTime = pushWaitTime;
this.curContainerType = containerType;
}

/**
* 读取数据的方法 ,并且根据不同的容器类型,采用不同的读方法
* @return
* @throws Exception
*/
public Object pop()throws Exception {
Object data =null ;
data = DataManager.waitForPop(this,0);
return data;
}

/**
* 插入数据方法
* @author
*/
public void push(Object data)throws Exception {
// TODO Auto-generated method stub
DataManager.waitForPush(this, 0, data);
}

public int getLength(){
return dataList.size();
}

/**
* 判断容器是否为空
* @return 如果为空则返回true,否则返回false
* @author
*/
public boolean isEmpty(){
int length = dataList.size();
if (length <= 0){
return true;
}
return false;
}

/**
* 判断容器是否为满,
* @return 如果为满则返回true,否则返回false
* @author
*/
public boolean isFull(){
if(this.containerSize ==-1){
return false;
}
if(this.containerSize <= this.dataList.size()){
return true;
}
return false;
}
public int getPopRetryTime() {
return popRetryTime;
}
public int getPopWaitTime() {
return popWaitTime;
}
public int getPushRetryTime() {
return pushRetryTime;
}
public int getPushWaitTime() {
return pushWaitTime;
}
public String getCurContainerType() {
return curContainerType;
}
}
DataManager.java
/**
*
* 这是一个工具类,主要实现了对容器中的数据插入和获取操作,
* 其关键点在于能够根据用户的需要进行等待或不等待
* @author
*
*/
import container.Container;
public class DataManager {

/**
* 等待获取数据方法,
* @param container 待获取的容器
* @param ct  要获取的容器的类型
* @param curRetryTime  当前尝试获取的次数
* @return  返回的获取数据
* @throws Exception 不能获取时抛出异常
* @author
*/
public static Object waitForPop (Container container,int curRetryTime) throws Exception {
Object data;
int indexData = 0;
//不为空的话直接取值
if(!container.isEmpty()){
if(container.getCurContainerType().equals("stack")){
indexData = container.getLength()-1;
}else if(container.getCurContainerType().equals("queue")){
indexData = 0;
}else if(container.getCurContainerType().equals("random")){
indexData = (int)(Math.random()*container.getLength());
}
data = container.dataList.get(indexData);
container.dataList.remove(indexData);
return data;
}
//为空的话,等待,再测试是否能够拿到,并且要判断是否需要无穷等待
if(container.getPopRetryTime()>-1){
if(curRetryTime >= container.getPopRetryTime()){
throw new Exception("容器为空,请稍候再试!");
}else{
curRetryTime++;
}
}
Thread.sleep(container.getPopWaitTime());
return waitForPop (container,curRetryTime);
}
/**
* 插入数据的方法
* @param container 待插入的容器
* @param curRetryTime 以尝试插入的次数
* @param data 待插入的数据
* @throws Exception  不能插入时抛出异常
* @author
*/
public static void waitForPush(Container container,int curRetryTime,Object data)throws Exception{

//判断容器是否已满,如果不满的话则直接添加进去
if(!container.isFull()){
container.dataList.add(data);
return ;
}
//如果容器满的话,等待,再测试是否能够插入,并且要判断是否需要无穷等待
if(container.getPushRetryTime()>-1){
if(curRetryTime >= container.getPushRetryTime()){
throw new Exception("容器已满,请稍候再试!");
}else{
curRetryTime++;
}
}
//等待片刻
Thread.sleep(container.getPushWaitTime());

waitForPush(container,curRetryTime,data);
}
}
XMLUtil.java
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
/**
* 本类主要实现对xml文件的解析
* @author hp
*
*/
public class XMLUtil {

/**
* 根据制定的配置文件xml构建一棵DOM数,并返回改树的根节点
* @param filePath
* @return
* @throws Exception
* @author
*/
public static  Element getDOMTree(String filePath)throws Exception {
//取得DOM树
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(filePath);
Element root = doc.getDocumentElement();
return root;
}

/**
* 取得已知节点某属性的值
* @param Element
* @param String
* @return
* @author
*/
public static String getAttributeOfElement(Element e,String type){
return e.getAttribute(type);
}

/**
* 本方法只适用于每个标记中只有一个相同类型的子标记的情况,直接读取其文本值
* @param parent 父标记
* @param childType  子标记值
* @return 
* @author
*/
public static String getTextValueOfElement(Element parent,String childType){
NodeList childList = parent.getElementsByTagName(childType);
Element curElement = (Element) childList.item(0);
String childValue ;
//这里主要进行处理,保证能够独到数据,如果读不到数据,则赋值为空
try{
childValue = curElement.getFirstChild().getNodeValue().toString();
}catch(NullPointerException n){
childValue = "";
}
return childValue;

}
}
TaoZhi.java
import java.util.Hashtable;
import java.util.Map;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import util.XMLUtil;
import container.Container;
public class TaoZhi {

Map<String,Container> containerList = new Hashtable<String,Container>();
   
/**
* 对配置文件的解析方法,并生成相应的容器实例
* @param configFilePath
* @param containerType
* @throws Exception
* @author
*/
public void parse(String configFilePath,String containerType) throws Exception{
//得到DOM树的根节点
Element root = XMLUtil.getDOMTree(configFilePath);
//得到子节点
NodeList containerTypeList = root.getElementsByTagName(containerType);
//遍历该节点列表,为不同ID的节点进行实例化操作
for(int i = 0 ; i< containerTypeList.getLength() ; i++ ){
Element curElement = (Element)containerTypeList.item( i );
//得到该节点的ID
String id = curElement.getAttribute("id");
//String id = XMLUtil.getAttributeOfElement(curElement, "id");
//取得该节点下各个子节点的值
int  containerSize = Integer.valueOf( XMLUtil.getTextValueOfElement(curElement, "containerSize"));
int  popRetryTime = Integer.valueOf( XMLUtil.getTextValueOfElement(curElement, "popRetryTime"));
int  popWaitTime = Integer.valueOf( XMLUtil.getTextValueOfElement(curElement, "popWaitTime"));
int  pushRetryTime = Integer.valueOf( XMLUtil.getTextValueOfElement(curElement, "pushRetryTime"));
int  pushWaitTime = Integer.valueOf( XMLUtil.getTextValueOfElement(curElement, "pushWaitTime"));

Container curContainer = new Container(containerSize,popRetryTime,popWaitTime,pushRetryTime,pushWaitTime,containerType);

//下面的判断表示,如果存在重复的ID则不能使用
if(containerList.get(id) == null && curContainer !=null){
containerList.put(id, curContainer);
}else{
System.out.println("不能存在重复的ID或者配置文件设置有误,请修改配置文件");
}
}
}
/**
* 构造器,实现对配置文件的解析,将生成的容器加入到容器列表
* @param configFilePath
* @throws Exception
* @author
*/
public TaoZhi(String configFilePath) throws Exception{
//解析配置文件,并开始构造对象实例
this.parse(configFilePath,"stack");
this.parse(configFilePath,"queue");
this.parse(configFilePath,"random");
}

/**
* 获取数据
* @param ID 要获取数据的容器的id号
* @return 返回获取的数据
* @throws Exception 如果找不到数据,抛出异常
* @author
*/
public Object pop(String ID) throws Exception{
Object data;
Container curContainer = this.containerList.get(ID);
if( curContainer == null){
throw new Exception("您要取数据的容器不存在!请重新设定ID号!");
}else{
data = curContainer.pop();
}
return data;
}

/**
* 往容器插入数据
* @param ID  要插入的容器号
* @param data 要插入的数据
* @throws Exception
* @author
*/
public void push(String ID,Object data)throws Exception{
Container curContainer = this.containerList.get(ID);
if( curContainer == null){
throw new Exception("您要插入的容器不存在!请重新设定ID号!");
}else{
curContainer.push(data);
}
}
/**
* @param args
*/
public static void main(String[] args) throws Exception{
TaoZhi tz = new TaoZhi("./config.xml");
tz.push("1", 1);
tz.push("1", 2);
tz.push("1", 3);
System.out.println(tz.pop("1"));
System.out.println(tz.pop("5"));
System.out.println(tz.pop("1"));
}
}
上午 Servlet 中的Filter & Listener…
 Servlet监听器
 在web应用中响应特定对象的特定事件,这样就比较方便的控制application,session,request对象发生的特定事件,实现对特定事件的集中处理。
 Servlet监听器用于监听一些重要事件的发生,监听器对象可以在事情发生前、发生后可以做一些必要的处理。
 分类及介绍:(红色表示重要)
 1、ServletContextListener:用于监听WEB 应用启动和销毁的事件,监听器类需要实现javax.servlet.ServletContextListener 接口。
 这个其实就是对于application应用对象。

 2.  ServletContextAttributeListener:用于监听WEB应用属性改变的事件,包括:增加属性、删除属性、修改属性,监听器类需要实现javax.servlet.ServletContextAttributeListener接口。
 3.  HttpSessionListener:用于监听Session对象的创建和销毁,监听器类需要实现javax.servlet.http.HttpSessionListener接口或者javax.servlet.http.HttpSessionActivationListener接口,或者两个都实现。
 配置文件如下:
 <listener> <listener-class>类名</ listener-class ></ listener >
 4.  HttpSessionActivationListener:用于监听Session对象的钝化/活化事件,监听器类需要实现javax.servlet.http.HttpSessionListener接口或者javax.servlet.http.HttpSessionActivationListener接口,或者两个都实现。
 5.  HttpSessionAttributeListener:用于监听Session对象属性的改变事件,监听器类需要实现javax.servlet.http.HttpSessionAttributeListener接口。该接口要实现的方法,和对于的触发事件如下:
   
统计在线人数的时候应该用实现HttpSessionListener接口,也就是当一个用户来到是,实现创建一个session对象,从而计数一次。而上面的触发事件是不同的,表示一个Attribute增加一个就触发一次。
 部署:
 监听器的部署在web.xml文件中配置
 过滤器

1.1 什么是过滤器
  过滤器是一个程序,它先于与之相关的servlet或JSP页面运行在服务器上。过滤器可附加到一个或多个servlet或JSP页面上,并且可以检查进入这些资源的请求信息。在这之后,过滤器可以作如下的选择:
  ①以常规的方式调用资源(即,调用servlet或JSP页面)。
  ②利用修改过的请求信息调用资源。
  ③调用资源,但在发送响应到客户机前对其进行修改。
  ④阻止该资源调用,代之以转到其他的资源,返回一个特定的状态代码或生成替换输出。
 1.2 Servlet过滤器的基本原理
  在Servlet作为过滤器使用时,它可以对客户的请求进行处理。处理完成后,它会交给下一个过滤器处理,这样,客户的请求在过滤链里逐个处理,直到请求发送到目标为止。例如,某网站里有提交“修改的注册信息”的网页,当用户填写完修改信息并提交后,服务器在进行处理时需要做两项工作:判断客户端的会话是否有效;对提交的数据进行统一编码。这两项工作可以在由两个过滤器组成的过滤链里进行处理。当过滤器处理成功后,把提交的数据发送到最终目标;如果过滤器处理不成功,将把视图派发到指定的错误页面。
2.Servlet过滤器开发步骤
  开发Servlet过滤器的步骤如下:
  ①编写实现Filter接口的Servlet类。
  ②在web.xml中配置Filter。

上面中的/*表示对所有的信息过滤。
  开发一个过滤器需要实现Filter接口,Filter接口定义了以下方法:
  ①destory()由Web容器调用,初始化此Filter。
  ②init(FilterConfig filterConfig)由Web容器调用,初始化此Filter。
  ③doFilter(ServletRequest request,ServletResponse response,FilterChain chain)具体过滤处理代码。
FilterChain 的作用是:FilterChain是servlet容器提供给开发者的一个对象,用于资源请求调用的一个链表(可以参考CoR模式)!   过滤器使用FilterChain(过滤器链表)来调用链表里的下一个过滤器!调用完链表里最后一个过滤器以后,再继续调用其它的资源。    doFilter:(没有返回值)   如果过滤器链表里没有其它过滤器的话,这个过滤链的调用就会转到其它资源的调用。   FilterChain是由容器来管理的!
也是就是说多个过滤器会形成一个链结构,且就是通过这个FilterChain来实现转发嘚。
 常用:权限管理,字符过滤等等
分享到:
| XML
评论

相关推荐

Global site tag (gtag.js) - Google Analytics