J2EE

$1 Servlet

![image-20220523152958194]

1.1 Servlet 的基本概念

Servlet是运行在服务器上面用于生成动态web页面的程序

1.1.1 Servlet编程

​ 基本关系:

servlet为一个结构,通过GenericServlet或者HttpServlet实现

/*Servlet接口中的函数
ServletConfig:用于保存Servlet实例中配置信息
ServletContext:提供有关的容器信息
*/
public void init(ServletConfig config) throws ServeletException;
public void service(ServeletRequest req,ServletResponese res) throws ServletException,IOException;
public void destroy();
public ServletConfig getServletConfig();
public String getServletInfo();  //包含servlet信息
/*GenericServlet*/
/*
该类对于Servlet接口中的大多数方法进行了实现,但是在service方法中的设置为abstract,所以该方法为一个抽象类,对于一个程序,我们只需要实现其service方法就可以对于一个用户的请求进行处理并且返回对应的响应
*/
/*HttpServlet*/
/*
该类对于GenericServlet进行了集成,并且对于servlet提供的接口进行了HTTP实现,对service方法作为了分发器!!!!任何时候不可重载
*/
/*常用方法doGet(),doPost(),doHead(),doOptions(),doDelete(),doPut(),doTrace()*/
public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException,ServeletException;
/*实例*/
package Hello;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * Servlet implementation class HelloWorld
 */
public class HelloWorld extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter o=response.getWriter();
        o.println("<html>");
        o.println("<body>");
        o.println("<head>");
        o.println("<title>Hello World</title>");
        o.println("</head>");
        o.println("<body>");
        o.println("<h1>Hello World!</h1>");
        o.println("</body>");
        o.println("</html>");
    }
}

注意:对于上面的import部分以及异常处理,在eclipse或者其他IDE中可以直接通过建立一个servlet来导入

1.1.2 Servlet生命周期

实例化->init()->service()->destroy->销毁实例

对于多线程问题,可以采用synchronized来定义service(doGet)方法,从而使用队列处理

1.1.3 Servlet部署描述符

web.xml保存在/WEB-INF下,用于保存servlet的基本部署信息

servlet对应的class文件保存在/web-inf/classes中

<servlet>
    <servlet-name>填写名字</servlet-name>
    <servlet-class>对应的类名(要加入包名)</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>对应上面的name</servlet-name>
    <url-pattern>映射到的网址</url-pattern>
</servlet-mapping>

1.1.4 ServletContext

定义了一系列方法用于Servlet通信,且每个JVM中的web-app中只有一个ServletContext

作用:

  1. 域对象
  2. 读取全局配置参数
  3. 搜索当前工程目录下的资源文件
/*ServletContext的应用*/
ServletContext context=this.getServletContext();
/*域对象*/
context.getAttribute(name);
context.setAttribute(name,value);
context.removeAttribute(name);

/*读取全局配置参数*/
context.getInitParameter(name);//根据指定的参数名获取参数值
context.getInitParameterNames();//获取所有参数名称列表

/*路径获取*/
context.getResourcePaths();

1.2 过滤器

Servlet过滤器可以检查和修改ServletRequest和ServletResponse对象

1.2.1 基本信息

作用:

  1. 查询请求并作出行为
  2. 阻塞请求响应对,使其不能进一步传递
  3. 修改请求头部和数据
  4. 修改响应头部和数据
  5. 与外界资源进行交互

适用场合:

  1. 认证过滤
  2. 登录和审核过滤
  3. 图像转换过滤
  4. 数据压缩过滤
  5. 加密过滤
  6. 资源访问触发事件过滤

1.2.2 编程步骤

编程步骤:

  1. 建立一个实现Filter接口的类
  2. 在doFilter方法中实现过滤行为
  3. 调用FilterChain对象中的doFilter方法
  4. 对相应的Servlet和JSP页面注册过滤器
  5. 禁用激活器servlet
/*设定过滤器处理所有的请求和响应的文本编码*/
package Filter;

import jakarta.servlet.http.HttpFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import jakarta.servlet.*;

/**
 * Servlet Filter implementation class MyFilter
 */
public class MyFilter extends HttpFilter {

    private static final long serialVersionUID = 1L;

    public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("gb2312");
        response.setContentType("text/html;utf-8");
        chain.doFilter(request, response);//可以理解为过滤链,用于处理过滤
    }
}

Servlet和Jsp的注册

<filter>
    <filter-name>过滤器名字</filter-name>
    <filter-class>对应的过滤器类</filter-class>
</filter>
<filter-mapping>
    <filter-name>过滤器名字(对应)</filter-name>
    <url-pattern>过滤路径</url-pattern>
    <servlet-name>指定servlet过滤</servlet-name>
</filter-mapping>

1.3 会话

1.3.1 会话与会话管理

会话是指一个用户在客户端登录,为达到某个目的与服务器端多次交互最后退出应用系统的全过程(个人理解为每个人访问到浏览器关闭相关网页的过程)

会话机制:

  1. 一个web容器必须支持HTTP协议
  2. 会话HTTP为无状态协议
  3. 需要一种服务器端的机制维持会话状态信息
  4. 服务器使用散列表(Hash)来保存信息

会话过程:

  1. 客户端发送会话表示
  2. 会话识别过程
  3. 会话状态保存和获取
  4. 会话识别发送给客户端

1.3.2 会话追踪机制

  1. Cookies
  2. SSL Session
  3. URL重写
  4. 表单隐藏
  • Cookies:引擎将用户ID保存在cookie中,发送该cookie到客户端,客户端将会在以后的请求中把这个cookie返回客户端(保存在windows的AppData文件夹下面,并且采用二进制形式无法被直接打开)
  • SSL Sessions:采用HTTPS协议,非规范要求Servlet必须协议
  • URL重写:将Session id写入URL中,URL会被解析为与某个Session相连

例如:

http://www.myservlet.com/index.html?jsessionid=1234
  • 表单隐藏:利用HTML中的hidden属性,将表单字段传入服务器
<input type="hidden" name="user id" value=15>

1.3.3 会话编程

/*创建会话*/
HttpSession session=request.getSession(true);  
//这里如果使用false就会调用一个已经有的会话
/*储存和访问会话属性*/
session.setAttribute(String s,Object o);
session.getAttribute(String s);
/*关闭会话*/
HttpSession.invalidate();
HttpSession.setInactiveInterval(int second);  //设置超时时间,如果为负值用不超时

1.3.4 实例

/*购物车的例子*/
HttpSession session=request.getSession();
ShoppingCart cart;
synchronized(session){
    cart = (ShoppingCart)session.getAttribute("shop");
    if(cart==null){
        cart=new ShoppingCart();
        session.setAttribute("shop",cart);
    }
}

1.4 事件监听

1.4.1 事件的分类和Listener接口

  • Application级别事件

    • servlet
    • Context
  • Session级别事件(Http)
事件种类事件描述接口
Context生命周期改变context建立与关闭ServletContextListener
Context属性值改变添加,删除,修改context属性ServletContextAttributeListener
Session生命周期改变Session创建,销毁和超时HttpSessionListener
Session属性值改变添加,删除,修改Session属性值HttpSessionAttributeListener
  • ServletContext事件
事件类型接口方法
创建Servlet上下文ServletContextListenercontextInitialized()
关闭Servlet上下文ServletContextListenercontextDestroyed()
添加特性ServletContextAttributeListenerattributeAdded()
删除特性ServletContextAttributeListenerattributeRemoved()
替换特性ServletContextAttributeListenerattributeReplaced()
  • Http会话事件
事件类型接口方法
激活HTTP会话HttpSessionListenersessionCreated()
即将钝化HTTP会话HttpSessionListenersessionDestroyed()
添加特性HttpSessionAttributeListenerattributeAdded()
删除特性HttpSessionAttributeListenerattributeRemoved()
替换特性HttpSessionAttributeListenerattributeReplaced()

1.4.2 事件监听器编程

  • 实现上述的接口之一
  • 创建不含任何参数的公共构造方法(默认构造器,如果重写了必须要写一个不带参的构造器)
  • 编写对应的方法函数

例如:

package myApp;
import jakarta.Servlet.*;
public final class MySessionAttributeListenerClass implements HttpSessionAttributeListener{
    public void attributeAdded(HttpSessionBindingEvent sbe){
        /*当添加属性时调用该方法*/
    }
    public void attributeRemoved(HttpSessionBinding){
        /*当删除属性时调用该方法*/
    }
}

监听器部署:

<listener>
    <listener-class>监听器类名</listener-class>
</listener>

1.4.3 例子

监听器实现对于网站在线人数的实时监控

package Listener;


import java.util.Enumeration;

import org.apache.jasper.compiler.NewlineReductionServletWriter;
import org.apache.tomcat.util.security.PrivilegedSetAccessControlContext;

import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletContextAttributeEvent;
import jakarta.servlet.ServletContextAttributeListener;
import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.http.HttpSession;
import jakarta.servlet.http.HttpSessionContext;
import jakarta.servlet.http.HttpSessionEvent;
import jakarta.servlet.http.HttpSessionListener;

/**
 * Application Lifecycle Listener implementation class OnLineCountListener
 *
 */
public class OnLineCountListener implements HttpSessionListener, ServletContextAttributeListener, ServletContextListener {
    private int count;
    private ServletContext context=null;
    private void log(String message) {
        System.out.println("ContextListener:"+message);
    }
    public OnLineCountListener() {
        count=0;
    }
    public void contextInitialized(ServletContextEvent event) {
        this.context=event.getServletContext();
    }
    public void setContext(HttpSessionEvent se) {
        se.getSession().getServletContext().setAttribute("onLine", new Integer(count));
        
    }
    public void sessionCreated(HttpSessionEvent se) {
        count++;
        setContext(se);
    }
    public void sessionDestroyed(HttpSessionEvent se) {
        count--;
        setContext(se);
    }
    public void attributeAdded(ServletContextAttributeEvent event) {
        log("attributeAdded("+event.getName()+","+event.getValue()+")");
    }
    public void attributeRemoved(ServletContextAttributeEvent event) {
        log("attributeRemoved("+event.getName()+","+event.getValue()+")");
    }
    public void attributeReplaced(ServletContextAttributeEvent event) {
        log("attributeReplaced("+event.getName()+","+event.getValue()+")");
    }
    public void contextDestroyed(ServletContextEvent event) {
        log("contextDestroyed()");
        this.context=null;
    }
}


标签:暂无标签
版权属于:Jtripper 所有,转载请注明文章来源。

本文链接: https://www.jtripperbacaf.com/index.php/archives/49/

赞 (0)

评论区

发表评论

49+30=?

暂无评论,要不来一发?

回到顶部