2

I would like other web application (in .net or any other) to call my JAX-RS web service to set and open my JSF page with some passed values.

E.g.

  • Another web application just pass the userId and a token to open an entry page.
  • User will complete the entry and service will return the uniqueId for created entry.

I am confused in how I can set JSF context parameters and open that JSF page using JAX-RS. Can anyone give idea about how to set value of JSF session scoped managed bean using web service?

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
Jitesh
  • 1,374
  • 10
  • 19
  • JAX-RS and JSF are complementary technologies. You cannot open a jsf page from JAX-RS. If you want to open a jsf page from a client, you can do an http get to the jsf page and pass the relevant parameters in as request parameters. OR you can call a separate JAX-RS **service** in the same webapp as the jsf pages, set the parameters via that and then in a second request open the JSF page in an http get without passing in the parameters. Just make sure the parameters are stored in a long enough scope. – Kukeltje Mar 16 '16 at 09:43
  • OK, but now the question is how to set a long scope variable? E.g. trying to set a session variable in servlet using JAX-RS using @Context. But it is not working as the other servlets are not getting the values – Jitesh Mar 16 '16 at 11:34
  • Servlets? Use jax-rs with cdi and jsf picks it up to... go for modern standards – Kukeltje Mar 16 '16 at 11:51
  • I am trying to set value of session scoped managed bean but FacesContext.getCurrentInstance() giving null in webservice – Jitesh Mar 18 '16 at 05:12

3 Answers3

2

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:

  1. Manipulating the HTTP session associated with the request.
  2. 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:

Community
  • 1
  • 1
BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • Thanks @BalusC. I was waiting for your reply. But my issue is to pass some parameters (e.g. user,org. unit, location, etc.) and based on that open a page of JSF Application – Jitesh Mar 19 '16 at 04:53
  • Even I tried @Kukeltje comment got the url back but I was not able to set the higher scope variable. So is there any alternate way for doing this? – Jitesh Mar 19 '16 at 05:07
  • If both JAX-RS and JSF run on same server and basically share the same backend, then just pass those parameters to a JSF page instead as shown above. See also last paragraph of the answer. It looks like you overthought the solution and JAX-RS is unnecessary in the requirement. It's only useful for programmatic clients not for regular webbrowsers. – BalusC Mar 19 '16 at 09:25
  • But want to pass the parameters without displaying it in URL – Jitesh Mar 20 '16 at 15:21
  • Then just send a redirect after retriving it? The current `f:viewAction` example does that already in successful case. – BalusC Mar 20 '16 at 17:52
0

Try this in your code,

return new Viewable("/index", "FOO");

Or,

RequestDispatcher rd = request.getRequestDispatcher("{url}");
rd.forward(request, response);

Or,

return Response.status(myCode).entity(new Viewable("/index", "FOO")).build();
Thilina Sampath
  • 2,860
  • 5
  • 32
  • 59
0

try these example working in using jersey,

@GET
public Response get() {
    URI uri=new URI("http://nohost/context");
    Viewable viewable=new Viewable("/index", "FOO");
    return Response.ok(viewable).build();
}

to return something different use this approach:

@GET
public Response get() {
    int statusCode=204;
    Viewable myViewable=new Viewable("/index","FOO");
    return Response.status(statusCode).entity(myViewable).build();
}

Hope that helpe

Thilina Sampath
  • 2,860
  • 5
  • 32
  • 59