2016年3月10日 星期四

ServletConfig和ServletContext的方法,Attribute範圍 (Servlet 四)

ServletConfig有四個方法,由GenericServlet實作


<servlet>
    <servlet-name>ooo</servlet-name>
    <servlet-class>controller.TestServletConfig</servlet-class>
    <init-param>
        <param-name>p1</param-name>
        <param-value>xxx</param-value>
    </init-param>
    <init-param>
        <param-name>p2</param-name>
        <param-value>20</param-value>
    </init-param>
</servlet>
    
<servlet-mapping>
    <servlet-name>ooo</servlet-name>
    <url-pattern>/xxx</url-pattern>
</servlet-mapping>

※一樣給初始參數



public class TestServletConfig extends GenericServlet {
    @Override
    public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
        Enumeration<String> enu = getInitParameterNames();
        while (enu.hasMoreElements()) {
            System.out.println(getInitParameter(enu.nextElement()));
        }
    
        System.out.println("ServletName=" + getServletName());
        ServletContext sc = req.getServletContext();
        System.out.println(sc.getContextPath());
    
        System.out.println("majorVersion=" + sc.getMajorVersion());
        System.out.println("minorVersion=" + sc.getMinorVersion());
        System.out.println("serverInfo=" + sc.getServerInfo());
        System.out.println("servletContextName=" + sc.getServletContextName());
        System.out.println("serverName=" + req.getServerName());
        System.out.println("serverPort=" + req.getServerPort());
    
        sc.setAttribute("aaa", "xxx");
        System.out.println(sc.getAttribute("aaa"));
        sc.removeAttribute("aaa");
        System.out.println(sc.getAttribute("aaa"));
    
        PrintWriter out = resp.getWriter();
        Enumeration<String> attrs = sc.getAttributeNames();
        while(attrs.hasMoreElements()){
            String key = attrs.nextElement();
            out.println("key=" + key + "<br />");
            out.println("value=" + sc.getAttribute(key) + "<br /><br />");
        }
    }
}

※結果:
xxx
20
ServletName=ooo
/TestServletXXX
majorVersion=3
minorVersion=1
serverInfo=Apache Tomcat/8.0.24
servletContextName=TestServlet
serverName=localhost
serverPort=8080
xxx
null

由此可以知,Servlet的版本是majorVersion.minorVersion,也就是3.1版
Container是tomcat8
ServletContextName是專案名稱,不是ContextName(getContextPath才是)
serverName是伺服器的IP位址,自己測當然是本機了,可以在網址上的localhost,改127開頭的就會顯示了(後面不可以是3個0或3個255)

getAttributeNames太多了,自行run看看了(印在頁面和控制台不太一樣哦,有很多的mime-type) 我列出一個最常用的
key=javax.servlet.context.tempdir
value=D:\eclipse-jee-mars-R-win32-x86_64\workspace\.metadata\.plugins\
org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\TestServletXXX
這個路徑是JSP轉成Servlet的資料夾,以後如果jsp有錯,它也會寫行數,指的就是這裡的行數

※這次繼承的是GenericServlet,所以要實作service方法

※getServletName()取得的是web.xml的ooo,不知要做什麼?

※getServletContext非常重要,sc.getContextPath()可以取得ContextPath,之前用的是HttpServletRequest的ContextPath,這裡沒有,所以要這樣取



※Attribute範圍

以下要說明ServletContext、HttpSession、HttpServletRequest的範圍


@WebServlet(urlPatterns = { "/xxx" })
public class TestServletConfig extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/plain; charset=Big5");
        PrintWriter out = resp.getWriter();
    
        out.println("ServletContext");
        ServletContext sc = req.getServletContext();
        sc.setAttribute("aaa", "看我");
        out.println(sc.getAttribute("aaa"));
        out.println();
    
        out.println("HttpSession");
        HttpSession session = req.getSession();
        session.setAttribute("aaa", "看我");
        out.println(session.getAttribute("aaa"));
        out.println();
    
        out.println("HttpServletRequest");
        resp.setContentType("text/plain; charset=Big5");
        req.setAttribute("aaa", "看我");
        out.println(req.getAttribute("aaa"));
    }
}



@WebServlet(urlPatterns = { "/ooo" })
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/plain; charset=UTF-8");
        PrintWriter out = resp.getWriter();
    
        out.println(req.getServletContext().getAttribute("aaa"));
        out.println(req.getSession().getAttribute("aaa"));
        out.println(req.getAttribute("aaa"));
    }
}

※也可以寫在繼承GenericServlet的service方法,但它的參數是HttpServletRequest的爸爸,沒有getSession可以用,但其他兩個可以

※ServletContext:只要一塞值,就一直有,直到Stop the server或Console的Terminate

※HttpSession:同一家瀏覽器一塞值就一直有
要注意的是如果留一個瀏覽器,然後按Servers的Stop the server,再啟動也能抓的到值,但如果是按Console的Terminate就沒有
大部分的Container有效期限是30分鐘(如果其問按了一下,會再重新計算30分鐘),tomcat6是60分鐘(官網寫成60秒),tomcat7和8都是30分鐘(但7和8都已標記Deprecated),tomcat9就拿掉了,這個網址是8的,將網址的8改成其他版本就可以看到各版本的了,要找一個叫maxInactiveInterval的,第6版有說可以用session.setMaxInactiveInterval()單位是秒,API有寫,但這寫法是針對這個Session物件,
如果想針對全部的Session,可在web.xml設定,如下:
<web-app>
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
</web-app>
※單位是分鐘,而非毫秒
※HttpServletRequest:只有一次的存活期,現在還不明顯,要講到forward、include才知道

沒有留言:

張貼留言