[JAX-RS] Use @Provider to leverage JAX-RS provider auto-discovery feature.

Please see the result in the new blog: http://dev.vvirlan.com/jax-rs-use-provider-to-leverage-jax-rs-provider-auto-discovery-feature/

Advertisements

[JAX-RS] Some good auth resources

http://stackoverflow.com/questions/26777083/best-practice-for-rest-token-based-authentication-with-jax-rs-and-jersey

http://www.developerscrappad.com/1814/java/java-ee/rest-jax-rs/java-ee-7-jax-rs-2-0-simple-rest-api-authentication-authorization-with-custom-http-header/

https://jersey.java.net/documentation/latest/security.html

https://www.ibm.com/support/knowledgecenter/SSAW57_8.5.5/com.ibm.websphere.nd.doc/ae/twbs_jaxrs_impl_securejaxrs_webcont.html

 

 

 

[WTF] Criteria API

This is the best representation of what I want to say about JPA criteria API:

http://www.odi.ch/weblog/posting.php?posting=667

EntityManager em = ...;
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);
Root<Pet> pet = cq.from(Pet.class);
cq.select(pet);
TypedQuery<Pet> q = em.createQuery(cq);
List<Pet> allPets = q.getResultList();

The equivalent JPQL query is:

FROM Pet

The equivalent SQL query is:

SELECT * FROM Pet

Clearly SQL is too simple and boring. You really need a bullshit API to produce a simple SQL query. Of course this will ease maintenance, improve performance, reduce code, prevent bugs, speed up development by a factor of 10 and reduce your project cost by 99% at least. A classic case of overengineering.

Java EE 7 WebSocket example

1. Createa a Java EE Web application called MyWebSocket for example.
2. In index.html:

<!DOCTYPE html>
<html>
    <head>
        <title>Start Page</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script language="javascript">
            var ws;
            function connect() {
                ws = new WebSocket("ws://localhost:8080/MyWebSocket/sockOne");
                ws.onmessage = onMessage;
            }
            function onMessage(evt) {
                var dataarr = evt.data;
                document.getElementById("valueElement").innerHTML = dataarr;
            }
            window.addEventListener("load", connect, false);
        </script>
    </head>
    <body>
        <h1>Hello World!</h1>
        <b>Value: </b>
        <b id="valueElement">no data yet</b>
    </body>
</html>

2. Create a class Called WebSocketEndpoint. Here the most important annotations are @ServerEndpoint, @OnOpen, @OnClose and @OnError, in these methods you put whatever you want to get executed when these events happen:

package com.vvirlan.websocket;

import java.io.IOException;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

/**
 *
 * @author vvirlan
 */
@ServerEndpoint("/sockOne")
public class WebSocketEndpoint {

    private static final Logger LOGGER = Logger.getLogger("WebSocketEndpoint");
    private static Queue<Session> sessionQueue = new ConcurrentLinkedQueue<>();

    public static void send(double number) {
        String toSend = String.format("%f", number);
        try {
            for (Session session : sessionQueue) {
                session.getBasicRemote().sendText(toSend);
                LOGGER.log(Level.INFO, "Sent: {0}", toSend);
            }
        } catch (IOException e) {
            LOGGER.log(Level.SEVERE, e.toString());
        }
    }

    @OnOpen
    public void openConnection(Session session) {
        sessionQueue.add(session);
        LOGGER.log(Level.INFO, "Connection opened");
    }

    @OnClose
    public void closeConnection(Session session) {
        sessionQueue.remove(session);
        LOGGER.log(Level.INFO, "Connection closed");
    }

    @OnError
    public void error(Session session, Throwable th) {
        sessionQueue.remove(session);
        LOGGER.log(Level.WARNING, "Connection errorred");
        LOGGER.log(Level.WARNING, th.toString());

    }
}

3. The bean which will produce our fake data. It gets injected a TimerService as a @Resource and when @Timeout happens it invokes the send method of our endpoint:

package com.vvirlan.websocket;

import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.Timeout;
import javax.ejb.TimerConfig;
import javax.ejb.TimerService;

/**
 *
 * @author vvirlan
 * Generates a double every second and calls the endpoint for updating the clients
 */
@Startup
@Singleton
public class GeneratorBean {
    @Resource TimerService timerService;
    private Random random;
    private volatile double number = 777.0;
    private static final Logger logger = Logger.getLogger("GeneratorBean");
    
    @PostConstruct
    public void init() {
        logger.log(Level.INFO, "Initializing EJB");
        random = new Random();
        timerService.createIntervalTimer(1000, 1000, new TimerConfig());
    }
    
    @Timeout
    public void timeout() {
        number = 1.5 * (random.nextInt(100));
        WebSocketEndpoint.send(number);
    }
}

JSF simple ajax example

Here is a simple AJAX example in JSF (run on Glassfish).
Just to note: for sending the value to the bean you use the execute attribute of f:ajax, and for displaying the output from the beans’s getter, you use the render attribute.

1. pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.mycompany</groupId>
    <artifactId>ajaxtest</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>ajaxtest</name>

    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${endorsed.dir}</outputDirectory>
                            <silent>true</silent>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>javax</groupId>
                                    <artifactId>javaee-endorsed-api</artifactId>
                                    <version>7.0</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

2. The xhtml page:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        Hello from Facelets
        
        <h:form>
            <h:inputText id="msg" value="#{myBean.text}"/>
        <h:commandButton id="submit" value="Submit">
            <f:ajax event="click"  execute="msg" render="outText"/>
        </h:commandButton>
            <h:outputText value="The message: #{myBean.text}" id="outText">
            </h:outputText>
            
            </h:form>
        
    </h:body>
</html>

3. The Bean:

package com.mycompany.ajaxtest;

import java.io.Serializable;
import javax.enterprise.inject.Model;

/**
 *
 * @author vvirlan
 */
@Model
public class MyBean implements Serializable {
    
    private String text = "defaullt";
    
    
    public void message() {
        System.out.println("The message "+text);
        
    }

    public String getText() {
        System.out.println("getText message "+text);
        return text;
    }

    public void setText(String text) {
        System.out.println("setText message "+text);
        this.text = text;
    }
}

[JAX-WS] Simple Dispatch Client Example

Here is an example of a Dispatch type Java SE WebService client.
1. A sample Web Service (Running as a Dynamic Web Application in Glassfish):

package com.vvirlan;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.xml.ws.soap.Addressing;
/**
 *
 * @author vladimir
 */
@Addressing(enabled = true, required = true)
@WebService(serviceName = "NewWebService")
public class NewWebService {

    @WebMethod(operationName = "hello")
    public String hello(@WebParam(name = "name") String txt) {
        return "Hello " + txt + " !";
    }
}

2. Here is the client (A simple Java SE application). Make sure to start the previous application first:

package dispatchclient;

import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import javax.xml.ws.soap.AddressingFeature;
import javax.xml.ws.soap.SOAPBinding;

/**
 *
 * @author vladimir
 */
public class DispatchClient {

    public static void main(String[] args) {

        QName port = new QName("http://vvirlan.com/", "PortName");
        Service service = Service.create(port);
        service.addPort(port, SOAPBinding.SOAP11HTTP_MTOM_BINDING, "http://localhost:8080/SimpleJaxWs/NewWebService");
        Dispatch<SOAPMessage> dispatch = service.createDispatch(port, SOAPMessage.class, Service.Mode.MESSAGE, new AddressingFeature());
        SOAPBinding binding = (SOAPBinding) dispatch.getBinding();
        
        binding.setMTOMEnabled(true);
        SOAPMessage request = null;
        try {
            request = MessageFactory.newInstance().createMessage();
            SOAPBody reqSoapBody = request.getSOAPBody();
            SOAPElement methodName;
            QName method = new QName("http://vvirlan.com/", "hello", "vvir");
            QName name = new QName("name");

            methodName = reqSoapBody.addChildElement(method);
            SOAPElement nameParam = methodName.addChildElement(name);
            nameParam.addTextNode("Vladimir");

        } catch (SOAPException e) {
            e.printStackTrace();
        }

        SOAPMessage response = dispatch.invoke(request);
        try {
            SOAPBody resSoapBody = response.getSOAPBody();
            System.out.println(resSoapBody.getTextContent());
        } catch (SOAPException e) {
            e.printStackTrace();
        }

    }
}

This will generate a SOAP request like:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:vvir="http://vvirlan.com/">
    <soapenv:Header/>
    <soapenv:Body>
        <vvir:hello>
            <name>Vladimir</name>
        </vvir:hello>
    </soapenv:Body>
</soapenv:Envelope>

And the response will be

<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <ns2:helloResponse xmlns:ns2="http://vvirlan.com/">
            <return>Hello Vladimir !</return>
        </ns2:helloResponse>
    </S:Body>
</S:Envelope>

web.xml examples for all versions of Servlet

1. Servlet 3.1

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
		 http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
</web-app>

2. Servlet 3.0

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
	      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	      version="3.0">
</web-app>

3. Servlet 2.5

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
	      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	      http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	      version="2.5">
</web-app>

4. Servlet 2.4

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
	      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	      xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
	      http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
	      version="2.4">

  <display-name>Servlet 2.4 Web Application</display-name>
</web-app>

5. Servlet 2.3

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Servlet 2.3 Web Application</display-name>
</web-app>

[JMS] Standalone JMS Client

If you were trying to make a JMS client to run as a standalone application

1. Create a java project.
2. Add as dependencies:

java-ee api and
C:\installs\glassfish\glassfish-4.1\glassfish\lib\gf-client.jar
(adjust path)
3. Create main class:

package jmsclient;

import java.util.Hashtable;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueConnectionFactory;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import static javax.naming.Context.INITIAL_CONTEXT_FACTORY;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class JmsClient {

    //@Resource(mappedName = "jms/Factory")
    private static ConnectionFactory connectionFactory;

    //@Resource(mappedName = "jms/Queue")
    private static Queue queue;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {

            try {
                Properties props = new Properties();
                props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.enterprise.naming.SerialInitContextFactory");
                Context initialContext = new InitialContext(props);

                connectionFactory = (QueueConnectionFactory) initialContext.lookup("jms/Factory");
                queue = (Queue) initialContext.lookup("jms/Queue");

            } catch (NamingException ex) {
                Logger.getLogger(JmsClient.class.getName()).log(Level.SEVERE, null, ex);
            }

            Connection connection = connectionFactory.createConnection();
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            MessageProducer messageProducer = session.createProducer(queue);
            TextMessage message = session.createTextMessage();
            message.setText("This is message 1");
            messageProducer.send(message);

        } catch (JMSException ex) {
            ex.printStackTrace();
            Logger.getLogger(JmsClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

4. Create “jms/Factory” and “jms/Queue” JMS resources in Glassfish
5. Create and deploy your JMS EJB SimpleMessageBean


package com.vvirlan.ejb;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

@MessageDriven(mappedName = "jms/Queue", activationConfig = {
    @ActivationConfigProperty(propertyName = "aknowledgeMode",
            propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "destinationType",
            propertyValue = "javax.jms.Queue")
})
public class SimpleMessageBean implements MessageListener {

    @Resource
    private MessageDrivenContext mdc;

    @Override
    public void onMessage(Message message) {
        TextMessage msg = null;
        try {

            if (message instanceof TextMessage) {
                msg = (TextMessage) message;
                Logger.getLogger(SimpleMessageBean.class.getName()).log(Level.SEVERE, null, msg.getText());
                System.out.println(msg.getText());
            }
        } catch (JMSException e) {
            e.printStackTrace();
            mdc.setRollbackOnly();;
        }
    }
}

6. Run your client. You should see the message in the logs: This is message 1

[Starter] EJB Session Bean based Web Server and Servlet client

EJB Session Bean based Web Server and Servlet client in Netbeans

1. Create a Class Library project which will hold your Remote EJB interfaces

1

2. Create new interface called WsHello

package com.vvirlan.ejb;
import javax.ejb.Remote;
@Remote
public interface WsHello {
    public String sayHello(String name);
}

3. Create a new Project of type EJB Module
3
4. Create a new class in the EJB Module this class will implement your interface defined in the Class Library you defined earlier

package com.vvirlan.ejb;

import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebService;
@Stateless
@WebService
public class WsHelloImpl implements WsHello {
    private String msg = "Hello! ";
    @WebMethod
    public String sayHello(String name) {
        return msg + name;
    }
}

5. Create a Web Application and a new Servlet in it. Here you add the annotation @EJB to autowire your interface.

package com.vvirlan.servlet;

import com.vvirlan.ejb.HelloServiceBean;
import com.vvirlan.ejb.WsHello;
import java.io.IOException;
import java.io.PrintWriter;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class WsServlet extends HttpServlet {

    @EJB
    private WsHello hello;
  
    
    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        String result = hello.sayHello("Vlad");
        try (PrintWriter out = response.getWriter()) {
            /* TODO output your page here. You may use following sample code. */
            out.println("<!DOCTYPE html>");
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet WsServlet</title>");            
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>Servlet WsServlet at " + request.getContextPath() + "</h1>");
            out.println("<h1>Servlet WsServlet at " + result + "</h1>");
            out.println("</body>");
            out.println("</html>");
        }
    }
}

6. Add the Class Library as a dependency in your web application project. Now all errors should solve by themselves.

2