java servlet认识

背景

在没有servlet之前,都是通过socket来处理http请求的;但是socket处理http请求的代码量比较多,并且需要自己来解析http协议;
实现一个web站点需要很多开发工作。特别是http协议解析的工作;

servlet的出现解决了这个问题,它是一个接口,专门用来处理http请求的;

1、servlet是什么

servlet是一个接口,定义了处理http请求的规范;

有两部分组成

  • servlet服务器容器 tomcat、jetty、resin等;
  • servlet接口实现类;业务开发,并将这些类丢到服务器容器中;发布成为一个站点

servlet服务器容器实现拦截初始化相关的servlet实例,并按照接口顺序依次调用方法;

                 ┌───────────┐
                 │My Servlet │
                 ├───────────┤
                 │Servlet API│
┌───────┐  HTTP  ├───────────┤
│Browser│◀──────▶│Web Server │
└───────┘        └───────────┘

3、servlet生命周期

servlet生命周期:
1、初始化:调用init方法; 用户访问路径时,会创建servlet实例;只会创建一次
2、服务:调用service方法;用户访问路径时,会调用service方法;会多次调用。处理业务逻辑。
3、销毁:调用destroy方法;服务器关闭时,会调用destroy方法;只会销毁一次

备注 开发中一般使用HttpServlet,该类实现了service方法;主要用来判断请求类型,调用doGet或doPost方法;

4、servlet配置

4.1、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">

    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.jiang.servlet.user.LoginServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
        <init-param>
            <param-name>admin</param-name>
            <param-value>123456</param-value>
        </init-param>
        <init-param>
            <param-name>username</param-name>
            <param-value>password</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/login.do</url-pattern>
    </servlet-mapping>
</web-app>
4.2、注解方式配置

注解属性值与xml配置文件属性值相对于


img.png
@WebServlet(urlPatterns = "/")
public class HelloServlet extends HttpServlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("Servlet is initialized.");
    }
    
    @Override
    @SuppressWarnings("all")
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        resp.setContentType("text/html");
        String name = req.getParameter("name");
        if (name == null) {
            name = "world";
        }
        PrintWriter pw = resp.getWriter();
        pw.write("<h1>Hello, " + name + "!</h1>");
        pw.flush();
    }
}

5、servlet的重定向与转发

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String redirectToUrl = "/hello"
        // 发送重定向响应:
        resp.sendRedirect(redirectToUrl);

        // 代理转发:
        req.getRequestDispatcher("/hello").forward(req, resp);
    }

6、cookie与session

我们把这种基于唯一ID识别用户身份的机制称为Session。

每个用户第一次访问服务器后,会自动获得一个Session ID。

如果用户在一段时间内没有访问服务器,那么Session会自动失效,下次即使带着上次分配的Session ID访问,服务器也认为这是一个新用户,会分配新的Session ID。

在有效期内自动续期

  • session的服务端sessionId存放在servlet服务器内存中;
  • client端,如果是浏览器,则存放在cookie中;

备注
同一个域名的session默认id都是"JSESSIONID",同一个域名多个站点,需要在servlet服务器容器修改,避免冲突

7、servlet线程安全

servlet是单例的,且默认是线程不安全的;
如果需要线程安全,可以重写service方法,在方法中加锁;

8、Filter

过滤器,顾名思义就是对事物进行过滤的。

在Web中的过滤器,当然就是对请求进行过滤,我们使用过滤器,就可以对请求进行拦截,然后做相应的处理,实现许多特殊功能。如登录控制,权限管理,过滤敏感词汇等.

8.1、生命周期

初始化阶段:当服务器启动时,我们的服务器(Tomcat)就会读取配置文件,扫描注解,然后来创建我们的Filter。
拦截和过滤阶段:只要请求资源的路径和拦截的路径相同,那么过滤器就会对请求进行过滤,这个阶段在服务器运行过程中会一直循环。
销毁阶段:当服务器(Tomcat)关闭时,服务器创建的Filter也会随之销毁。

注解方式配置

import javax.servlet.annotation.WebFilter;
// FilterConfig是注解中的参数
@WebFilter(filterName = "LifeCycleFilter", urlPatterns = "/life")
public class LifeCycleFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    }

    @Override
    public void destroy() {
    }
}

登录验证demo

@WebFilter(
        value = "/*",
        filterName = "LogFilter",
        initParams = {@javax.servlet.annotation.WebInitParam(name="Site", value="JavaWeb"),@javax.servlet.annotation.WebInitParam(name="asd", value="dsa")},
        servletNames = {"LogFilter"}
)
public class LogFilter implements Filter {
    public void  init(FilterConfig config) throws ServletException {

        // 获取初始化参数
        String site = config.getInitParameter("Site");

        // 输出初始化参数
        System.out.println("网站名称: " + site);
    }

    
    public void  doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        String urlPath = req.getRequestURI();
        String url = req.getRequestURL().toString();
        System.out.println("urlPath: " + urlPath);
        // 把请求传回过滤链
        if( urlPath.contains("/login") || urlPath.contains("/logout")){
            chain.doFilter(request,response);
        }
        else{
            HttpSession session =req.getSession(false);
            if(session == null|| session.getAttribute("name") == null){
                // 这是代理转发,不是重定向
                // request.getRequestDispatcher("/login").forward(request,response);
                res.sendRedirect( "/login");
            }
            else{
                chain.doFilter(request,response);
            }
        }
    }
    public void destroy( ){
        System.out.println("过滤器已销毁!");
    }
}

9、Listener

9.1、Listener 基本信息

概念:监听器就是一个实现了特定接口的Java类。
分类:

  • 一类监听器:监听域对象的创建、销毁
  • 二类监听器:监听域对象中的属性变更(属性设置、属性替换、属性移除)
  • 三类监听器:监听域对象中的java对象的绑定
9.2、一类监听器(对象监听器,创建销毁)
  • ServletContextListener,监听ServletContext域对象的创建、销毁。服务器容器启动成功,销毁时触发
  • HttpSessionListener 监听HttpSession域对象的创建、销毁。session创建触发sessionCreated方法,销毁时触发sessionDestroyed方法。代码中的创建session对象才会触发
  • ServletRequestListener 监听ServletRequest域对象的创建、销毁。request创建触发requestInitialized方法,请求结束立即销毁时触发requestDestroyed;参数是事件对象,不能拦截
9.3、二类监听器(属性值监听器)
  • ServletContextAttributeListener 监听ServletContext域对象中属性变更;早起站点中全局共享数据,发生变更时触发
  • HttpSessionAttributeListener session级的属性值监听器
  • ServletRequestAttributeListener 请求级的属性值监听器
9.4、三类监听器(对象绑定监听器)
  • HttpSessionBindingListener 监听HttpSession域对象中java对象的绑定、解除绑 。 测试不生效
  • ServletRequestBindingListener 监听ServletRequest域对象中java对象的绑定、解除绑定

10、servletContext

ServetContext官方叫servlet上下文。服务器会为每一个工程创建一个对象,这个对象就是ServletContext对象。这个对象全局唯一,而且工程内部的所有servlet都共享这个对象。所以叫全局应用程序共享对象。

10.1、ServletContext对象方法
  • getAttribute(String name) 获取属性值
  • setAttribute(String name,Object obj) 设置属性值
  • removeAttribute(String name) 移除属性
  • getAttributeNames() 返回所有属性值;
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容