问候,StackOverFlow 成员。我刚刚开始学习如何使用 Java Enterprise Beans 和 Java Persistence API 等技术编写支持 Web 的应用程序。
NetBeans 官方网站目前提供了一个捆绑包,(据说)允许我开发上述应用程序。一个大小约为 213 MB 的捆绑包。
现在是这样:假设我想模拟登录网站的过程。你知道,当我登录亚马逊时,我的会话数据存储在我的浏览器中,这就是他们能够显示诸如“欢迎,米格尔·马丁斯”或“米格尔·马丁斯的推荐购买”之类的内容的方式, 正确的?正确的。好吧,这就是我要做的(让我们从 index.jsp 开始):
<%@page import="beans.UserBeanRemote"%>
<%@page import="entities.SimplifiedUser"%>
<%@page import="beans.BeanFacade"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<%
UserBeanRemote userBean = BeanFacade.getUserBean();
userBean.setAuthenticatedUser(session, new SimplifiedUser("Miguel Martins", "password"));
SimplifiedUser authenticatedUser = userBean.getAuthenticatedUser(session);
if (authenticatedUser == null) {
out.write("No user is authenticated.");
}
else {
out.write("There is an authenticated user. Username: " + authenticatedUser.getUserName());
}
%>
</body>
</html>
很简单,对吧?我的意图是(显然)调用 setAuthenticatedUser 方法来存储会话数据,然后调用 getAuthenticatedUser 方法基本上询问“谁在这个 Web 浏览器中进行了身份验证?”
这就是我对其余部分的编程方式。请记住,这应该是一个简单/简约的应用程序,用于学习目的。
BeanFacade.java
package beans;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class BeanFacade {
private static InitialContext context;
private static void initializeContext() throws NamingException {
if (context == null) {
context = new InitialContext();
}
}
public static UserBeanRemote getUserBean() throws NamingException {
initializeContext();
return (UserBeanRemote) context.lookup("java:global/SimplifiedAuthentication/SimplifiedAuthentication-ejb/UserBean!beans.UserBeanRemote");
}
}
用户Bean.java
package beans;
import entities.SimplifiedUser;
import javax.ejb.Stateless;
import javax.servlet.http.HttpSession;
@Stateless
public class UserBean implements UserBeanRemote {
@Override
public void setAuthenticatedUser(HttpSession session, SimplifiedUser user) {
session.setAttribute("authenticated_user", user);
}
@Override
public SimplifiedUser getAuthenticatedUser(HttpSession session) {
return (SimplifiedUser) session.getAttribute("authenticated_user");
}
}
UserBeanRemote.java(显然是UserBean的远程接口)
package beans;
import entities.SimplifiedUser;
import javax.ejb.Remote;
import javax.servlet.http.HttpSession;
@Remote
public interface UserBeanRemote {
public void setAuthenticatedUser(HttpSession session, SimplifiedUser user);
public SimplifiedUser getAuthenticatedUser(HttpSession session);
}
最后但同样重要的是,SimplifiedUser.java。这就是我想要存储为会话数据的内容。
package entities;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class SimplifiedUser implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private String userName;
private String password;
public SimplifiedUser() {
}
public SimplifiedUser(String userName, String password) {
this.userName = userName;
this.password = password;
}
public String getUserName() {
return userName;
}
}
然而,令我沮丧的是,当我运行该项目时,它向我抛出了一个异常:
HTTP 状态 500 -
类型异常报告
信息
描述服务器遇到一个内部错误 () 阻止它完成这个请求。
例外
org.apache.jasper.JasperException: javax.ejb.EJBException: java.rmi.MarshalException: CORBA BAD_PARAM 1330446342 也许;嵌套异常是:java.io.NotSerializableException:
根本原因
javax.ejb.EJBException:java.rmi.MarshalException:CORBA BAD_PARAM 1330446342 也许;嵌套异常是:java.io.NotSerializableException:
根本原因
java.rmi.MarshalException: CORBA BAD_PARAM 1330446342 也许;嵌套异常是:java.io.NotSerializableException:
根本原因
java.io.NotSerializableException:
根本原因
org.omg.CORBA.BAD_PARAM:vmcid:OMG 次要代码:6 完成:也许
note 异常的完整堆栈跟踪及其根本原因可在 GlassFish Server Open Source Edition 3.0.1 日志中找到。GlassFish Server 开源版 3.0.1
而且,经过一些老式的调试(“注释掉”),似乎异常的原因是这样的:
session.setAttribute("authenticated_user", user);
和这个:
return (SimplifiedUser) session.getAttribute("authenticated_user");
这表明,不知何故,他们不希望我将我的用户数据(也不检索它)存储在 HttpSession 实例中。
有人知道为什么吗?首先将 Serializable 对象存储在 HttpSession 实例中不是完全合法的吗?如果是这样,那么这里到底发生了什么?
谢谢你,米格尔·马丁斯