Come posso accedere all'oggetto HttpServletRequest quando utilizzo i servizi Web Java
-
02-07-2019 - |
Domanda
Sto usando Java 6, Tomcat 6 e Metro. Uso le annotazioni WebService e WebMethod per esporre il mio servizio web. Vorrei ottenere informazioni sulla richiesta. Ho provato il seguente codice, ma wsCtxt è sempre nullo. Quale passo devo fare per non ottenere null per WebServiceContext.
In altre parole: come posso eseguire la seguente riga per ottenere un valore non nullo per wsCtxt?
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();
}
Soluzione
Ti consiglio di rinominare la variabile da wsCtxt a wsContext o di assegnare l'attributo name all'annotazione @Resource. Il tutorial J2ee su @Resource indica che il nome di la variabile viene utilizzata come parte della ricerca. Ho riscontrato questo stesso problema usando l'iniezione di risorse in Glassfish iniettando un diverso tipo di risorsa.
Anche se il tuo nome corretto potrebbe non essere wsContext. Sto seguendo questo java tip . Se ti piace il nome della variabile wsCtxt, usa l'attributo name nella dichiarazione della variabile:
@Resource (name = " wsContext ") WebServiceContext wsCtxt;
Altri suggerimenti
Ho ancora questo problema. Ecco il mio trucco era scrivere un ServletRequestListener che inserisca la richiesta in una var ThreadLocal. Quindi il WebService può ottenere la richiesta da ThreadLocal. In altre parole, sto reimplementando qualcosa che non funziona per me.
Ecco l'ascoltatore:
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);
}
}
Ecco il wrapper 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();
}
}
E il cablaggio web.xml:
<listener>
<listener-class>ecb.sdw.webservices.SDMXRequestListener</listener-class>
</listener>
Il servizio Web utilizza il seguente codice per ottenere la richiesta:
richiesta HttpServletRequest finale = (HttpServletRequest) ServletRequestStore.getServletRequest ();
Il seguente codice funziona per me usando Java 5, Tomcat 6 e Metro
Potrebbe essere che ci sia un conflitto tra il supporto WS in Java 6 e la versione di Metro in uso. L'hai provato su una build 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;
}
Forse l'annotazione javax.ws.rs.core.Context è per quello che stai cercando, invece di Resource?