Search code examples
htmljsf-2xhtmljavabeansglassfish-3

How to pass String from Java applet in XHTML page to a managed bean


So as advised I am extending my earlier question to pick up the username of the system opening my web page and then authenticating that user accordingly. Thanks to some useful advice and after long hours of reading and testing I managed to write a very simple Java Applet which I embedded in login.xhtml page. However, now I'm stuck over next appropriate step in order to pass the username picked up by the java applet to the login managed bean. Allowing my web page to authenticate user based on their system's username without user actually having to put his username in the login.xhtml page. Meanwhile trying to search for the next appropriate step I feel my understanding going up and down and sideways. What best i could pick is that now in order to pass the username picked up from java applet to the login bean I will have to write JavaScript? But I am not sure if this is really what is required or there is another appropriate step to handle this more elegantly. Please excuse my limited knowledge on this.

Updates made based on the answer

Java Applet Code

  import java.applet.Applet;

    public class SSOApplet extends Applet {

        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        String sysUser = null;

        public String getSystemUsername() {
            try {
                sysUser = System.getProperty("user.name");
                return sysUser;
            } catch (Exception e) {
                System.out.println(e);
                return null;
            }

        }

    public void sendToJs() {
        String name = getSystemUsername();
        System.out.println("sendTOJS picked this username of user" + name);
        try {
            JSObject window = JSObject.getWindow(this);
            window.call("updateServer", new Object[] {name});
        } catch (JSException jse) {
            jse.printStackTrace();
        }
    }
    }

Code Snippet from my login.xhtml

<script type="text/javascript">
    function updateServer(name) {
        document.getElementById('username').value = name;
        document.getElementById('button').click();
    }
</script>
    <object>
            <param name="myApplet" value="SSOApplet.class" />
        </object>

Would be really helpful if someone could advice the next appropriate step. Thanks a lot in advance!

UserDaoBean Controller class

public boolean validateUser(String username) {
        try {

            String checkUser = (String) entityManager
                    .createQuery(
                            "select u.username from User u where u.username =:username")
                    .setParameter("username", username).getSingleResult();
            System.out.println("User found in database: " + checkUser);

            if (checkUser.equalsIgnoreCase(username)) {
                System.out.println("Loggin sucessful!");
                return true;
            }
        } catch (NoResultException e) {
            System.out.println("No result found in database");

            return false;
        }
        return false;

    }

Login Managed Bean

@ManagedBean(name = "loginBean")
@RequestScoped
public class LoginBean implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @EJB
    private UserDaoBean uDB;
    @EJB
    private UserGroupDaoBean uGDB;
    private User userId;

    SSOApplet myapplet = new SSOApplet();

    public String username = myapplet.getSystemUsername();

//  private String username;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String login() {
        FacesContext context = FacesContext.getCurrentInstance();
System.out.println("JS sent this username" + username);
        if (uDB.validateUser(username)) {
            userId = uDB.findUser(username);

            context.getExternalContext().getSessionMap().put("userId", userId);
            if (uGDB.validateGroup(userId)) {
                return "home.jsf?faces-redirect=true&amp;includeViewParams=true";
            }
            return "normalHome.jsf?faces-redirect=true&amp;includeViewParams=true";

        } else {
            FacesMessage message = new FacesMessage();
            message.setSeverity(FacesMessage.SEVERITY_ERROR);
            message.setSummary("Username doesn't exists! OR User is trying to login from someone else's account");
            context.addMessage("", message);
            return null;
        }
    }

Message Printed in Console

INFO: JS sent this usernamenull INFO: No result found in database INFO: WARNING: FacesMessage(s) have been enqueued, but may not have been displayed. sourceId=[severity=(ERROR 2), summary=(Username doesn't exists! OR User is trying to login from someone else's account), detail=(Username doesn't exists! OR User is trying to login from someone else's account)]

Exception after invoking Applet in Bean

WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
java.lang.ClassNotFoundException: netscape.javascript.JSException
    at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1509)
    at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1359)
    at beans.LoginBean.<init>(LoginBean.java:31)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
    at java.lang.Class.newInstance0(Class.java:372)
    at java.lang.Class.newInstance(Class.java:325)
    at com.sun.faces.mgbean.BeanBuilder.newBeanInstance(BeanBuilder.java:188)
    at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:102)
    at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:409)
    at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:269)
    at com.sun.faces.el.ManagedBeanELResolver.resolveBean(ManagedBeanELResolver.java:244)
    at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:116)
    at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
    at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
    at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:103)
    at com.sun.el.parser.AstValue.getTarget(AstValue.java:149)
    at com.sun.el.parser.AstValue.invoke(AstValue.java:237)
    at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:302)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
    at javax.faces.component.UICommand.broadcast(UICommand.java:315)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:722)

Solution

  • The easiest way is to make use of JSObject class, that enables communication of Java with JavaScript from an Applet, to call a JavaScript function with your string as parameter that will do its job of updating server-side managed beans.

    1. Applet to JavaScript part

    Introduce a following method in your applet:

    public void sendToJs() {
        String name = getSystemUsername();
        try {
            JSObject window = JSObject.getWindow(this);
            window.call("updateServer", new Object[] {name});
        } catch (JSException jse) {
            jse.printStackTrace();
        }
    }
    

    2. JavaScript updates

    function updateServer(name) {
        document.getElementById('username').value = name;
        document.getElementById('button').click();
    }
    

    3. JSF view to JSF backing bean

    <h:form prependId="false">
        <h:inputHidden id="username"/>
        <h:commandButton id="button" style="display:none">
            <f:ajax execute="@form/>
        </h:commandButton>
    </h:form>
    

    You can note that it'd be less code if Primefaces were used (look for <p:remoteCommand>) and a JS library like jQuery. Also note that username could be sent via POST/GET directly from the applet to a, for example, special dedicated servlet for processing (look for Apache's HttpClient).