Сеансовый объект без сохранения состояния с переменными экземпляра

Любая логика, имеющая отношение, что отображено в представлении, должна быть делегирована к вспомогательному методу, как методы в модели строго для обработки данных.

Вот то, что Вы могли сделать:

# In the helper...

def link_to_thing(text, thing)
  (thing.url?) ? link_to(text, thing_path(thing)) : link_to(text, thing.url)
end

# In the view...

<%= link_to_thing("text", @thing) %>
15
задан Jim Ferrans 30 October 2009 в 02:51
поделиться

5 ответов

Я бы вообще не стал использовать переменную экземпляра в сессионном компоненте без сохранения состояния. Независимо от того, с какой причиной проблемы вы столкнулись, вероятно, вы все равно не захотите это делать.

10
ответ дан 1 December 2019 в 00:41
поделиться

When I read What is a Session Bean? section of the J2EE 1.4 tutorial:

Stateless Session Beans

A stateless session bean does not maintain a conversational state for a particular client. When a client invokes the method of a stateless bean, the bean's instance variables may contain a state, but only for the duration of the invocation. When the method is finished, the state is no longer retained. Except during method invocation, all instances of a stateless bean are equivalent, allowing the EJB container to assign an instance to any client.

In your case, the call to methodB() from methodA() will be on the same instance and is equivalent to this.methodB(). I'm thus tend to say that methodB() can't output something else that the value that what was passed to methodA().

This is confirmed by the first sentence in section 7.11.8 in the EJB 2.0 spec: "The container must ensure that only one thread can be executing an instance at any time". This means you cannot come to a situation where data (in your instance variables) from different clients (threads) will be mixed. You are ensured unique access to the instance variables until methodA() has returned!

That said, I'm not saying that you don't have a problem somewhere. But I don't think that your pseudo code is equivalent.

(EDIT: Having read some comments to the OP's question, there is now clearly a doubt about the pseudo code and semantic used. I'm clarifying possible consequences below.)

As underlined by Rocket Surgeon, what do you mean exactly by class variable? Do you really mean class variable as opposed to instance variable? If yes, the pseudo code doesn't reflect it but this will clearly lead to unpredictable behavior. Actually, from section 24.1.2 (and first point) in the EJB 2.0 spec, it is clear that you are not allowed to write data to a class variable (although you can do it). There must be a good reason for this :)

24
ответ дан 1 December 2019 в 00:41
поделиться

Вероятная причина проблемы в том, что контейнер использует один и тот же объект в двух запросах (то есть в двух потоках) одновременно. Таким образом, первый поток переходит к строке, которая вызывает методB, а затем следующий поток переходит к коду, который вызывает методB, а затем первый поток выполняет вызов методаB, вызывая проблему. Во всяком случае, это объяснило бы его поведение. Кажется, это не соответствует спецификации, но это может быть просто ошибкой.

В общем, даже если разрешено, сохранение состояния в bean-компоненте - не лучшая идея. Это приводит к путанице в коде и легко может привести к ошибкам, когда вы забываете начинать заново со всем своим состоянием при каждом вызове метода.

Было бы гораздо лучше просто передавать эти объекты между методами, и это позволило бы избежать всех проблем .

5
ответ дан 1 December 2019 в 00:41
поделиться

Because this is very strange I performed a quick test with Netbeans and my local Glassfish 2.1.

  1. Create a new project using Samples->Java EE->Servlet Stateless. This creates an enterprise project with a simple stateless bean and a servlet that uses it.
  2. I modified the stateless bean to look like this, as close to your example as possible I think.

    @Stateless
    открытый класс StatelessSessionBean реализует StatelessSession {
    
     String clName;
    
     private void testNa () {
     System.out.println (clName);
     }
    
     public String sayHello (String name) {
     this.clName = имя;
     testNa ();
     return "Testcase";
     }
    }
    

Это работает как надо. Я не знаю, какой редактор вы используете, но если это Netbeans, может быть интересно запустить его самостоятельно.

2
ответ дан 1 December 2019 в 00:41
поделиться

Все зависит от того, что вы подразумеваете под «переменной уровня класса». Переменная класса должна иметь модификатор static. Если clName не работает, то каждый экземпляр вашего сеансового компонента без сохранения состояния имеет свою собственную копию clName . Ваш сервер Java EE, вероятно, создал пул из двух или более экземпляров сессионного компонента без сохранения состояния, и каждый из ваших вызовов testNa () и sayHello () отправляется произвольному экземпляру. .

0
ответ дан 1 December 2019 в 00:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: