我想在Servlet过滤器中访问FacesContext, 有时(不是每次)我都会遇到内部服务器错误。
import java.io.IOException;
import javax.faces.context.FacesContext;
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.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.codec.binary.Base64;
public class AuthenticationFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
UserDetailsBean userBean = null;
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
FacesContext context = FacesUtil.getFacesContext(req, res);
String param = req.getParameter("PARAMETER_VALUES");
if((param!=null && param.isEmpty()) || !isAuthenticated(req)) {
if(param != null && !param.isEmpty()) {
userBean = new UserDetailsBean();
setCookies(param, userBean, req, res);
FacesUtil.setManagedBeanInView(context, "userDetailsBean", userBean);
request.setAttribute("userDetailsBean", userBean);
chain.doFilter(request, response);
}
else {
String homePage = "http://homePage";
res.sendRedirect(homePage);
}
}
else {
try {
if(!context.isPostback()){
userBean = getUserBeanFromCookies(req.getCookies());
request.setAttribute("userDetailsBean", userBean);
}
} catch(Exception e) {
userBean = getUserBeanFromCookies(req.getCookies());
request.setAttribute("userDetailsBean", userBean);
}
chain.doFilter(request, response);
}
}
private UserDetailsBean getUserBeanFromCookies(Cookie[] cookies) {
UserDetailsBean userBean = new UserDetailsBean();
for(Cookie c: cookies) {
String cName = c.getName();
if("userId".equals(cName)) {
userBean.setUserNbr(c.getValue());
}
else if("userEmail".equals(cName)) {
userBean.setEmail(c.getValue());
}
else if("firstName".equals(cName)) {
userBean.setFirstName(c.getValue());
}
else if("lastName".equals(cName)) {
userBean.setLastName(c.getValue());
}
}
return userBean;
}
private boolean setCookies(String param, UserDetailsBean userBean, HttpServletRequest request, HttpServletResponse response) {
boolean validUser = false;
if(param != null) {
String strParams = new String(Base64.decodeBase64(param.getBytes()));
String[] pairs = strParams.split("&");
for(String pp: pairs) {
String[] s = pp.split("=");
if("p_userid".equals(s[0])) {
userBean.setUserNbr(s[1]);
validUser = true;
}
else if("p_email".equals(s[0])){
userBean.setEmail(s[1]);
}
else if("p_first_name".equals(s[0])) {
userBean.setFirstName(s[1]);
}
else if("p_last_name".equals(s[0])) {
userBean.setLastName(s[1]);
}
}
}
if(validUser) {
String cookiePath = "/";
Cookie cookie = new Cookie("userId", userBean.getUserNbr());
cookie.setMaxAge(-1); // Expire time. -1 = by end of current session, 0 = immediately expire it, otherwise just the lifetime in seconds.
cookie.setPath(cookiePath);
response.addCookie(cookie);
cookie = new Cookie("userEmail", userBean.getEmail());
cookie.setMaxAge(-1);
cookie.setPath(cookiePath);
response.addCookie(cookie);
cookie = new Cookie("firstName",userBean.getFirstName());
cookie.setMaxAge(-1);
cookie.setPath(cookiePath);
response.addCookie(cookie);
cookie = new Cookie("lastName", userBean.getLastName());
cookie.setMaxAge(-1);
cookie.setPath(cookiePath);
response.addCookie(cookie);
}
return validUser;
}
public boolean isAuthenticated(HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
if(cookies == null) {
return false;
}
for(Cookie c: cookies) {
String cName = c.getName();
if("userId".equals(cName)) {
if(c.getValue() == null || c.getValue().isEmpty()) {
return false;
}
else {
return true;
}
}
}
return false;
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ViewScoped
@ManagedBean(name="userDetailsBean")
public class UserDetailsBean implements Serializable {
private String userNbr;
private String email;
private String firstName;
private String lastName;
public String getUserNbr() {
return userNbr;
}
public void setUserNbr(String userNbr) {
this.userNbr = userNbr;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
import javax.faces.FactoryFinder;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextFactory;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.lifecycle.LifecycleFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FacesUtil {
public static FacesContext getFacesContext(HttpServletRequest request, HttpServletResponse response) {
FacesContext facesContext = FacesContext.getCurrentInstance();
if (facesContext == null) {
LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
FacesContextFactory contextFactory = (FacesContextFactory) FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
facesContext = contextFactory.getFacesContext(request.getSession().getServletContext(), request, response, lifecycle);
UIViewRoot view = facesContext.getApplication().getViewHandler().createView(facesContext, "");
facesContext.setViewRoot(view);
FacesContextWrapper.setCurrentInstance(facesContext);
}
return facesContext;
}
// Wrap the protected FacesContext.setCurrentInstance() in a inner class.
private static abstract class FacesContextWrapper extends FacesContext {
protected static void setCurrentInstance(FacesContext facesContext) {
FacesContext.setCurrentInstance(facesContext);
}
}
}
这里的身份验证实际上是由其他应用程序处理的, 一旦用户登录,它将发送带有一些信息的请求参数(PARAMETER_VALUES)。
我们正在使用JSF 2.1.9& Tomcat 6.0.35。 我在Filter的这一行收到错误 FacesContext context = FacesUtil.getFacesContext(req,res);
错误堆栈跟踪:
Exception=java.lang.NullPointerException
at org.apache.catalina.connector.Request.parseParameters(Request.java:2599)
at org.apache.catalina.connector.Request.getParameter(Request.java:1106)
at org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:355)
at javax.servlet.ServletRequestWrapper.getParameter(ServletRequestWrapper.java:158)
at com.sun.faces.context.RequestParameterMap.containsKey(RequestParameterMap.java:99)
at java.util.Collections$UnmodifiableMap.containsKey(Collections.java:1280)
at com.sun.faces.renderkit.ResponseStateManagerImpl.isPostback(ResponseStateManagerImpl.java:84)
at com.sun.faces.context.FacesContextImpl.isPostback(FacesContextImpl.java:207)
at com.sandbox.external.site.test.filter.AuthenticationFilter.doFilter(AuthenticationFilter.java:36)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.ha.tcp.ReplicationValve.invoke(ReplicationValve.java:347)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:396)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
当我在错误说明的行中看到Tomcat 6.0.35的源代码时, if(!getMethod()。equalsIgnoreCase(“POST”)) 返回; 在这里找不到太多信息。
答案 0 :(得分:5)
您无法访问过滤器中的FacesContext
,因为FacesContext
已初始化FacesServlet
,并且在请求到达servlet之前会处理您的过滤器。
如果它有时有效,可能是因为副作用(JSF为每个请求创建一个FacesContext,每个请求都绑定到一个线程,并且线程被servlet容器重用)。
我也想知道你为什么要通过实施自己的安全过滤器来重新发明轮子。已有的解决方案可用(如Spring Security或标准JEE security)并经过充分测试。
有关BalusC的更多信息,请参阅此问题: