First of all, this question indicates a misunderstanding of purpose of "REST web services" in general. The question concretely asks to perform two rather unusual tasks with a REST web service:
- Manipulating the HTTP session associated with the request.
- Redirecting to a HTML page managed by a stateful MVC framework as response.
Both squarely contradict the stateless nature of REST. Those tasks aren't supposed to be performed by a REST web service. Moreover, REST web services are primarily intented to be used by programmatic clients (e.g. JavaScript or Java code), not by webbrowsers which consume HTML pages. You normally don't enter the URL of a REST webservice in browser's address bar in order to see a HTML page. You normally enter the URL of a HTML page in browser's address bar. That HTML page can in turn be produced by a HTML form based MVC framework such as JSF.
In your specific case, after the programmatic client has retrieved the unique
ID from the REST web service, then the programmatic client should in turn all by itself fire a new request to the JSF web application. E.g. as follows in Java based client (below example assumes it's a plain servlet, but it can be anything else as you said yourself):
String uniqueId = restClient.getUniqueId(userId, token);
String url = "http://example.com/context/login.xhtml?uniqueId=" + URLEncoder.encode(uniqueId, "UTF-8");
response.sendRedirect(url);
In the target JSF web application, just use <f:viewParam>
/<f:viewAction>
the usual way in order to grab the unique ID and perform business actions based on that. E.g. as below in login.xhtml
:
<f:metadata>
<f:viewParam name="uniqueId" value="#{authenticator.uniqueId}" />
<f:viewAction action="#{authenticator.check}" />
</f:metadata>
@ManagedBean
@RequestScoped
public class Authenticator {
private String uniqueId;
@EJB
private UserService service;
public String check() {
FacesContext context = FacesContext.getCurrentInstance();
User user = service.authenticate(uniqueId);
if (user != null) {
context.getExternalContext().getSessionMap().put("user", user);
return "/somehome.xhtml?faces-redirect=true";
}
else {
context.addMessage(null, new FacesMessage("Invalid token"));
return null; // Or some error page.
}
}
// Getter/setter.
}
Perhaps the REST webservice could for convenience even return the full URL including the unique ID so that the client doesn't need to worry about the target URL.
String uniqueIdURL = restClient.getUniqueIdURL(userId, token);
response.sendRedirect(uniqueIdURL);
On the other hand, there's a reasonable chance that you just misunderstood the functional requirement and you can just directly process the user ID and token in the JSF web application, the more likely if it runs at the same server as the REST web service and also uses HTTPS. Just add an extra <f:viewParam>
and do the same business service logic as the JAX-RS resource in the <f:viewAction>
method.
<f:metadata>
<f:viewParam name="userId" value="#{authenticator.userId}" />
<f:viewParam name="token" value="#{authenticator.token}" />
<f:viewAction action="#{authenticator.check}" />
</f:metadata>
See also: