다음 문제에 대해 필사적입니다. JSF/PrimeFaces (Wildfly 10)에서는 AJAX 호출과 비 AJAX 호출을 모두 사용합니다. 세션이 만료되고 누군가 시스템과 상호 작용 (클릭)하면 login.xhtml
으로 리디렉션되어야하고 사용자에게 새 로그인을 요청해야합니다. 문제는 그것이 AJAX가 아닌 컨트롤에 대해서만 작동한다는 것입니다. 내가 AJAX 컨트롤을 클릭하면, 내가 로그인 페이지에 도착,하지만 난 로그인/암호를 입력하면, 나는 다음과 같은 오류 얻을 : 나는 다음과 같은 클래스 수많은 자료를 읽고 구현 한AJAX 호출에서 부분 응답 메시지와 함께 페이지 리디렉션이 실패합니다.
<partial-response id="j_id1">
<changes>
<update id="j_id1:javax.faces.ViewState:0">
<![CDATA[ 982009515771098472:-6468147585577406798 ]]>
</update>
</changes>
</partial-response>
:
을 JsfAjaxPhaseListener.java
public class JsfAjaxPhaseListener implements PhaseListener {
public void beforePhase(PhaseEvent event) {
}
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
@Override
public void afterPhase(PhaseEvent event) {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest httpRequest = (HttpServletRequest) context.getExternalContext().getRequest();
if (httpRequest.getRequestedSessionId() != null && !httpRequest.isRequestedSessionIdValid()) {
String facesRequestHeader = httpRequest.getHeader("Faces-Request");
boolean isAjaxRequest = facesRequestHeader != null && facesRequestHeader.equals("partial/ajax");
if (isAjaxRequest) {
try {
context.getExternalContext().redirect("/admin/login.xhtml");
} catch (IOException ex) {
Logger.getLogger(JsfAjaxPhaseListener.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
SessionExceptionHandler.java
,536,913,632 우리는 다양한 리디렉션, 통화의 다양한 변형을 시도<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>facelets.SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
10
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>admin/index.xhtml</welcome-file>
</welcome-file-list>
<security-constraint>
<display-name>securityConstraint</display-name>
<web-resource-collection>
<web-resource-name>resources</web-resource-name>
<url-pattern>/admin/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
<auth-constraint>
<role-name>Administrator</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>incomakerSecurityDomain</realm-name>
<form-login-config>
<form-login-page>/login.xhtml</form-login-page>
<form-error-page>/errorLogin.xhtml</form-error-page>
</form-login-config>
</login-config>
<security-role>
<role-name>Administrator</role-name>
</security-role>
<error-page>
<error-code>500</error-code>
<location>/errorCatchall.xhtml</location>
</error-page>
</web-app>
, 그것에서 이틀을 보냈다 : 같은 10
public class SessionExceptionHandler extends ExceptionHandlerWrapper {
private static final Logger LOGGER = LoggerFactory.getLogger(SessionExceptionHandler.class);
private ExceptionHandler wrapped;
SessionExceptionHandler(ExceptionHandler exception) {
this.wrapped = exception;
}
@Override
public ExceptionHandler getWrapped() {
return wrapped;
}
@Override
public void handle() throws FacesException {
final Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator();
while (i.hasNext()) {
ExceptionQueuedEvent event = i.next();
ExceptionQueuedEventContext context
= (ExceptionQueuedEventContext) event.getSource();
Throwable t = context.getException();
if (t instanceof ViewExpiredException) {
ViewExpiredException vee =(ViewExpiredException) t;
FacesContext fc =FacesContext.getCurrentInstance();
Map<String, Object> requestMap = fc.getExternalContext().getRequestMap();
NavigationHandler nav =
fc.getApplication().getNavigationHandler();
try {
((ConfigurableNavigationHandler)nav).performNavigation("admin/login.xhtml?faces-redirect=true");
fc.renderResponse();
} finally {
i.remove();
}
}
}
getWrapped().handle();
}
}
SessionExceptionHandlerFactory.java
public class SessionExceptionHandlerFactory extends ExceptionHandlerFactory {
private ExceptionHandlerFactory parent;
public SessionExceptionHandlerFactory(ExceptionHandlerFactory parent) {
this.parent = parent;
}
@Override
public ExceptionHandler getExceptionHandler() {
ExceptionHandler handler = new SessionExceptionHandler(parent.getExceptionHandler());
return handler;
}
}
web.xml을 보인다 , 그러나 아무것도 도움이되지 않습니다. 수동으로 로그인 페이지를 다시로드하면 모든 것이 작동합니다. 프로그래밍 방식으로 다시로드하려고하면 부분 응답이 항상 실패합니다.
도움 주셔서 감사합니다.
이 정보가 유용할까요? http://stackoverflow.com/q/35841356 – BalusC
감사합니다. @BalusC. 불행히도, 그것은 작동하지 않는 것 같습니다. 첫째, 우리는 OmniFaces가 아닌 PrimeFaces를 사용합니다. context.getExternalContext() 전에 invalidateSession()을 추가하려했으나 성공하지 못했습니다. 도움이 될 것 같아요 context.getExternalContext(). 리디렉션 대신 ConfigurableNavigationHandler.performNavigation() 사용하는 것입니다,하지만 나는 이유를 잘 모르며 해결 방법이 아닌 해결 방법을 고려해야합니다. :-( – TomS
OmniFaces는 PrimeFaces와 같은 컴포넌트 라이브러리가 아니며 모든 JSF 기반 애플리케이션에서 사용할 수있는 유틸리티 라이브러리입니다 – BalusC