I’m new to web services in general and have been doing a lot of research on it, but I’m currently unable to capture request headers I need for authentication purposes.
Here’s the scenario: I have an Android client calling a login() method on my JAX-RS RESTful web service, after adding a username/password combination to the request headers. The web service (which runs on JBoss AS 7.1) should then capture those headers.
The problem is everytime this login() method is called, the request seems to have not being serviced yet, thus leading to an IllegalStateException upon executing WebServiceContext.getMessageContext().
I’ve tried adding @PostConstruct annotation to the method’s header, but to no avail. When I do this the method doesn’t seem to be initialized at all. Instead I have a ClassNotFoundException upon calling it.
How can I get through this issue? I’ve been stuck on this for days and tried multiple different approaches both at the client and the web service to capture those headers, but they would either not apply to the project’s architecture or simply not work as expected.
Here’s the service’s interface:
@ApplicationPath("/apppath")
@Path("/wspath")
public interface LoginService {
@GET
@Path("/login")
@Produces(MediaType.APPLICATION_JSON)
public String login();
}
Here’s the service’s implementation:
@Stateless
@Local(LoginService.class)
public class LoginServiceImpl implements LoginService {
@Resource
WebServiceContext wsContext;
@Override
public String login() {
// This line throws an IllegalStateException.
MessageContext msgContext = wsContext.getMessageContext();
// TODO: Capture authentication data from headers.
@SuppressWarnings("unchecked")
Map<String, List<String>> headers = (Map<String, List<String>>) msgContext.get(MessageContext.HTTP_REQUEST_HEADERS);
// Dummy return for testing purposes.
return "It works" + headers.toString();
}
}
And here’s a simple JUnit test code I’m working on to try to fix the problem on client side.
public class LoginServiceTest {
@Test
public void test() {
String mEmail = "a@a.com";
String mPassword = "aaaa";
HttpGet request = new HttpGet("http://localhost:8080/apppath/wspath/login");
String auth = Base64.encodeBytes((mEmail + ":" + mPassword).getBytes());
request.addHeader("Authorization", "Basic " + auth);
HttpClient httpClient = new DefaultHttpClient();
try {
InputStream inputStream = httpClient.execute(request).getEntity().getContent();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String wsReturn;
while ((wsReturn = bufferedReader.readLine()) != null) {
System.out.println(wsReturn);
}
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
That’s not the right way to access service context in a JAX-RS servive, the
WebServiceContextclass is injected into JAX-WS web services. In a JAX-RS service class you can use the@Contextannotation to have theHttpServletRequestrequest object injected and ask it for the headers.For example:
You can look at this link to get more information about JAX-RS or go through the Java EE 6 Tutorial.