zoukankan      html  css  js  c++  java
  • ServletContext(生命周期、对象的获取、记录访问次数、getServletContext().getAttribute()错误分析)

    一、ServletContext对象

    每一个Web工程对应于一个ServletContext对象,此对象代表web应用,由服务器创建,可以解决不同用户的数据共享问题。

    1、生命周期:

    创建:web应用被加载到服务器或服务器开启。

    销毁:web应用被移除或服务器关闭。

    2、对象的获取:

    (1)实现Servlet接口的类内部:

       public void init(ServletConfig servletConfig) throws ServletException {
            ServletContext servletContext= servletConfig.getServletContext();
        }

    (2)getServletContext():

       protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            ServletContext servletContext=getServletContext();
        }

     (3)通过Session获取:

     ServletContext servletContext=request.getSession().getServletContext();

    3、ServletContext对象的应用:

    (1)获得初始化参数(web.xml的全局数据):

        <servlet>
            <servlet-name>MyServlet</servlet-name>
            <servlet-class>ServletDemo</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>MyServlet</servlet-name>
            <url-pattern>/abc</url-pattern>
        </servlet-mapping>
        <context-param>//一组标签只能存储一组键值对
            <param-name>zhai</param-name>
            <param-value>zhai1997</param-value>
        </context-param>
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            ServletContext servletContext=getServletContext();
            String paramvalue=servletContext.getInitParameter("zhai");//由键获取值
            System.out.println(paramvalue);
        }

     如果数据不存在,返回NULL。

     (2)获得工程发布后的绝对路径:

        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            ServletContext servletContext=getServletContext();
            String realpath=servletContext.getRealPath("/web.text");
            System.out.println(realpath);
            String realpath1=servletContext.getRealPath("/WEB-INF/wen-inf.text");
            System.out.println(realpath1);
            String realpath2=servletContext.getRealPath("../工程.text");
            System.out.println(realpath2);
        }

     

     getRealPath的参数为相对于web的路径,因为发布到服务器的时候只发布web文件中的内容,因此:工程.text文件不能被访问到。

    (3)域对象(作用范围为整个web应用)

    Servlet1:创建ServletContext对象设置键和值(数据存储):

        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            ServletContext servletContext=getServletContext();
            servletContext.setAttribute("name","zhai");
        }

    Servlet2:由键获取值:

       String attribute=(String)this.getServletContext().getAttribute("name");
         System.out.println(attribute);
        }

    需要先访问Servlet1设置键和值,再去访问Servlet2获取值。如果不存在返回NULL。

    二、ServletContext对象应用——三天免登录(记录访问次数)

    1、用到的知识点:

    (1)Cookie

    (2)Session

    (3)ServletContext

     其中Cookie和Session是会话技术的组成部分,一次会话从打开浏览器的某个站点开始,到浏览器关闭为止。如打开浏览器中的淘宝时一次会话开始,关闭浏览器的时候此次会话结束。

    要想实现三天免登录记录网站访问次数的功能,只有Cookie和Session技术是不行的,因为Cookie实现的的是免登录功能。通过创建Cookie,生成了Cookie文件,在下次登录时可以直接读取Cookie中的用户信息,不用重新输入账户和密码。Session的运用解决的是不同请求的数据共享问题,即创建了Session后,在访问不同的页面的时候,可以通过Request对象获取Session的值。

    要想记录页面访问的次数,要用到ServletContext技术,可以解决不同用户的数据共享问题。即ServletContext中的值是所有用户共享的。可以获取或修改值。

    2、过程分析:

    第一次登录(没有Sessio和Cookie):

     

     需要进行手动登录。

    首次登录后(Cookie未过期之前)登录:

    MainServlet的运行结果:

     

    因为Session的运用在CookieServlet中存储的Session中的数据,在MainSewrvlet中依旧能够调用。

    由于SertvletContext的运用,浏览量会递增,不会因为浏览器、服务器的关闭而造成数据从0开始增加。

    3、代码分析:

    CookieServlet:

     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html; charset=utf-8");//设置浏览器编码格式
            Cookie[] cookies=request.getCookies();
            Connection con=null;
            login log= null;
            int successNum=0;
            try {
                con= C3p0Utils.getConnection();
                QueryRunner qr = new QueryRunner();
                String sql = "Select * from login";
                List<login> list = qr.query(con, sql, new BeanListHandler<login>((login.class)));
                if(cookies!=null) {//验证数据库中是否有与Cookie对应的用户
                    for (int i = 0; i < list.size(); i++) {
                        log= list.get(i);
                    for (Cookie cookie : cookies) {
                            if((log.getAccount().equals(cookie.getName()))&&(log.getPassword().equals(cookie.getValue()))){
                                HttpSession httpSession=request.getSession();
                                httpSession.setAttribute("login",log);
                                ServletContext servletContext = this.getServletContext();//获取ServletContext对象
                                if((servletContext.getAttribute("contextNum"))!=null) {
                                    int num=Integer.parseInt(servletContext.getAttribute("contextNum").toString());
                                    num++;
                                    servletContext.setAttribute("contextNum",num);//将int类型的num储存到contextNum
                                }else{
                                  servletContext.setAttribute("num",1);
                                }
    
                               successNum++;
                            }
                    }
                    }
                    if(successNum>=1){
    
                        response.sendRedirect("/Servlet_login_war_exploded/main");
                    }
                    else{
                        request.getRequestDispatcher("page").forward(request,response);
                    }
    
                }
                else{
                    request.getRequestDispatcher("page").forward(request,response);
                }
            }
            catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }

    有Cookie则用数据库校验,成功直接进入主页面,并生成Session和ServletContext,不成功则请求转发到登录页面重新进行登录。

    MainServlet:

      login log= (login) request.getSession().getAttribute("login");
            int num=(int)this.getServletContext().getAttribute("contextNum");

    通过Session和ServletContext获取CookieServlet中的数据。

    LogServlet:

    try {
                con=C3p0Utils.getConnection();
                QueryRunner qr = new QueryRunner();
                String sql = "Select * from login where account=? and password=?";
                Object[] select = {account,password};
                log = qr.query(con, sql, new BeanHandler<login>((login.class)), select);
                if(log!=null){
                    response.getWriter().write("nihao"+account);
                    Cookie cookie=new Cookie(account,password);
                    cookie.setPath("/Servlet_login_war_exploded/cookie");
                    cookie.setMaxAge(3*24*3600);
                    response.addCookie(cookie);
                }
                else{
                    response.getWriter().write("wrong");
                }

    是在无Cookie或数据库校验失败的情况下调用的,数据库中有用户信息则生成Cookie。

    4、问题分析(类型转换错误):

    错误代码:

    int num=(int) this.getServletContext().getAttribute("contextNum");

    原因:this.getServletContext().getAttribute("contextNum")为Object类型,需要先转换为String类型,再转换为int类型:

    int num=Integer.parseInt(servletContext.getAttribute("contextNum").toString());
  • 相关阅读:
    win10 安装anaconda+tensorflow
    CNN 理论
    mac 调出任何来源方法
    git忽略文件权限检查
    ios plist获取权限
    Vue-从入门到第三次世界大战_1
    libc++abi.dylib: terminating with uncaught exception of type NSException
    unity3d导出xcode项目使用afnetworking 3框架导致_kUTTagClassMIMEType 问题解决方案
    ios cannot use "@throw" with objective-c exceptions disabled 问题解决方案
    关于iOS APP转让
  • 原文地址:https://www.cnblogs.com/zhai1997/p/11564894.html
Copyright © 2011-2022 走看看