我們可以在Servlet中寫一個參數構造函數嗎?如果是的話,你怎麼打電話?如何使用參數啓動時初始化Servlet?
回答
我們可以寫一個Servlet的參數的構造函數?
是的,你可以,但它是沒用的,因爲servlet容器不會調用它。
正確的方式做到這一點是使用init()
方法:
@Override
public void init() throws ServletException {
String foo = getInitParameter("foo");
String bar = getServletContext().getInitParameter("bar");
// ...
}
在這個例子中,getInitParameter("foo")
返回web.xml
具體<servlet>
條目的<init-param>
的價值,getServletContext().getInitParameter("bar")
返回的值獨立<context-param>
在web.xml
。
構造函數是由應用程序服務器管理的對象。
有關初始化,請參閱init()方法。
更新:
我可以用一個構造函數在我的servlet?
答:一個servlet是一個普通的Java類,所以當沒有自定義 構造函數時,默認的構造函數是沒有參數的。 Servlet容器通常使用 Class.newInstance()方法加載 servlet,所以你必須小心 添加一個顯式的默認構造函數,如果你添加了非默認的構造函數,則爲 。
爲什麼init()而不是servlet的構造函數? – 2009-08-14 04:48:29
你不能。 Servlet由容器反射性地實例化。如果Servlet規範已經允許在構造函數的參數,你就必須有一些複雜的部署描述符一樣,
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>MyServlet</servlet-class>
<servlet-argument id="1" type="string">Test<servlet-argument>
<servlet-argument id="2" type="int">10</servlet-argument>
<load-on-startup>1</load-on-startup>
</servlet>
我想沒有人希望這樣。
有趣的答案 – 2009-08-14 05:02:33
這裏的問題是servlet配置語法,而不是參數化構造函數的複雜性 – Aivar 2011-10-29 14:05:21
問題可能狀態更一般。
「根據servlet的(2.3) 規範中,Servlet是 由servlet引擎實例化由 調用無參數的構造如何 能我初始化一個servlet正確 因爲正確初始化 依賴於 中心/國際/獨特/應用 配置?」
實際上,你可以在構造函數中使用serlvets和/或根據你的喜好初始化它們。但是,它需要一點管道。
假設你有一個有構造函數參數的一個servlet:
package org.gawi.example.servlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class SampleServlet extends HttpServlet
{
private final String mMessage;
public SampleServlet(String message)
{
mMessage = message;
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("text/plain");
response.getWriter().write(mMessage);
}
}
你首先需要的是一種獨特的servlet whithin您的應用程序,讓我們稱之爲InitializationServlet,創建所有需要的實例。然後必須將這些實例導出到servlet上下文中以供其他servlet檢索(稍後解釋)。該InitializationServlet可能是這樣的:
package org.gawi.example.servlets;
import javax.servlet.*;
import javax.servlet.http.*;
public class InitializationServlet extends HttpServlet
{
public void init() throws ServletException
{
SampleServlet servletA = new SampleServlet("this is servlet A");
SampleServlet servletB = new SampleServlet("this is servlet B");
SampleServlet servletC = new SampleServlet("this is servlet C");
getServletContext().setAttribute("servletA", servletA);
getServletContext().setAttribute("servletB", servletB);
getServletContext().setAttribute("servletC", servletC);
}
}
你看到只有init()
方法已經提供。此servlet不處理任何HTTP請求。它的唯一目的是將Servlet存儲在ServletContext中。請注意,您也可以使用此servlet來加載您的應用程序配置。因此,這可以充當網絡應用程序入口點,如程序的main(String[] args)
方法。這可能會提醒你SpringSource的ContextLoaderServlet。
的最後一塊是將有效地由servlet容器實例化的DelegateServlet,只有這個servlet會將所有相關的方法調用被包裝的servlet實例:
package org.gawi.example.servlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class DelegateHttpServlet extends HttpServlet
{
private static final String SERVLET_CONTEXT_KEY_INIT_PARAMETER = "servletContextKey";
private HttpServlet mServlet;
public void init(ServletConfig servletConfig) throws ServletException
{
super.init(servletConfig);
locateServlet(servletConfig);
mServlet.init(servletConfig);
}
private void locateServlet(ServletConfig servletConfig) throws ServletException
{
String servletContextAttributeName = servletConfig.getInitParameter(SERVLET_CONTEXT_KEY_INIT_PARAMETER);
if (servletContextAttributeName == null)
{
throw new ServletException("Unable to find init parameter '" + SERVLET_CONTEXT_KEY_INIT_PARAMETER + "'");
}
Object object = servletConfig.getServletContext().getAttribute(servletContextAttributeName);
if (object == null)
{
throw new ServletException("Unable to find " + servletContextAttributeName + " in servlet context.");
}
if (!(object instanceof HttpServlet))
{
throw new ServletException("Object is not an instance of"
+ HttpServlet.class.getName()
+ ". Class is "
+ object.getClass().getName()
+ ".");
}
mServlet = (HttpServlet) object;
}
public void destroy()
{
mServlet.destroy();
}
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
{
mServlet.service(req, res);
}
}
在其初始化時,DelegateServlet會使用servlet初始參數在servlet上下文中查找目標servlet。
對於這樣的應用程序可能看起來像在web.xml中:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Example</display-name>
<description>Example web showing handling of servlets w/ constructors.</description>
<servlet>
<servlet-name>Initialization</servlet-name>
<servlet-class>org.gawi.example.servlets.InitializationServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>A</servlet-name>
<servlet-class>org.gawi.example.servlets.DelegateHttpServlet</servlet-class>
<init-param>
<param-name>servletContextKey</param-name>
<param-value>servletA</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet>
<servlet-name>B</servlet-name>
<servlet-class>org.gawi.example.servlets.DelegateHttpServlet</servlet-class>
<init-param>
<param-name>servletContextKey</param-name>
<param-value>servletB</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet>
<servlet-name>C</servlet-name>
<servlet-class>org.gawi.example.servlets.DelegateHttpServlet</servlet-class>
<init-param>
<param-name>servletContextKey</param-name>
<param-value>servletC</param-value>
</init-param>
<load-on-startup>4</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>A</servlet-name>
<url-pattern>/servlet/a</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>B</servlet-name>
<url-pattern>/servlet/b</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>C</servlet-name>
<url-pattern>/servlet/c</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>5</session-timeout>
</session-config>
</web-app>
請務必先加載InitializationServlet,使用低<load-on-startup>
值。
這種方法的好處是HttpServlet
對象可以像任何其他常規Java對象或bean一樣處理。因此,它提供了對初始化的更好控制:在init()
方法中沒有更多棘手的事情要做,也沒有混亂的servlet init-arg處理。
如果我們有參數化的構造函數或公共構造函數,servlet如何可以是單例? ? servlet容器是否有一個「SampleServlet」的例子,如你的例子。你能否詳細說明一下。? – 2014-09-16 08:11:04
- 1. 如何在啓動時初始化()/初始化()一個Scalatra servlet?
- 2. 如何在服務器啓動時初始化一個servlet
- 3. Tomcat Java Servlet - 在應用程序啓動時初始化類
- 4. 使用參數初始化
- 5. 如何初始化參數
- 6. 加載/初始化服務器啓動時的Java servlet
- 7. 如何禁用log4j servlet初始化?
- 8. 如何從servlet初始化方法獲取請求參數
- 9. 啓動時自動初始化庫(IES)
- 10. 調用Servlet時頁面初始化
- 11. 如何在初始化數據庫時顯示啓動畫面?
- 12. 如何參數化Web應用程序(不是servlet)的初始化
- 13. 初始化,初始化與參數和便利初始化
- 14. 啓動時參數化初始化的單例數據庫對象?
- 15. 用參數初始化
- 16. 啓動時控制初始化滯後
- 17. 如何在Eclipse啓動時禁用「初始化Java工具」?
- 18. 如何通過參數時我初始化一個工廠初始化在角
- 19. 如何在啓動時自動將啓動參數發送至初始化腳本?
- 20. 使用的初始化參數
- 21. 數據源初始化啓動
- 22. 初始化servlet時如何傳遞引用
- 23. AppEngine servlet的長時間初始化
- 24. 初始化數組時初始化System.AccessViolationException
- 25. 如何在初始化時使用UITableViewStyleGrouped?
- 26. 如何檢索JSP初始化參數
- 27. 如何初始化VAR Record參數
- 28. tomcat球衣servlet初始化
- 29. Servlet不會初始化
- 30. 在Servlet中初始化ApplicationContext
servlet + web.xml是歷史上第一個依賴注入框架 – dfa 2009-08-14 04:55:42