我处于 glassfish-jee/jsf-jpa 场景中, 当我尝试访问我的 ManagerBean 之一中的 protected 函数(我不满足 @RolesAllowed 指定的要求)时,我会收到 web.xml 中配置的登录页面提示。 登录后,我被重定向到通用主页(home.xhtml)。
由于我的函数返回 void(它在数据库中执行一些业务),我希望重定向到登录后的同一页面。
当我尝试访问 protected 页面时,重定向功能非常有效,但是使用不返回任何内容的 protected 函数,似乎“我从无处而来,也将去往无处”(originalURL 为 null,请参阅下面的代码详情)
我在 StackOverflow 上搜索了一整天,我读了很多答案,但没有一个起作用,到目前为止,这些是我的代码行..
登录.xhtml
<h:form>
<h:outputLabel for="username" value="Username" />
<h:inputText id="username" value="#{LoginManagedBean.username}"
required="true" />
<h:message for="username" />
<br />
<h:outputLabel for="password" value="Password" />
<h:inputSecret id="password" value="#{LoginManagedBean.password}"
required="true" />
<h:message for="password" />
<br />
<h:commandButton value="Login" action="#{LoginManagedBean.login}" />
<h:messages globalOnly="true" />
</h:form>
LoginManagedBean.java
package userInterfaces;
//imports
/**
* Session Bean implementation class LoginManagedBean
*/
@ManagedBean(name="LoginManagedBean")
@ViewScoped
public class LoginManagedBean {
//getters and setters
private String username;
private String password;
private String originalURL;
public LoginManagedBean() {
// TODO Auto-generated constructor stub
}
@PostConstruct
public void init() {
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
originalURL = (String) externalContext.getRequestMap().get(RequestDispatcher.FORWARD_REQUEST_URI);
String uri = ((HttpServletRequest) externalContext.getRequest()).getRequestURI();
if (originalURL == null) {
originalURL = externalContext.getRequestContextPath() + "/home.xhtml";
} else {
String originalQuery = (String) externalContext.getRequestMap().get(RequestDispatcher.FORWARD_QUERY_STRING);
if (originalQuery != null) {
originalURL += "?" + originalQuery;
}
}
}
public void login() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext externalContext = context.getExternalContext();
HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
try {
request.login(username, password);
externalContext.redirect(originalURL);
} catch (ServletException e) {
context.addMessage(null, new FacesMessage("Unknown login"));
}
}
public void logout() throws IOException {
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
externalContext.invalidateSession();
externalContext.redirect(externalContext.getRequestContextPath() + "/login.xhtml");
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>TravelDreamDynamicWeb</display-name>
<welcome-file-list>
<welcome-file>home.jsf</welcome-file>
</welcome-file-list>
<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>/faces/*</url-pattern>
<url-pattern>*.xhtml</url-pattern>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.xhtml</form-login-page>
<form-error-page>/loginError.xhtml</form-error-page>
</form-login-config>
</login-config>
<error-page>
<error-code>403</error-code>
<location>/loginError.xhtml</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/login.xhtml</location>
</error-page>
<security-constraint>
<web-resource-collection>
<web-resource-name>Pagine Cliente</web-resource-name>
<description></description>
<url-pattern>/cliente/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>CLIENTE</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Pagine Impiegato</web-resource-name>
<description></description>
<url-pattern>/impiegato/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>IMPIEGATO</role-name>
</auth-constraint>
</security-constraint>
</web-app>
具体函数的实现(仅供引用,很抱歉它是意大利语和英语的混合体
@Override
@RolesAllowed({"CLIENTE"})
public void aggiungiACarrelloMgr(int idPacchetto) {
String username=FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
Query query=em.createQuery("SELECT u FROM UtenteRegistrato u WHERE u.username='"+username+"'");
List<UtenteRegistrato> utente= query.getResultList();
int idCarrello=utente.get(0).getIdCarrello();
Carrello carrello=new Carrello(new CarrelloPK(idCarrello,idPacchetto));
em.persist(carrello);
}
“VisualizzaPacchetti.xhtml”中的命令按钮(对未登录的用户可见)尝试调用 protected 函数(在启动 javax.ejb.AccessLocalException 后触发转发到登录页面)
<h:commandButton action="#{PacchettoManagedBean.aggiungiACarrello(PacchettoManagedBean.pacchetti.get(statoPack.index).idPacchetto)}" value="+CARRELLO" />
感谢您的宝贵时间, 如果我的解释中遗漏了一些内容,请告诉我,对我的英语不好感到抱歉
马西莫
最佳答案
您好,Massimo,欢迎来到 Stack Overflow。我快速检查了您的代码,看来您的 LoginManagedBean 是 ViewScoped,这意味着它会保持状态,直到 View 相同。在您的情况下,您请求的 login.xhtml 可能与您的原始 View 不同,因此 LoginManagedBean 的状态丢失。
尝试在 LoginManagedBean
中将 @ViewScoped
更改为 @SessionScoped
。
我不知道它是否符合你的逻辑,以防它不只是为登录相关的东西创建一个 session 范围的bean,因为你无论如何都需要它。看看你的方法名称,我假设你正在构建一个电子商务(我也是意大利人),所以你可能已经有一个 session 范围的 bean 了。
关于java - 登录后重定向不起作用(jsf-glassfish),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21355205/