Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Tuesday, November 25, 2014

Creating a simple WebSocket Server to send ActiveMQ events from a queue

WebSocket 

WebSocket is a protocol providing full-duplex communications channels over a single TCP connection. The WebSocket protocol was standardized by the IETF as RFC 6455 in 2011, and the WebSocket API in Web IDL is being standardized by the W3C.- Wikipedia

ActiveMQ


Apache ActiveMQ is a popular open source messaging server. it supports many cross language clients and protocols. Mainly it supports JMS 1.1 and J2EE 1.4

This application dequeue events(or whatever things in the queue) and send them to a TCP clients using websocket.

This is the WebSocketHandler class. This contains the methods that use to initiate websocket connection with clients. In onConnect method, connection is established with the ActiveMQ and starts dequeuing events from the queue. Please make sure create a queue named "mydataque" in ActiveMQ before continuing.


/**

 * Created by IntelliJ IDEA.

 * User: Chann

 * Date: 11/23/14

 * Time: 11:06 PM

 * To change this template use File | Settings | File Templates.

 */

import java.io.IOException;

import java.util.concurrent.CountDownLatch;

import java.util.concurrent.Future;

import java.util.concurrent.TimeUnit;



import org.apache.activemq.ActiveMQConnectionFactory;

import org.eclipse.jetty.websocket.api.Session;

import org.eclipse.jetty.websocket.api.StatusCode;

import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;

import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;

import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;

import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;

import org.eclipse.jetty.websocket.api.annotations.WebSocket;



import javax.jms.*;



@WebSocket

public class MyWebSocketHandler {





    private static String url = "tcp://localhost:61616";

    private static String subject = "mydataque";



    //private final CountDownLatch closeLatch;



    @SuppressWarnings("unused")

    private Session session;







    @OnWebSocketClose

    public void onClose(int statusCode, String reason) {

        System.out.println("Close: statusCode=" + statusCode + ", reason=" + reason);

    }



    @OnWebSocketError

    public void onError(Throwable t) {

        System.out.println("Error: " + t.getMessage());

    }



    @OnWebSocketConnect

    public void onConnect(Session session) {

        System.out.println("Connect: " + session.getRemoteAddress().getAddress());

        try {

            session.getRemote().sendString("Hello Webbrowser");

        } catch (IOException e) {

            e.printStackTrace();

        }

        /////////////////////////////////////////////////////////////////////

        System.out.printf("Got connect: %s%n", session);

        this.session = session;

        try {



            Future<Void> fut;



            int i = 0;



            // Getting JMS connection from the server

            ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(

                    url);

            Connection connection = connectionFactory.createConnection();

            connection.start();



            // Creating session for sending messages

            javax.jms.Session session2 = connection.createSession(false,

                    javax.jms.Session.AUTO_ACKNOWLEDGE);



            // Getting the messages from the queue

            Destination destination = session2.createQueue(subject);



            // MessageConsumer is used for receiving (consuming) messages

            MessageConsumer consumer = session2.createConsumer(destination);



            try {



                // Receive the message.

                System.out.println("The Consumer : " + consumer.toString());

                while (true) {



                    Message message = consumer.receive();

                    System.out.println("Received message '"

                            + ((TextMessage) message).getText() + "'");

                    fut = session.getRemote().sendStringByFuture(((TextMessage) message).getText());

                    fut.get(2, TimeUnit.SECONDS);

                    Thread.sleep(50);

                    i++;

                }



            } catch (Exception e) {

                System.out.println("Error : " + e.getMessage());

            }



            finally {

                session.close(StatusCode.NORMAL,

                        "[Consumer]Closing the session with the Server!!");

                connection.close();

                session2.close();



            }





        } catch (Throwable t) {

            t.printStackTrace();

        }

        /////////////////////////////////

    }



    @OnWebSocketMessage

    public void onMessage(String message) {

        System.out.println("Message: " + message);

    }

}
This is the class that contains main methode that initiate webSocket.  After running this class you can access your webSocket using any browser which supports webSockets using url ws://localhost:8081
You can use simple Chrome extensions like this

/**

 * Created by IntelliJ IDEA.

 * User: Chann

 * Date: 11/23/14

 * Time: 11:01 PM

 * To change this template use File | Settings | File Templates.

 */

import org.eclipse.jetty.server.Server;

import org.eclipse.jetty.websocket.server.WebSocketHandler;

import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;

import javax.servlet.ServletException;



public class WebSocketTest {



    public static void main(String[] args) throws Exception {

        Server server = new Server(8081);

        WebSocketHandler wsHandler = new WebSocketHandler() {

        //MessageSocket wsHandler = new MessageSocket()

            @Override

            public void configure(WebSocketServletFactory factory) {

                factory.register(MyWebSocketHandler.class);

            }

        };

        server.setHandler(wsHandler);

        server.start();

        server.join();

    }


}

Thursday, March 6, 2014

File Uploading with Spring

In web applications that uses Spring framework some times we may need to add functionality to upload file to server. This can be done easily as follows.



First create a form to select a  file,

<!--  Form -->

<i>Uploading File With Ajax</i><br/>

<form id="form" method="post" action="/fileUpload/upload/" enctype="multipart/form-data">

  <!-- File input -->   

  <input name="file" id="file" type="file" /><br/>

</form>

<button value="Submit" onclick="uploadJqueryForm()" >Upload</button><i>Using JQuery Form Plugin</i><br/>

<div id="result"></div>

</body>

</html>
when the button clicks, it calls uploadJqueryForm() function. In that function we can submit the file to the respective controller method. Here is the uploadJqueryForm() function


function uploadJqueryForm(){
    $('#result').html('');
   $("#form").ajaxForm({
    success:function(data) { 
          $('#result').html(data);
     },
     dataType:"text"
   }).submit();
}
This fuction will submit the file and calls the path specified in the "action" tag in the above form. Then we need to write a controller method to handle that request from the function uploadJqureyForm()

@RequestMapping(value = "fileUpload/upload", method = RequestMethod.POST)
    public @ResponseBody String upload(MultipartHttpServletRequest request, HttpServletResponse response,Model model) {                 
 
      Iterator itr =  request.getFileNames();
  
      MultipartFile mpf = request.getFile(itr.next());
      System.out.println(mpf.getOriginalFilename() +" uploaded!");
      String fullFileName="";
      String filePath="";
  
      try {
                
         ufile.length = mpf.getBytes().length;
         ufile.bytes= mpf.getBytes();
         ufile.type = mpf.getContentType();
         ufile.name = mpf.getOriginalFilename();
         
         
             InputStream in= mpf.getInputStream();    
             String fileName = mpf.getOriginalFilename();            
             
             String fileExtension = fileName.substring(fileName.indexOf(".")+1,fileName.length());
                
          
           filePath="D:\\DEV\\work\\files\\Temp\\";
           fullFileName = "D:/DEV/work/files/Temp/"+fileName;
          File files = new File(filePath);
          if (!files.exists()) {
           if (files.mkdirs()) {
            System.out.println("Multiple directories are created!");
           } else {
            System.out.println("Failed to create multiple directories!");
           }
          }
          writeFile(in,fullFileName);
          
      
  
     } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
     }
  
      
      return "home"; //or whatever the model you need
  
   }
In that methode we get the file as a Multipart request.

Inside this method we call writeFile() method. Here is that method.
this method will write the file into the server folder which we created in the above controller method.

private void writeFile(InputStream in,String fileName){
   
    File file = new File(fileName);
    FileOutputStream fo;
    logger.info("Saving File "+fileName);
   try {
    fo = new FileOutputStream(file);
      byte[] buf = new byte[512]; // optimize the size of buffer to your need
        int num;
        while ((num = in.read(buf)) != -1) {
         fo.write(buf, 0, num);
        }
      fo.flush(); 
        fo.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   
    }

References : Reference 1Reference 2
   

Thursday, January 16, 2014

Simple Web Service with JBoss AS

Introduction

What is a Web Service?

Web service is a application that provide client application to use server applications methods. Assume you have a simple java programme with several classes. You can use those classes only inside your programme( or you have to include them as lib files). If you develop your programme as web service and host it in a application server, then client programms can use those classes( actually the methods inside those classes) via a network. Special thin about web services is it is platform independent. That means you may develop your web service using java, but clients that use the web service need not to be java, it may be .Net or any other language. 

How it works

When we publish a web service to a application server, we can get a xml document called WSDL(there are several technologies, but for this article I make things simple). This is the key to the web service, it contains all the method signatures, what is the address that web service can access, what are the protocols used etc. When creating client side we use this document to specify way of communication with the server application. Then how the platform independence comes into action? When we sending messages we use a protocol, that means both sides knows what they are sending and receiving. When a client needs to request something from server it converts its message to that protocol, when server side get the request it converts it back to original version that the server application can understands. Same thing happens with the other way of communication. Most popular protocol is SOAP. You can read more from here

Things we need

  • JDK 1.5 (or higher).
  • JBoss App Server.
  • Apache Maven (Read this how to install maven)
  • IDE (I used Intellij Idea 12.0)
If you are using JBoss 5.0.0 or lesser version please make sure you install JBoss WS framework to your application server. Read this article to install those applications on to your pc.


For the rest of this article I assume you have installed and configured above things correctly.

Folder structure for web application (war)

Server can identify our application as web application, if we bundle the classes and other necessary files in the following manner. At the end of the this article I'm going to bundle all the necessary files into .war file using Maven build tool.



  • classes folder contains all the classes in our application.
  • lib folder contains all the libraries that need for the application
  • web.xml file contains instructions to the server that which classes need to be loaded when web service is in action.
  • for our discussion let's forget about other files/folders

Implementation

  •  Create a java project (make sure you don't select any project modules such as web services, web services clients etc. for the first time we are going to start from the scratch)
  • Then right click on the project name in Intellij and select add framework support, select maven and click ok.
  • Now you have a clean maven java project. 
Now you have a project with pom.xml file. Folder structure should look like this.
  • Right click on your java folder (in Intellij project tab) and select New > Package
  • Give your package a name. ( I gave com.webservice)
  • Now right click on main folder and select New>Directory. create a directory called webapp and inside that create a directory called WEB-INF (this is the folder that contains web.xml file so give names exactly as above)
Now we are ready to go.


Create a class in com.webservice package
This is the class that our web service methods are implemented.
Now we can implement methods for our web service. Let’s create helloworld method that returns a string.

Now we need to make this class a web service class and this method a web service method. We can do it by adding annotations.  Just before your class name add @WebClass and before your method name add @Webmethod. After adding those annotations it will not recognize by our program, put cursor on those words and press Alt+enter to import  javax.jws.WebMethod and javax.jws.WebService.

Here is the WebClass

 package com.webservice;  
 import javax.jws.WebMethod;  
 import javax.jws.WebService;  
 /**  
  * Created by IntelliJ IDEA.  
  * User: Chann  
  * Date: 1/15/14  
  * Time: 9:58 PM  
  * To change this template use File | Settings | File Templates.  
  */  
 @WebService  
 public class WebClass {  
     @WebMethod  
    public String helloWebService(String name){  
      return "Hello "+ name;  
    }  
 } 
Now create a file named web.xml inside WEB-INF folder and add followings to that file. This is the file that contains details about our web service to server. <servlet-class> tag defines the classes that are related to web service. Let’s postpone to discuss about url-patterns and other stuff.

 <web-app>  
   <servlet>  
     <servlet-name>HelloWebService</servlet-name>  
     <servlet-class>com.webservice.WebClass</servlet-class>  
   </servlet>  
   <servlet-mapping>  
     <servlet-name>HelloWebService</servlet-name>  
     <url-pattern>/*</url-pattern>  
   </servlet-mapping>  
 </web-app>  
Now it’s almost done coding our web service. Now we need to build these classes and package them to a war file to deploy in JBoss server
We use maven to build our project. We have a pom.xml file in our project. Let’s modify it to do our job.

We need to package our web service as a war file. That is done through the <packaging> tag.

 <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" 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>groupId</groupid>  
   <artifactid>WebService</artifactid>  
   <version>1.0-SNAPSHOT</version>  
   <packaging>war</packaging>  
   <dependencies>  
     <dependency>  
       <groupid>com.sun.xml.bind</groupid>  
       <artifactid>jaxb-core</artifactid>  
       <version>2.2.8-b01</version>  
     </dependency>  
     <dependency>  
       <groupid>com.sun.xml.bind</groupid>  
       <artifactid>jaxb-impl</artifactid>  
       <version>2.2-promoted-b65</version>  
     </dependency>  
   </dependencies>  
   <build>  
     <plugins>  
       <plugin>  
         <artifactid>maven-war-plugin</artifactid>  
         <version>2.4</version>  
         <configuration>  
           <packagingexcludes>WEB-INF/lib/*.jar</packagingexcludes>  
         </configuration>  
       </plugin>  
     </plugins>  
   </build>  
 </project> 
we need to add the war plugin to make a war using maven. That is the reason to add maven-war-plugin to our pom.xml file. We need to add <packagingExcludes> tag to bundle our WEB-INF folder without addional jar files(some times it gives errors if we keep those jar lib files inside WEB-INF folder). And additionally we need to add two dependencies to work properly. Now we can make our project. Either click package in maven life-cycle in Intellij idea(in left side) or open project folder via cmd prompt ( open cmd prompt and navigate to project folder) and then type maven clean install, press enter. You can find the war file in target folder inside project folder.

Now you can put this war file inside JBoss>Server>default>deploy folder. And run the Start.bat file inside JBoss > bin folder to start the server.

Now your web service is in action.