【发布时间】:2011-02-27 22:05:01
【问题描述】:
目前我正在更新一个 jsf 项目,并意识到当 jsf 页面收到请求并且页面返回给客户端时,我在浏览器中完全看到页面,尽管事实上我没有点击,但对同一页面的新请求到达后,我意识到了一个关于项目的奇怪事情我正在使用导航处理程序进行导航的任何事情。我在我的项目中使用 jsf(myfaces),richfaces。
我在这些类上设置了两个断点,我看到大多数页面(不是全部)发送请求并且请求通过 menufilter -> myfacesservletwrapper(此时浏览器完全显示页面)在此 menufilter 中断另一个相同请求之后页。
package com.endersys.itap.ui;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.endersys.itap.ui.module.user.User;
import com.endersys.itap.ui.module.user.UserManager;
import java.io.FileInputStream;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
public class MenuFilter implements Filter {
private String ALLOWED = "login.xhtml";
private String ALLOWED_FOLDER = "a4j";
private static boolean searchEnabled = false;
private static boolean syslogServiceEnabled = false;
private static String SYSLOG_PAGE= "syslogsettings.xhtml";
private Properties conf;
private String SEARCH_PAGE= "search.xhtml";
private static final String BASE_PATH = "/opt/itap/logmonitor/";
private static final String CONF_PATH = BASE_PATH + "etc/logmonitor.properties";
private static Logger logger = Logger.getLogger(MenuFilter.class.getName());
public void destroy() {
}
public void init(FilterConfig arg0) throws ServletException {
if(loadConfiguration())
{
if(conf.getProperty("search_enabled").equalsIgnoreCase("true"))
{
searchEnabled = true;
}
try
{
if(conf.getProperty("syslog_enabled").equalsIgnoreCase("true"))
{
syslogServiceEnabled = true;
}
}catch(Exception exc)
{
exc.printStackTrace();
}
}
}
private boolean loadConfiguration()
{
conf = new Properties();
FileInputStream fis = null;
try {
fis = new FileInputStream(CONF_PATH);
conf.load(fis);
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
return false;
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
return true;
}
/**
* TODO Unit test this function extensively.
*/
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
try
{
UserManager userManager = (UserManager) ((HttpServletRequest) req)
.getSession(true).getAttribute("userManager");
// http://localhost:8080/itapgui-v2*/index.xhtml*
String relativePath = ((HttpServletRequest) req).getServletPath();
// Servlet path has a leading "/" but our menu items do not.
relativePath = relativePath.substring(1);
// http://localhost:8080*/itapgui-v2*/index.xhtml
String contextPath = ((HttpServletRequest) req).getContextPath();
if(!searchEnabled && relativePath.endsWith(SEARCH_PAGE))
{
((HttpServletResponse) res).sendRedirect(contextPath
+ "/index.xhtml");
return;
}
if(!syslogServiceEnabled && relativePath.endsWith(SYSLOG_PAGE))
{
((HttpServletResponse) res).sendRedirect(contextPath
+ "/index.xhtml");
return;
}
if (!relativePath.endsWith(ALLOWED)
&& !relativePath.startsWith(ALLOWED_FOLDER)) {
// Permission required.
// if (relativePath.endsWith("logout.xhtml")) {
// ((HttpServletRequest) req).getSession(true).invalidate();
// ((HttpServletResponse) res).sendRedirect(contextPath
// + "/login.xhtml");
// return; // Required.
// }
if (userManager == null) {
// Not authorized.
if(relativePath != null && relativePath.endsWith("index.xhtml"))
{
((HttpServletResponse) res).sendRedirect(contextPath
+ "/login.xhtml");
}else
{
((HttpServletResponse) res).sendRedirect(contextPath
+ "/login.xhtml?session=expired");
}
return; // Required.
}
User user = userManager.getUser();
if (user.getId() == null) {
// Not authorized.
((HttpServletResponse) res).sendRedirect(contextPath
+ "/login.xhtml");
return; // Required.
} else if (user.getId() != 1) {
Menu menu = (Menu) ((HttpServletRequest) req).getSession(true)
.getAttribute("menu");
MenuItem item = menu.getItemByPath(relativePath);
if(item != null)
{
if (!userManager.access(item.getPerms())) {
((HttpServletResponse) res).sendRedirect(contextPath
+ "/error.xhtml");
return; // Required.
}
}
}
}
chain.doFilter((HttpServletRequest) req, (HttpServletResponse) res);
}catch(Exception exc)
{
exc.printStackTrace();
if(exc instanceof IOException)
{
throw (IOException) exc;
}
else if(exc instanceof ServletException)
{
throw (ServletException) exc;
}
}
}
}
public class MyFacesServletWrapper extends MyFacesServlet {
private static final String CONN_ERROR_URI = "/dberror.xhtml";
private static final String OTHER_ERROR_URI = "/errors.xhtml";
@Override
public void service(ServletRequest request, ServletResponse response) throws IOException, ServletException {
try {
super.service(request, response);
} catch (ServletException e) {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
//if an database exception has occured
if (ExceptionUtils.indexOfType(e, javax.persistence.PersistenceException.class) != -1) {
res.sendRedirect(req.getContextPath() + CONN_ERROR_URI);
}
else {
// add the exception to the session scope attribute
// to show stack trace
req.getSession().setAttribute("exception", e);
res.sendRedirect(req.getContextPath() + OTHER_ERROR_URI);
}
}
}
}
【问题讨论】:
-
我还没有解决问题,但我认为它是由richfaces引起的。但我不确定,任何人都对richfaces和ajax有很大的帮助。
-
很难说。 Richfaces 提出两个请求的原因有很多。我猜想有多个请求来自客户端,这在您的 servlet 或过滤器中不是问题。不过我可能会误解你的英语。
-
当我点击某个动作源时,是否可以发送两个请求。例如,如果有一个页面在另一个表单中包含一个表单
-
有可能。我经常看到它是由于将“oncomplete”和“rerender”标签与一些 javascript 重新渲染相结合的结果。