Servlet详解(二)

来源:互联网 发布:哪个软件可以写日记 编辑:程序博客网 时间:2024/04/29 23:43

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);    }}

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

原创粉丝点击