我有一个包含多个WARS的Web应用程序。这些WARS都执行不同的功能,但有许多共同点:Css,Js,页眉和页脚,以及输出错误消息和事务确认的某些jsps。为了获得良好的可维护性,我不希望在多个位置拥有任何这些共享文件,而是一个位置,所以如果我对其进行编辑,则会显示在所有位置。只是基本的代码管理的东西,我认为我真的不需要在这里向任何人探讨这个问题。
对于Css和Js,我有一个根战,我只是绝对地解决了它的所有<link>
和<script>
标签。对于页眉和页脚(jsp片段),我正在使用<c:import>
并再次从根战中获取。我遇到的最后一个问题是共享jsps。
我经常在用户尝试执行操作后转发到这些jsps,这导致更改我们的数据库以确认事务已完成,或者在我想要向用户提供格式化消息的其他情况下。 Servlet可能看起来像这样......
public class sampleServlet extends ExtendedHttpServlet{ //ExtendedHttpServlet used to add common function to all of our HttpServlets including the foward function I use below.
public void doPost(HttpServletRequest request, HttpServletResponse response){
//Do some preperation stuff here, then...
try{
ModelJob.insertNewControlMJob(user, submit); //ModelJob is my inteface to our 'Job' Table Model...
submit.setSeqId(ModelJob.getSeqId(user, submit));
EmailFactory.SUBMIT_NEW_EMAIL.sendCMAdminEmail(user, submit, null);
EmailFactory.SUBMIT_NEW_EMAIL.sendUserEmail(user, submit, null);
req.setAttribute("color","Green");
req.setAttribute("message"," Job Successfully Submited. Sequece id : " + submit.getSeqId());
forward("/WEB-INF/TransactionResult.jsp", req, resp);
return;
}catch(Exception e){
req.setAttribute("color","Red");
req.setAttribute("message","Teradata failure : " + e.getMessage());
forward("/WEB-INF/TransactionResult.jsp", req, resp);
e.printStackTrace();
return;
}
}
}
这是我在超类ExtendedHttpServlet
中定义的上述方法:
protected void forward(String destination, HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
RequestDispatcher dispatcher = request.getRequestDispatcher(destination.toString());
dispatcher.forward(request, response);
}
但是有了这个,我必须在我的所有战争中都有一份TransactionResult.jsp副本,这会使维护变得有点痛苦。
我的问题是 - 有什么方法可以让我的前向功能在其他WAR中找到jsps转发。或者也许我可以在我的EAR中包含jsp并让前端找到jsp文件。我的理解是jsps只是文件,并在运行时由特殊的servlet编译,所以我不明白为什么这不可能?
感谢您提供任何建议/见解/帮助......
编辑因为有些人问过哪个服务器,我目前在Websphere v 7.0上
答案 0 :(得分:2)
您可以通过ServletContext#getContext()
获取其他servlet上下文,然后使用ServletContext#getRequestDispatcher()
提供的请求调度程序。首先,您需要配置服务器以启用“交叉上下文”选项。默认情况下,大多数服务器都禁用此功能目前还不清楚你正在使用哪个服务器,所以这里只是一些提示:对于Tomcat,检查crossContext
的{{1}}属性,对于Glassfish,检查context.xml
crossContextAllowed
属性}。
完成后,您将能够通过servlet中的上下文路径获取另一个glassfish-web.xml
,如下所示:
ServletContext
然后,您需要在所需资源的路径上从中获取ServletContext otherServletContext = getServletContext().getContext("/otherContextPath");
,并在其上调用forward()
,然后传递当前的HTTP servlet请求和响应。
RequestDispatcher
完全不同的替代方法是创建一个完全独立的Java项目(在Eclipse中称为“Web Fragment Project”),其中将共享JSP放在Java源文件夹的otherServletContext.getRequestDispatcher("/WEB-INF/TransactionResult.jsp").forward(request, response);
文件夹中。最后,使用此Java项目将所有WAR部署在/META-INF/resources
文件夹中的JAR文件中(在Eclipse中,将独立Java项目添加为所有Web项目的“部署程序集”应该足够)。您可以访问/WEB-INF/lib
文件夹中的JSP,就像它们在当前WAR中一样。
答案 1 :(得分:2)
如果您使用的是兼容servlet 3.0的服务器,我建议将所有共享Web资源(JSP,CSS文件等)打包在jar的META-INF/resources
目录中。将此jar放在每个webapp的WEB-INF/lib
中,这些共享资源将成为webapp的一部分,就像它们直接位于webapp的根目录一样。
答案 2 :(得分:1)
使用ServletContext.getContext()访问其他应用程序的上下文(在同一虚拟主机中)。获得该功能后,您可以使用该请求调度程序进行转发。
为了使上述功能正常运行,您可能需要启用某些供应商特定设置以覆盖默认安全性,请参阅此处:What does the crossContext attribute do in Tomcat? Does it enable session sharing?