2013-10-17 4 views
0

나는 새로운 db 연결을 생성하는 커스텀 인터셉터를 사용하고 있으며 액션을 실행하기 전에 현재 액션에이 연결을 설정한다. 그런 다음 인터셉터가 연결을 닫습니다.Struts 2의 ActionContext가 현재 요청에 고유합니까?

내가 다른 클래스와이 DB 연결을 공유 할 수있는 편리한 방법을 찾고 있어요/작용으로 사용된다 (예 : 모델 등) 정적 메서드. 예를 들어 User.get(id) 또는 User.getEmail(id)과 같은 정적 메서드를 각 메서드에 별도로 db 연결을 전달하지 않고 호출 할 수 있습니다.

ServletActionContext.getActionContext().put("db", db);

및 다음 I과 같은 정적 법에서이 DB 연결에 액세스 할 수있다 :

I는 수행하여 인터셉터에서 ActionContext 상 DB 연결을 설정할 수

public class User implements Model 
{ 
    public static String getEmail(int id) 
    { 
     Connection db = 
     (Connection) ServletActionContext.getActionContext().get("db"); 
     //... 
    } 
} 

내 질문은 새로운 ActionContext 모든 주어진 요청을 생성 할 것이다, 그래서 새로운 DB 연결마다 사용되는 것을 확신 할 수 있습니까? 내가 500 사람들이 mysite.com/fooAction를 방문했다면, 나는 그 (500 개) 요청의 각 고유 ActionContext에 생성되며, User.getEmail()를 호출 할 때마다 지정된 요청에 고유 한 경우에만 DB 연결에 액세스 것이라고 확신 할 수 예컨대?

감사합니다.

답변

2

내 질문은 새로운 ActionContext에 모든 주어진 요청을 생성 할 것이다, 그래서 새로운 DB 연결 각 때 사용됩니다 확신 할 수 있습니까?

는 스레드 안전의 ThreadLocal ActionContext에 사용하기 때문에

. Struts 2는 각각의 요청에 대한 ActionContext를 생성하고, 각 요청에는 자체 스레드가있다. 그래서 네, 만약 당신이 새로운 연결을 생성하고 그것을 ActionContext에 저장하면 모든 스레드는 자체 연결을 갖게 될 것입니다. 그러나 이것은 ActionContext에 연결을 저장하는 것을 권장하지 않습니다. 왜냐하면 이것은 Struts 2와 좋은 관계가 아니기 때문이며, 또한 서비스가 웹 특정 클래스를 호출해서는 안되기 때문입니다.

From Struts 2 Javadoc:

ActionContext에이 동작이 실행되는 상황이다. 각 컨텍스트 기본적 동작 등

ActionContext에 값이 ActionContext에 스레드 당 고유 에 저장 즉 로컬 스레드 세션 파라미터 로케일 같은 실행에 필요한 객체의 용기이다. 자세한 내용은 ActionContext.ActionContextThreadLocal 클래스를 참조하십시오. 의 이점은 사용자 특정 동작 컨텍스트에 대해 걱정할 필요가 없다는 것입니다.

ActionContext context = ActionContext.getContext(); 마지막으로, 스레드 로컬 사용의 때문에 당신은 당신의 행동이 스레드 안전 만들기에 대해 걱정할 필요가 없습니다.

ActionContext에 발췌 :

public class ActionContext implements Serializable { 

    static ThreadLocal<ActionContext> actionContext = new ThreadLocal<ActionContext>(); 
    .... 
} 
+0

질문 있습니다 ..의 경우 beginnin g는 내 클래스의, 나는 다음 줄을했다 :'private static Connection db = (Connection) ServletActionContext.getActionContext(). get ("db");'이것은 스레드 로컬에서도 실행될 것인가 아니면 더 나은가? 각각의 메소드 내에서 db를 개별적으로 얻으시겠습니까? –

+1

스레드 로컬이 아닌 @ClickUpvote. 또한 클래스 로더가 클래스를로드하자마자 static이 호출되기 때문에 NullPointerException이 발생합니다. Struts 2는 초기화되지 않았으며 요청도 없습니다. 따라서 메서드 내부에서 호출해야합니다. –

+0

고마워요. 정말로 도움을 주셔서 감사합니다. 이것은 당신이 오랫동안 곤란을 겪을 수있는 문제 중 하나이거나 해결책이 없다고 생각하는 것입니다. –

3

질문에 대답하려면 :

내 질문은, 새로운 ActionContext에 모든 주어진 요청에 대해 생성 될 수를, 그래서 확신 할 수 새 db 연결이 각 시간 사용됩니까?

예. 그렇습니다. 참고 자료는 java-doc입니다. Alfredo Osorio에 의해 제공되는 것과 비슷하며 2.3.x 버전만을 나타냅니다.

struts2 버전을 사용하고 있다고 말할 수 있습니까?

나는

ServletActionContext.getActionContext() 

를 사용하는 버전을 찾을 수 없습니다 대신 서명은

ServletActionContext.getActionContext(javax.servlet.http.HttpServletRequest) 

는 스레드 로컬 정적 인 여전히 ActionContext에 인스턴스 고유 인에 관한 comment에 대답하는 것입니다 요청할 때마다 수행하기 때문에

ActionContext.getContext() 

내부적으로 스레드 로컬 인스턴스에서 get을 호출합니다.

actionContext.get() 

다음과 같은 점에서 post을 참조하십시오.

그러나

ServletActionContext.getActionContext(javax.servlet.http.HttpServletRequest) 

스레드 로컬를 사용하는 것보다 다른 경로를 취하는 방법, 깊게 파고. 다음은

getValueStack

getActionContext

public static ActionContext getActionContext(HttpServletRequest req) { 
    ValueStack vs = getValueStack(req); 
    if (vs != null) { 
     return new ActionContext(vs.getContext()); 
    } else { 
     return null; 
    } 
} 

public static ValueStack getValueStack(HttpServletRequest req) { 
    return (ValueStack) req.getAttribute(STRUTS_VALUESTACK_KEY); 
} 

몇 가지 추가 참조 (소스 코드)입니다.

ActionContext

OgnlValueStack

ValueStack

다음 글도 도움이 될 수 있습니다.

  1. will-a-new-actioncontext-and-valuestack-be-created-for-every-new-action-object

  2. struts2-actioncontext-and-valuestack

업데이트 2 :

ActionChaining 경우에 관련되고 언급 here (상기 링크 1)로 추가하고 싶어 작용은 자체 인터셉터 스택과 결과로 호출됩니다.

그러나 실행 된 스레드는 동일합니다.

값 스택과 매개 변수가 복사됩니다. See - ActionChainResult # execute (ActionInvocation).

chain-invocation이 완료되면 action-context의 상태가 재설정됩니다. (DefaultActionProxy # execute() 참조).

부분적 정보 : 동작 호출이 DefaultActionInvocation # init (ActionProxy)에서 설정되었지만 재설정 된 경우 또는 재설정 된 위치를 확인할 수 없습니다.

출처 :

DefaultActionInvocation

DefaultActionProxy

DefaultActionProxyFactory

ActionChainResult

FilterDispatcher(Deprecated)

+0

내가 사용하고있는 서명은'ServletActionContext.getContext()'입니다. HttpServletRequest를 전달할 필요는 없습니다. 최신 버전 (2.3.15.2)을 사용하고 있습니다. 어떤 아이디어? –

+0

그리고 http://stackoverflow.com/questions/19755939/struts-2-resetting-action-instance-while-still-in-interceptor에 도움을 줄 수 있다면 위대 할 수도 있습니다. –

+0

@ClickUpvote 메소드'ServletActionContext.getContext()'는 실제로는 ActionContext로부터 온 것입니다. [ActionContext.getContext()] (http://grepcode.com/file/repo1.maven.org/maven2/org.apache.struts.xwork/xwork-core/2.3.15/com/opensymphony/xwork2/ActionContext 참조) .java # ActionContext.getContext % 28 % 29). 'actionContext'가 ThreadLocal 변수 인 곳에서 위에서 언급 한 것처럼'actionContext.get()'을 호출합니다. 이 메서드는 질문의 메서드 서명과 다릅니다. 아마도 당신은 그에 따라 당신의 질문을 업데이트 할 수 있습니다. –

관련 문제