ServletContext详解

1.首先我们在IDEA里面新建一个工程: 

ServletContext详解_第1张图片

ServletContext详解_第2张图片 我们进行创建之后如下,我们点击父工程pom.xml,发现多了一个moudle:

ServletContext详解_第3张图片

 我们将Servlet-02里面的pom.xml进行必要的清除,设置一个干净的项目:




    
        untitled2
        org.example
        1.0-SNAPSHOT
    
    4.0.0

    servlet-02
    war



我们将该删的进行删除,即可发现一个干净的项目。

如果这个过程中出现错误,我们点击刷新即可。

对于我们要进行修改的web.xml,修改这个比较麻烦。

ServletContext详解_第4张图片

 对于经常共用的东西,我们可以在外面设置一个东西: (note.md)

ServletContext详解_第5张图片

 我们的公用的代码如下所示:

web.xml
```xml




```

这里面的点为esc键下面的键盘,···。

之后我们将main项目进行补全:

ServletContext详解_第6张图片

我们之后进行建包,同时建立HelloServlet类,然后进行在类里面编辑方法。

ServletContext详解_第7张图片

 写完Servlet之后,立马进入web,xml里面进行注册:

ServletContext详解_第8张图片

 
        hello
        com.rgf.servlet.HelloServlet
    
    
        hello
        /hello
    

这样子正常的操作就完成了。

之后我们进行查看Tomcat,我们点击如下所示:

ServletContext详解_第9张图片

 进入之后,我们选择我们所创建的包servlet-02,将此前的包进行删除,确保里面只有一个,这样子可以快速打包,避免一次打多个包:

ServletContext详解_第10张图片

 我们点击运行之后如下所示:

ServletContext详解_第11张图片

 我们出现这个画面即为成功。

ServletContext详解_第12张图片

由于我们没有写输出,所以这个为空白页面。

我们从HttpServlet,按住ctrl,点击鼠标左键,进入HttpServlet的源码界面,我们来进行分析:

ServletContext详解_第13张图片

 我们依靠这三个方面来进行分析:主要通过Structure分析方法:

ServletContext详解_第14张图片

 我们了解如下所示:

//this.getInitParameter()  初始化参数
        //this.getServletConfig()  Servlet配置
        //this.getServletContext() Servlet上下文
       // this指代自己,因为继承了HttpServlet所有父类的方法,就能使用父类方法this.。

在web.xml了解如下所示:

 
        
       
    
     
         hello
         com.rgf.servlet.HelloServlet
         
          
          
     

 我们进行重点了解ServletContext,如下所示:

比如我们在淘宝登录的时候,登陆完之后的注册信息会带到很多页面,跳到其他页面也是登录上去的,这个不是自己做到的,是中间商做到的。

web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用。

这个网站就是由这个对象来进行管理的:ServletContext

应用:1.共享数据

我在这个Servlet保存的数据可以在另外一个Servlet中拿到:

ServletContext详解_第15张图片

 但是这种方法是比较不合适的。

如下所示:

ServletContext详解_第16张图片

 我们利用ServletContext进行检验:

我们新建一个class,类名为GetServlet:(读取的类)

package com.rgf.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username = (String) context.getAttribute("username");
        resp.getWriter().print("rgf"+username);


    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

之后,我们将HelloServlet进行修改:(放置的类)

package com.rgf.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username = (String) context.getAttribute("username");
        resp.getWriter().print("rgf"+username);


    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

之后,我们新建了一个Servlet之后,我们在web.xml进行新建一个servlet:

 
        getc
        com.rgf.servlet.GetServlet
    
    
        getc
        /getc
    

点击运行之后,我们出现如下所示:

ServletContext详解_第17张图片

 我们看到了null,之后我们进行完善:代码如下所示:

package com.rgf.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //数据放上面
        ServletContext context = this.getServletContext();
        String username = (String) context.getAttribute("username");
        //响应放下面
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print("rgf"+username);


    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

我们在设置过程中我们可以看其他网页的设置进行设置:

ServletContext详解_第18张图片

 之后我们重新启动后如下所示:

ServletContext详解_第19张图片

 我们利用hello里面的set方法先要赋值,getc里面的get才能取到值,我们示例如下:

我们先存起来如下所示:

ServletContext详解_第20张图片

 之后我们取出来如下所示:

ServletContext详解_第21张图片

我们打开这个GetServlet进入该类:在ServletContext,按住ctrl键,点击鼠标左键,进入源代码:

ServletContext详解_第22张图片

 进入源代码之后,我们点击structure,查看结构:ServletContext详解_第23张图片

我们查看源代码,进行对源代码的分析如下所示:

源码分析:

里面的@Deprecated,该标签标记为已过时被废弃的或者不建议被使用:

ServletContext详解_第24张图片

 获得自己的路径:

String getContextPath();

获得版本信息:

int getMajorVersion();

    int getMinorVersion();

    int getEffectiveMajorVersion();

    int getEffectiveMinorVersion();

获得自己这个对象:(可以通过某一个字符串进行获取)

ServletContext getContext(String var1);

获取复杂的消息类型:

String getMimeType(String var1);

获取资源的路径:

Set getResourcePaths(String var1);

获取资源把它变成一个流:

 InputStream getResourceAsStream(String var1);

获取一个RequestDispatcherr,通过请求转发:

  RequestDispatcher getRequestDispatcher(String var1);

获取一个RequestDispatcher,通过名字转发:

 RequestDispatcher getNamedDispatcher(String var1);

获得真实的地址:

String getRealPath(String var1);

获得服务的信息:

String getServerInfo();

获得初始化的参数:

 String getInitParameter(String var1);

进行设置:(上面为获得,下面就是设置了)

void setAttribute(String var1, Object var2);

3.我们可以设置新的一个类:ServletDemo03:

在里面进行写如下代码:

context.getInitParameter("");

这个除了可以获取setInitParameter("");还可以获取如下所示:

我们可以在web.xml里面进行配置:

    

    
        url
        jdbc:mysql://localhost:3306/mybatis //jdbc的连接url
    

web.xml里面的初始化参数我们可以在ServletDemo03里面拿到:

我们的ServletDemo03里面的代码如下所示:

package com.rgf.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ServletDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //数据放上面
        ServletContext context = this.getServletContext();


        String url = context.getInitParameter("url");
        
        //响应放下面
        resp.getWriter().print(url);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

之后我们在web.xml里面进行注册该类的信息:


        gp
        com.rgf.servlet.ServletDemo03
    
    
        gp
        /gp
    

综上所述,所以ServletContext除了数据共享还可以获取初始化参数:

2.获取初始化参数

(1)ServletDemo03代码编写:

package com.rgf.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ServletDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //数据放上面
        ServletContext context = this.getServletContext();


        String url = context.getInitParameter("url");

        //响应放下面
        resp.getWriter().print(url);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

(2)web.xml代码进行设置:

 
        gp
        com.rgf.servlet.ServletDemo03
    
    
        gp
        /gp
    

我们进行运行之后如下所示:

ServletContext详解_第25张图片

3.请求转发(RequestDispatcherr)

我们设置一个新的类:ServletDemo04,我们编写该类的时候,会发现RequestDispatcher,我们进入该类的源码进行查看:

public interface RequestDispatcher {
    String FORWARD_REQUEST_URI = "javax.servlet.forward.request_uri";
    String FORWARD_CONTEXT_PATH = "javax.servlet.forward.context_path";
    String FORWARD_MAPPING = "javax.servlet.forward.mapping";
    String FORWARD_PATH_INFO = "javax.servlet.forward.path_info";
    String FORWARD_SERVLET_PATH = "javax.servlet.forward.servlet_path";
    String FORWARD_QUERY_STRING = "javax.servlet.forward.query_string";
    String INCLUDE_REQUEST_URI = "javax.servlet.include.request_uri";
    String INCLUDE_CONTEXT_PATH = "javax.servlet.include.context_path";
    String INCLUDE_PATH_INFO = "javax.servlet.include.path_info";
    String INCLUDE_MAPPING = "javax.servlet.include.mapping";
    String INCLUDE_SERVLET_PATH = "javax.servlet.include.servlet_path";
    String INCLUDE_QUERY_STRING = "javax.servlet.include.query_string";
    String ERROR_EXCEPTION = "javax.servlet.error.exception";
    String ERROR_EXCEPTION_TYPE = "javax.servlet.error.exception_type";
    String ERROR_MESSAGE = "javax.servlet.error.message";
    String ERROR_REQUEST_URI = "javax.servlet.error.request_uri";
    String ERROR_SERVLET_NAME = "javax.servlet.error.servlet_name";
    String ERROR_STATUS_CODE = "javax.servlet.error.status_code";

    void forward(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    void include(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
}

我们发现该类的源码里面:只有forward和include两个方法,其他的都是一堆常量。

我们在ServletDemo04里面进行编写的代码如下所示:

package com.rgf.servlet;

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 java.io.IOException;

public class ServletDemo04 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //数据放上面
        ServletContext context = this.getServletContext();
        System.out.println("进入了ServletDemo04");
        RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp"); //转发的请求路径
        //我们上面只有请求路径,还没有转发
        requestDispatcher.forward(req,resp); //调用forward方法实现请求转发
        //需要传两个参数,就是从HttpServletRequest的rep请求处理,到HttpServletResponse的resp请求响应回去


        String url = context.getInitParameter("url");

        //响应放下面
        resp.getWriter().print(url);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

之后我们在web.xml里面的代码如下所示:


        sd4
        com.rgf.servlet.ServletDemo04
    
    
        sd4
        /sd4
    

 进行运行之后如下所示:

ServletContext详解_第26张图片

 我们可以看到,jdbc:mysql://localhost:3306/mybatis,本是http://localhost:9571/servlet_02_war/gp里面的,但是http://localhost:9571/servlet_02_war/sd4加载的也是这个页面里面的内容。

ServletContext详解_第27张图片

 我们可知Status Code里面为200,而不是重定向的300,这是转发实现的。

我们请求到web.xml里面的sd4,通过一个getRequestDispatcher转发到了另外一个页面,转发的时候路径不会发生变化。之后的重定向路径是会发生变化的。

ServletContext详解_第28张图片

 4.读取资源文件

Properties,这里需要用到这个,我们去那个类里面进行new一个对象。

我们在ServletDemo03里面进行编写如下代码:

  Properties properties = new Properties();

我们进入Properties类里面查看源码,如下所示:

ServletContext详解_第29张图片

Properties里面继承了一些东西,它里面有一些自己的方法。

ServletContext详解_第30张图片

 我们对这些方法进行分析:

(1)可以传递一个自定义参数,让他读取某一个,否则就是默认的

public Properties(Properties defaults) {

(2) 设置一些属性的值,就是put里面的return put(key, value);

public synchronized Object setProperty(String key, String value) {

(3)加载,可以加载一个字符流也可以加载字节流

return put(key, value);

(4)往磁盘写。

 public void store(Writer writer, String comments)

(5)从XML里面去加载

public synchronized void loadFromXML(InputStream in)

(6)get一个属性

public String getProperty(String key) {

我们创建一个properties文件,可以在任何地方创建,只要没有超出main。

我们在resources里面进行创建:ServletContext详解_第31张图片

 我们在里面输入如下所示:

ServletContext详解_第32张图片

 我们进行了解我们在初学properties是如何进行读取的。

我们进行创建该类如下所示:

ServletContext详解_第33张图片

 我们一般都采用流,即为load(inStream);我们直接读取db.properties的绝对地址即可。但是现在是web应用,没有办法去保证绝对地址,因为web服务要走服务器,我们需要去web里面去拿,所以我们要观察db.properties会生成在web里面的哪个地方。

首先我们通过Maven,clean一下:

ServletContext详解_第34张图片

出现如下所示即可完成:

ServletContext详解_第35张图片  之后我们重新点击运行,进行测试:

ServletContext详解_第36张图片

 我们发现在WEB-INF里面的classes类里面,com下面有db.properties。

classpath叫类路径。里面还有servlet文件。

ServletContext详解_第37张图片

我们进行做如下测试:

我们可以将 db.properties复制到main下面的文件命名为aa.properties,重新运行之后,看target里面是否有aa.properties。

ServletContext详解_第38张图片

我们重新运行之后如下所示:

ServletContext详解_第39张图片

 我们发现里面没有aa.properties。

在Maven里面资源导出可能存在问题,Maven由于它的约定大于配置,我们之后可能遇到我们写的配置文件,无法被导出或者生效的问题,解决方案如下所示:在build下面加个resouces.我们将该代码放到当前项目的pom.xml里面:

 

        
            
                src/main/resources
                
                    **/*.properties
                    **/*.xml
                
                true
            
            
                src/main/java
                
                    **/*.properties
                    **/*.xml
                
                true
            
        
    

我们将该代码添加之后,重新运行之后,结果如下所示:

ServletContext详解_第40张图片

我们发现里面成功的出现了aa.properties。如果没有出现的话,我们可以再通过Maven里面的clean进行清除,然后再重新运行。即可进行查询。

Properties

在java目录下新建Properties

在resouces目录下新建Properties

发现:都被打包到了同一个路径下:classes,我们俗称这个路径为classpath;

我们了解到路径是怎么放的了,我们现在可以去读他了。

我们创建一个类为ServletDemo05,我们编写的代码如下所示:

package com.rgf.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class ServletDemo05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
        //把资源变成一个流
//第一个/不能省略,代表当前web项目,不然无法找到,这是一个相对定位的感觉
        Properties prop = new Properties();
        prop.load(is); //文件的流就拿到了。
        String user = prop.getProperty("username");//最好直接从db.properties文件里面直接复制。
        String pwd = prop.getProperty("password");

        resp.getWriter().print(user+":"+pwd);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

之后我们在那个web.xml里面进行配置如下所示:

 
        sd5
        com.rgf.servlet.ServletDemo05
    
    
        sd5
        /sd5
    

之后我们运行进行测试:

ServletContext详解_第41张图片

 我们可以读取到resouces里面的db.properties。我们是否可以读取到我们在main下面的aa.properties。我们进行测试如下所示:

我们的aa.properties文件如下所示:

ServletContext详解_第42张图片

 我们运行之后的界面如下所示:

ServletContext详解_第43张图片

 我们可知我们可以进行读取到。

综上所述:我们的读取资源文件的思路如下所示:

需要一个文件流,只要能变成一个流,我们即可进行读取到。

Properties(文件内容为:)

username=root
password=123456

通过ServletContext读取配置文件。

ServletContext是一个对象,我们之后还会再学习一些对象,比如Response,Request,Cookie,Session这些对象,我们就是再学习一个一个的类,这个类有哪些方法,如何去使用等等。针对ServletContext的四个应用。我们会在后面通过Session或者Request的一些方法来取代Context的共享数据的作用,我们更多的是用Session或者Request的一些方法来实现共享数据。第二个获取初始化参数我们基本不使用这个。第三个请求转发我们使用Request。第四个读取资源文件的话我们更多的是用类加载器。

你可能感兴趣的:(JavaWeb,java,servlet)