web-dev-qa-db-ja.com

Java Webサービスを使用しているときにHttpServletRequestオブジェクトにアクセスするにはどうすればよいですか?

Java 6、Tomcat 6、Metroを使用しています。WebServiceアノテーションとWebMethodアノテーションを使用してWebサービスを公開しています。リクエストに関する情報を取得したいのですが、次のコードを試しました。ただし、wsCtxtは常にnullです。not WebServiceContextに対してnullを取得するにはどのような手順を実行する必要がありますか。

言い換えると、次の行を実行してwsCtxtのnull以外の値を取得するにはどうすればよいですか?

MessageContext msgCtxt = wsCtxt.getMessageContext();

@WebService
public class MyService{

  @Resource
  WebServiceContext wsCtxt;

  @WebMethod
  public void myWebMethod(){
    MessageContext msgCtxt = wsCtxt.getMessageContext();
    HttpServletRequest req = (HttpServletRequest)msgCtxt.get(MessageContext.SERVLET_REQUEST);
    String clientIP = req.getRemoteAddr();
  }
15
Steve McLeod

変数の名前をwsCtxtからwsContextに変更するか、name属性を@Resourceアノテーションに割り当てることをお勧めします。 @ Resourceに関するJ2eeチュートリアル は、変数の名前がルックアップの一部として使用されることを示します。異なるタイプのリソースを注入するGlassfishでリソース注入を使用すると、これと同じ問題が発生しました。

あなたの正しい名前はwsContextではないかもしれませんが。私はこれをフォローしています Javaのヒント 。変数名wsCtxtが気に入った場合は、変数宣言でname属性を使用します。

@Resource(name="wsContext") WebServiceContext wsCtxt;

12
James A Wilson

次のコードは、Java 5、Tomcat6およびMetroを使用して機能します

Java 6のWSサポートと使用しているMetroのバージョンの間に競合がある可能性があります。Java 5ビルド?

@WebService
public class Sample {
    @WebMethod
    public void sample() {
        HttpSession session = findSession();
        //Stuff

    }
    private HttpSession findSession() {
        MessageContext mc = wsContext.getMessageContext();
        HttpServletRequest request = (HttpServletRequest)mc.get(MessageContext.SERVLET_REQUEST);
        return request.getSession();
    }
    @Resource
    private WebServiceContext wsContext;
}
3
Garth Gilmour

私はまだこの問題を抱えています。これが私の回避策で、リクエストをThreadLocal変数に入れるServletRequestListenerを書くことでした。次に、WebServiceはThreadLocalから要求を取得できます。言い換えれば、私は自分にとってうまくいかないものを再実装しています。

リスナーは次のとおりです。

import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;

public class SDMXRequestListener implements ServletRequestListener {

    public SDMXRequestListener() {
    }

    public void requestDestroyed(ServletRequestEvent event) {
    }

    public void requestInitialized(ServletRequestEvent event) {
        final ServletRequest request = event.getServletRequest();
        ServletRequestStore.setServletRequest(request);
    }

}

ThreadLocalラッパーは次のとおりです。

import javax.servlet.ServletRequest;

public class ServletRequestStore {

    private final static ThreadLocal<ServletRequest> servletRequests = new ThreadLocal<ServletRequest>();

    public static void setServletRequest(ServletRequest request) {
        servletRequests.set(request);
    }

    public static ServletRequest getServletRequest() {
        return servletRequests.get();
    }

}

そしてweb.xmlの配線:

  <listener>
        <listener-class>ecb.sdw.webservices.SDMXRequestListener</listener-class>
    </listener>

Webサービスは、次のコードを使用して要求を取得します。

最終的なHttpServletRequestリクエスト=(HttpServletRequest)ServletRequestStore.getServletRequest();

3
Steve McLeod

たぶん、javax.ws.rs.core.Contextアノテーションは、リソースではなく、探しているもののためのものですか?

1
asterite