Glassfish v3 + NetBeans + Симулятор простой аутентификации: почему я получаю исключение, связанное с сериализацией? - PullRequest
0 голосов
/ 11 октября 2010

Приветствую, коллеги по StackOverFlow.Я только начал изучать, как программировать веб-приложения с использованием таких технологий, как Java Enterprise Beans и Java Persistence API.

Официальный веб-сайт NetBeans в настоящее время предлагает пакет, который (предположительно) позволяет мне разрабатывать указанные приложения.Пакет с приблизительным размером 213 МБ.

Теперь сделка: предположим, я хочу смоделировать процесс входа на веб-сайт.Знаете, когда я захожу в Amazon, мои данные сеанса хранятся в моем браузере, и именно так они могут отображать такие вещи, как «Добро пожаловать, Мигель Мартинс» или «Рекомендованные покупки для Мигеля Мартинса», право?Правильно.Ну, вот что я делаю (давайте начнем с 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, чтобы в основном спросить «кто аутентифицирован в этом веб-браузере?»

И вот как я запрограммировал все остальное.Помните, что это должно быть простое / минималистичное приложение для целей обучения.

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");
    }
}

UserBean.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 Open Source Edition 3.0.1

И после некоторой устаревшей отладки («комментируя вещи») кажется, что причиной исключения является следующее:

session.setAttribute("authenticated_user", user);

И это:

return (SimplifiedUser) session.getAttribute("authenticated_user");

Что указывает на то, что почему-то они не хотят, чтобы я сохранял мои пользовательские данные (и не получал их) внутри экземпляра HttpSession.

Кто-нибудь знает, почему это?Разве не законно в первую очередь хранить объект Serializable внутри экземпляра HttpSession?Если так, то что здесь происходит в мире?

Спасибо, Мигель Мартинс

1 Ответ

0 голосов
/ 13 октября 2010

Мои извинения, коллеги из StackOverflow. После некоторого очень поучительного обсуждения между мной и одним из моих коллег по проекту, я понял ошибку моих путей. Короче говоря, кажется, что исключение связано с тем, что все, что я передаю в EJB, должно быть сериализуемым. И естественно, экземпляр HttpSession не сериализуем.

Даже если бы это было сериализуемо, этот мой коллега ясно, без тени сомнения, доказал мне, что экземпляр HttpSession никогда не должен покидать веб-уровень и передаваться на какой-то другой уровень (в данном случае, уровень EJB). Следовательно, то, что я пытался сделать ... Я делал это неправильно.

Правильный способ, по мнению самого моего коллеги, состоит в создании целого нового класса User, который будет использоваться исключительно на веб-уровне (т. Е. В итоге у нас будет два класса, класс User, который содержит символ @ Аннотация объекта и другой класс, который впоследствии будет известен как «UserViewModel», следуя шаблону разработки, известному как шаблон ViewModel. По сути, этот «второй класс пользователя» является сокращенной версией исходного класса, предназначенного для использования исключительно в веб-уровень.

Так что спасибо моему коллеге, который показал мне ошибку моего пути. Если кому-то есть что сказать по этому поводу, пожалуйста, говорите.

...