Servlets 在由许多servlet扩展的基础servlet中,在WEB-INF中只加载一次自定义XML文件
我有一个普通的Servlets 在由许多servlet扩展的基础servlet中,在WEB-INF中只加载一次自定义XML文件,servlets,Servlets,我有一个普通的JavaEEWeb应用程序,它不使用任何类似Struts、JSF等框架。在这个Web应用程序中,我有一个自定义XML(custom config.XML)文件 其中包含特定于该应用程序的配置列表。我不想在web.xml文件中提及此配置信息。现在当容器第一次 初始化任何servlet,我需要读取custom config.xml文件中提到的配置信息。为了实现这一点,我创建了一个自定义Servlet类,比如CustomServlet,它 扩展自HttpServlet,我的所有servl
JavaEE
Web应用程序,它不使用任何类似Struts
、JSF
等框架。在这个Web应用程序中,我有一个自定义XML(custom config.XML
)文件
其中包含特定于该应用程序的配置列表。我不想在web.xml
文件中提及此配置信息。现在当容器第一次
初始化任何servlet,我需要读取custom config.xml
文件中提到的配置信息。为了实现这一点,我创建了一个自定义Servlet类,比如CustomServlet
,它
扩展自HttpServlet
,我的所有servlet都将扩展frm thisCustomServlet
。因此,当Serlvet类加载时,我的CustomServlet
类也将加载
在我的CustomServlet
类中,我有一个静态方法,该方法将加载custom config.xml
文件并理解本文中提到的配置
我有两个问题。
这是正确的方法吗?或者我应该把它放在CustomServlet
类的init()方法中吗?
如何从类路径加载custom config.xml
文件?我无法使用ServletConfig.getResourceAsStream()
,因为我正在尝试从静态方法加载custom config.xml
。首先,为什么要使用静态方法加载xml文件?静态方法属于类而不属于对象。在super类中有一个默认构造函数,并使其能够加载xml
public abstract class BaseServlet extends HttpServlet{
public Base(){
loadXml();
}
private void loadXml(){
...
}
}
public class Servlet1 extends BaseServlet {
...
}
如果xml是类路径,那么可以使用FileInputStream()加载xml文件。首先,为什么要使用静态方法加载xml文件?静态方法属于类而不属于对象。在super类中有一个默认构造函数,并使其能够加载xml
public abstract class BaseServlet extends HttpServlet{
public Base(){
loadXml();
}
private void loadXml(){
...
}
}
public class Servlet1 extends BaseServlet {
...
}
如果xml是类路径,则可以使用FileInputStream()加载xml文件。在静态方法中加载没有意义。从那里无法获取ServletContext
。你需要用这种方法来做。您可以使用一个静态原子布尔
来检查它是否已经加载到当前JVM中
public abstract class CustomServlet extends HttpServlet {
private static AtomicBoolean loaded = new AtomicBoolean();
@Override
public void init() throws ServletException {
if (!loaded.getAndSet(true)) {
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/custom-config.xml");
// ...
}
}
// ...
}
或者,使用ServletContextListener
@WebListener
public class Config implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent event) {
InputStream input = event.getServletContext().getResourceAsStream("/WEB-INF/custom-config.xml");
// ...
}
// ...
}
您可以将解析后的XML结果放在应用程序范围中,使其可供所有servlet使用
另见:
用静态方法做这件事毫无意义。从那里无法获取ServletContext
。你需要用这种方法来做。您可以使用一个静态原子布尔
来检查它是否已经加载到当前JVM中
public abstract class CustomServlet extends HttpServlet {
private static AtomicBoolean loaded = new AtomicBoolean();
@Override
public void init() throws ServletException {
if (!loaded.getAndSet(true)) {
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/custom-config.xml");
// ...
}
}
// ...
}
或者,使用ServletContextListener
@WebListener
public class Config implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent event) {
InputStream input = event.getServletContext().getResourceAsStream("/WEB-INF/custom-config.xml");
// ...
}
// ...
}
您可以将解析后的XML结果放在应用程序范围中,使其可供所有servlet使用
另见:
为什么它需要是一个静态方法?我想的是,当CustomServlet类第一次被类装入器装入内存时,只需要执行一次。因此,您认为servlet是在每个HTTP请求上新创建/初始化的,而不是在应用程序启动时只初始化一次?servlet应该只初始化一次。但我将拥有多个从这个CustomServlet类扩展而来的servlet。我认为CustomServlet的init()方法将再次被调用。如果我的理解错了,请纠正我。哦,那样。您可以添加一个静态AtomicBoolean
或继续使用ServletContextListener
方法。我已经编辑了答案。为什么它需要是一个静态方法呢?我认为这只需要在CustomServlet类第一次被类装入器装入内存时执行一次。所以,您认为servlet是在每个HTTP请求上新创建/初始化的,而不是在应用程序启动时只初始化一次?servlet应该只初始化一次。但我将拥有多个从这个CustomServlet类扩展而来的servlet。我认为CustomServlet的init()方法将再次被调用。如果我的理解错了,请纠正我。哦,那样。您可以添加一个静态AtomicBoolean
或继续使用ServletContextListener
方法。我已经编辑了答案。你最后的陈述值得投反对票。此外,在构造函数中执行此任务不允许您使用ServletContext#getResourceAsStream()
。您的上一条语句值得投反对票。此外,在构造函数中执行此操作不允许您使用ServletContext#getResourceAsStream()
。非常感谢您的指导。我需要解析的结果在所有servlet中都可用,并且需要基于XML创建一些类级变量。第一种方法应该是合适的,对吗?我更喜欢ServletContextListener
方法。执行原子/同步/静态操作总是很棘手。“在适当的时候做一次”更容易。只要将它存储在应用程序范围中,并在必要时从那里检索(当然可以使用(静态)帮助器方法)。如果XML文件以Javabean的风格转换(例如JAXB可以这样做),并通过getServletContext().setAttribute(“config”,config)
存储在应用程序范围中,然后你应该能够在EL中轻松访问它,例如,${config.foo}
等等。哦,太好了。。我们正在使用JAXB访问XML文档。非常感谢您的指导。我需要解析的结果在所有servlet中都可用,并且需要基于XML创建一些类级变量。第一种方法应该是合适的,对吗?我更喜欢ServletContextListener
方法。执行原子/同步/静态操作总是很棘手。“在适当的时候做一次”更容易。只需将其存储在应用程序范围中,并在必要时从中检索(当然,您可以使用(stat