Servlet详解(二)

1.配置Servlet初始化参数

在Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数。
Servlet配置文件web.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_3_1.xsd"
         version="3.1">

    <servlet>
        <servlet-name>ServletCongigDemo</servlet-name>
        <servlet-class>cn.jxs.servlet.ServletConfigDemo</servlet-class>
        <!--ServletConfigDemo初始化参数-->
        <init-param>
            <param-name>username</param-name>
            <param-value>Jiangxs</param-value>
        </init-param>
        <init-param>
            <param-name>Password</param-name>
            <param-value>jxsjxs</param-value>
        </init-param>
        <init-param>
            <param-name>charset</param-name>
            <param-value>GBK2312</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>ServletCongigDemo</servlet-name>
        <url-pattern>/scd</url-pattern>
    </servlet-mapping>

</web-app>

  当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
代码示例:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

/**
 * Created by jiangxs on 2017/10/24.
 */
public class ServletConfigDemo extends HttpServlet{

    private ServletConfig config;

    @Override
    public void init(ServletConfig config) throws ServletException {
        this.config = config;
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //ServletConfig config = this.getServletConfig();
        Enumeration<String> names = config.getInitParameterNames();
        while (names.hasMoreElements()){
            String name = names.nextElement();
            String value = config.getInitParameter(name);
            String str = name+" = "+value;
            System.out.println(str);
            resp.getWriter().println(str);
        }
        System.out.println();
    }

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

但由于HttpServlet继承了GenericServlet,通过在GenericServlet的源码中我们可以看到在该类中其实已经创建了ServletConfig对象,并且给出了方法让我们获得该变量。
GenericServlet部分源码:

private transient ServletConfig config;
public ServletConfig getServletConfig() {
    return this.config;
}

所以在开发中通常省略对servlet的init方法的覆盖,而是通过getServletConfig()方法获得ServletConfig的对象config
示例代码如下:

package cn.jxs.servlet;

import javax.servlet.ServletConfig;
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.util.Enumeration;

/**
 * Created by jiangxs on 2017/10/24.
 */
public class ServletConfigDemo extends HttpServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletConfig config = this.getServletConfig();
        Enumeration<String> names = config.getInitParameterNames();
        while (names.hasMoreElements()){
            String name = names.nextElement();
            String value = config.getInitParameter(name);
            String str = name+" = "+value;
            System.out.println(str);
            resp.getWriter().println(str);
        }
        System.out.println();
    }

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

由于我在服务器和网页上都进行了输出和打印,所以打印结果如下图:
这里写图片描述

这里写图片描述

2.ServletContext对象

  WEB容器在启动时 ,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前Web应用。
  ServletConfig的对象中维护了ServletContext对象的引用,开发人员在编写Servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。
由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletConfig对象通常被称之为context域对象。

3.ServletContext应用

(1)多个ServletContext对象实现共享数据

  现在在ServletContextDemo1.java中创建ServletContext对象,并使用setAttribute()方法设置数据和属性存入ServletContext对象中,然后在ServletContextDemo2.java中新建ServletContext对象,并使用getAttribute获得在ServletContextDemo1.java中设置的数据和属性。示例代码如下:
web.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_3_1.xsd"
         version="3.1">

    <servlet>
        <servlet-name>ServletContextDemo1</servlet-name>
        <servlet-class>cn.jxs.servlet.ServletContextDemo1</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>ServletContextDemo1</servlet-name>
        <url-pattern>/scd1</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>ServletContextDemo2</servlet-name>
        <servlet-class>cn.jxs.servlet.ServletContextDemo2</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>ServletContextDemo2</servlet-name>
        <url-pattern>/scd2</url-pattern>
    </servlet-mapping>
</web-app>

ServletContextDemo1.java示例代码:

package cn.jxs.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;

/**
 * Created by jiangxs on 2017/10/25.
 */
public class ServletContextDemo1 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建Servlet对象
        //方式1:获得ServletConfig对象后再调用getServletContext()获得ServletContext对象
        //ServletContext context = this.getServletConfig().getServletContext();
        //方式2:通过getServletContext()方法直接获得ServletContext对象
        ServletContext context = this.getServletContext();
        //设置属性并保存到ServletContext对象中
        context.setAttribute("name","Jiangxs");
    }

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

ServletContextDemo2.java示例代码:

package cn.jxs.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;

/**
 * Created by jiangxs on 2017/10/25.
 */
public class ServletContextDemo2 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String str = "name = "+context.getAttribute("name");
        System.out.println(str);
        resp.getWriter().write(str);
    }

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

先运行ServletContextDemo1,将数据name存储到ServletContext对象中,然后运行ServletContextDemo2就可以从ServletContext对象中取出数据了,这样就实现了数据共享,如下图所示:
这里写图片描述
服务器端数据打印:
这里写图片描述

(2)获取WEB应用的初始化参数

首先在web.xml文件中使用标签配置WEB应用的初始化参数,web.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_3_1.xsd"
         version="3.1">

    <context-param>
        <param-name>username</param-name>
        <param-value>Jiangxs</param-value>
    </context-param>
    <context-param>
        <param-name>password</param-name>
        <param-value>jxsjxs</param-value>
    </context-param>
    <context-param>
        <param-name>charset</param-name>
        <param-value>GBK2312</param-value>
    </context-param>

    <servlet>
        <servlet-name>ServletContextDemo3</servlet-name>
        <servlet-class>cn.jxs.servlet.ServletContextDemo3</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>ServletContextDemo3</servlet-name>
        <url-pattern>/scd3</url-pattern>
    </servlet-mapping>

</web-app>

获取配置WEB应用的初始化参数value值的示例代码如下:

package cn.jxs.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;

/**
 * Created by jiangxs on 2017/10/25.
 */
public class ServletContextDemo3 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context  = this.getServletContext();
        //获取web.xml初始化参数的value值
        String username = context.getInitParameter("username");
        String password = context.getInitParameter("password");
        String charset = context.getInitParameter("charset");
        //打印到服务器
        System.out.println(username);
        System.out.println(password);
        System.out.println(charset);
        //打印到浏览器
        resp.getWriter().println(username);
        resp.getWriter().println(password);
        resp.getWriter().println(charset);
    }

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

运行结果如下图所示:
这里写图片描述

这里写图片描述

(3)用servletContext实现请求转发

下面代码示例是使用ServletContextDemo4向ServletContextDemo5进行转发。
这里需注意的是getRequestDispatcher()方法中需填写相对路径,注释写的比较清楚了,请看注释~~
先看看web.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_3_1.xsd"
         version="3.1">

    <servlet>
        <servlet-name>ServletContextDemo4</servlet-name>
        <servlet-class>cn.jxs.servlet.ServletContextDemo4</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>ServletContextDemo4</servlet-name>
        <url-pattern>/scd4</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>ServletContextDemo5</servlet-name>
        <servlet-class>cn.jxs.servlet.ServletContextDemo5</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>ServletContextDemo5</servlet-name>
        <url-pattern>/scd5</url-pattern>
    </servlet-mapping>

</web-app>

ServletContextDemo4.java代码如下:

package cn.jxs.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;

/**
 * Created by jiangxs on 2017/10/25.
 * ServletContextDemo4收到请求后,转发给ServletContextDemo5处理
 */
public class ServletContextDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //得到转发到ServletContextDemo5的转发对象
        ServletContext context = this.getServletContext();
        //getRequestDispatcher()方法内填写相对路径!
        //填写web.xml文件中<servlet-mapping>标签下<url-pattern>标签下的内容
        //例如为了转发到ServletContextDemo5,此时须填写web.xml文件中
        // <servlet-mapping>标签下<url-pattern>标签下的内容:/scd5
        RequestDispatcher dispatcher = context.getRequestDispatcher("/scd5");
        dispatcher.forward(req,resp);
    }

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

ServletContextDemo5.java代码如下:

package cn.jxs.servlet;

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

/**
 * Created by jiangxs on 2017/10/25.
 */
public class ServletContextDemo5 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("ServletContextDemo5 Processing!!");
        System.out.println("ServletContextDemo5正在处理请求!!");
    }

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

运行结果如下图所示:
这里写图片描述

这里写图片描述

(4)使用ServletContext对象读取资源文件

IDEA的Web工程与MyEclipse的Web工程目录结构有所不同,但大同小异,下面是我的Web工程的目录结构:
这里写图片描述

  • 使用servletContext读取资源文件:
package cn.jxs.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.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;

/**
 * Created by jiangxs on 2017/10/27.
 */
public class ServletContextDemo6 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置响应的内容类型以及编码方式,防止出现乱码
        resp.setContentType("text/html;charset=UTF-8");
        //读取web目录下的prop.properties配置文件方式一
        readWebPropFile1(resp);
        resp.getWriter().println("<hr/>");
        //读取web目录下的prop.properties配置文件方式二
        readWebPropFile2(resp);
        resp.getWriter().println("<hr/>");
        //读取web目录下的prop.properties配置文件方式三
        readWebPropFile3(resp);
        resp.getWriter().println("<hr/>");
        //读取src目录下的prop1.properties配置文件
        readSrcPropFile1(resp);
        resp.getWriter().println("<hr/>");
        //读取src目录下cn.jxs.servlet包下的prop2.properties配置文件
        readSrcPropFile2(resp);
    }

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

    /**
     * 读取web目录下的prop.properties配置文件方式一
     * description:通过ServletContext对象读取web目录下的prop.properties配置文件
     * attention:配置文件读取方式采用ServletCOntext的getResourceAsStream()方法
     * @param resp
     * @throws IOException
     * */
    public void readWebPropFile1(HttpServletResponse resp) throws IOException {
        ServletContext context = this.getServletContext();
        InputStream in = context.getResourceAsStream("/prop.properties");
        Properties prop = new Properties();
        prop.load(in);
        String url = prop.getProperty("url");
        String username = prop.getProperty("username");
        String password = prop.getProperty("password");

        resp.getWriter().println("读取web目录下的prop.properties文件:"+"<br/>");
        resp.getWriter().println("url = "+url+"<br/>");
        resp.getWriter().println("username = "+username+"<br/>");
        resp.getWriter().println("password = "+password+"<br/>");
    }

    /**
     *  读取web目录下的prop.properties配置文件方式二
     * description:通过ServletContext对象读取web目录下的prop.properties配置文件
     * attention:配置文件读取方式采用ServletCOntext的getgetRealPath()方法先获取绝对路径
     * 然后再使用流读取绝对路径对应的文件
     * @param resp
     * @throws IOException
     * */
    public void readWebPropFile2(HttpServletResponse resp) throws IOException {
        ServletContext context = this.getServletContext();
        String absolutePath = context.getRealPath("/prop.properties");
        //获取到操作文件名
        String fileName = absolutePath.substring(absolutePath.lastIndexOf("\\")+1);
        System.out.println("当前读到的文件是:"+fileName);

        FileInputStream in = new FileInputStream(absolutePath);
        Properties prop = new Properties();
        prop.load(in);

        String url = prop.getProperty("url");
        String username = prop.getProperty("username");
        String password = prop.getProperty("password");

        resp.getWriter().println("读取web目录下的prop.properties文件:"+"<br/>");
        resp.getWriter().println("url = "+url+"<br/>");
        resp.getWriter().println("username = "+username+"<br/>");
        resp.getWriter().println("password = "+password+"<br/>");
    }

    /**
     * 读取web目录下的prop.properties配置文件方式三
     * description:通过ServletContext对象读取web目录下的prop.properties配置文件
     * attention:配置文件读取方式采用ServletCOntext的getResource方法先获取url
     * 然后再使用流读取url
     * @param resp
     * @throws IOException
     * */
    public void readWebPropFile3(HttpServletResponse resp) throws IOException {
        ServletContext context = this.getServletContext();
        URL u = context.getResource("/prop.properties");
        InputStream in = u.openStream();
        Properties prop = new Properties();
        prop.load(in);

        String url = prop.getProperty("url");
        String username = prop.getProperty("username");
        String password = prop.getProperty("password");

        resp.getWriter().println("读取web目录下的prop.properties文件:"+"<br/>");
        resp.getWriter().println("url = "+url+"<br/>");
        resp.getWriter().println("username = "+username+"<br/>");
        resp.getWriter().println("password = "+password+"<br/>");
    }

    /**
     * description:通过ServletContext对象读取src目录下的prop1.properties配置文件
     * attention:配置文件读取方式采用ServletCOntext的getResourceAsStream()方法
     * @param resp
     * @throws IOException
     * */
    public void readSrcPropFile1(HttpServletResponse resp) throws IOException {
        ServletContext context = this.getServletContext();
        InputStream in = context.getResourceAsStream("/WEB-INF/classes/prop1.properties");
        Properties prop = new Properties();//map
        prop.load(in);

        String url = prop.getProperty("url");
        String username = prop.getProperty("username");
        String password = prop.getProperty("password");

        resp.getWriter().println("读取src目录下的prop1.properties文件:"+"<br/>");
        resp.getWriter().println("url = "+url+"<br/>");
        resp.getWriter().println("username = "+username+"<br/>");
        resp.getWriter().println("password = "+password+"<br/>");
    }

    /**
     * description:通过ServletContext对象读取src目录下cn.jxs.servlet包下的prop2.properties配置文件
     * attention:配置文件读取方式采用ServletCOntext的getResourceAsStream()方法
     * @param resp
     * @throws IOException
     * */
    public void readSrcPropFile2(HttpServletResponse resp) throws IOException {
        ServletContext context = this.getServletContext();
        InputStream in = context.getResourceAsStream("/WEB-INF/classes/cn/jxs/servlet/prop2.properties");
        Properties prop = new Properties();//map
        prop.load(in);

        String url = prop.getProperty("url");
        String username = prop.getProperty("username");
        String password = prop.getProperty("password");

        resp.getWriter().println("读取src目录下cn.jxs.servlet包下的prop2.properties文件:"+"<br/>");
        resp.getWriter().println("url = "+url+"<br/>");
        resp.getWriter().println("username = "+username+"<br/>");
        resp.getWriter().println("password = "+password+"<br/>");
    }
}

运行结果如下图:
这里写图片描述

  • 使用类装载器读取资源文件:

注意:这里的StudentDao类不能继承HttpServlet类,防止Dao层与Web层相互侵入。

StudentDao.java源代码:

package cn.jxs.dao;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * Created by jiangxs on 2017/10/27.
 */
public class StudentDao {
    public String get1() throws IOException {
        //获得类装载器
        ClassLoader loader = StudentDao.class.getClassLoader();
        //getResourceAsStream()方法从classes文件夹下开始读取
        InputStream in = loader.getResourceAsStream("prop1.properties");
        Properties prop = new Properties();
        prop.load(in);

        String url = prop.getProperty("url");
        String username = prop.getProperty("username");
        String password = prop.getProperty("password");
        System.out.println("读取src目录下的prop1.properties文件");
        System.out.println(url);
        System.out.println(username);
        System.out.println(password);
        return null;
    }

    public String get2() throws IOException {
        //获得类装载器
        ClassLoader loader = StudentDao.class.getClassLoader();
        //getResourceAsStream()方法从classes文件夹下开始读取
        InputStream in = loader.getResourceAsStream("/cn/jxs/servlet/prop2.properties");
        Properties prop = new Properties();
        prop.load(in);

        String url = prop.getProperty("url");
        String username = prop.getProperty("username");
        String password = prop.getProperty("password");
        System.out.println("读取src目录下cn.jxs.servlet包下的prop2.properties文件");
        System.out.println(url);
        System.out.println(username);
        System.out.println(password);
        return null;
    }
}

ServletContextDemo7.java源代码:

package cn.jxs.servlet;

import cn.jxs.dao.StudentDao;

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

/**
 * Created by jiangxs on 2017/10/27.
 */
public class ServletContextDemo7 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //调用StudentDao从prop.properties中获取数据
        StudentDao dao = new StudentDao();
        String student1 = dao.get1();
        String student2 = dao.get2();
    }

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

使用类装载器读取资源文件,将读取到的数据打印在服务器端输出,运行结果如下图所示:
这里写图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值