Showing posts with label Network. Show all posts

How to forward current Session in HttpURLConnection?

Server Room


HttpURLConnection
HttpURLConnection is helps to use HTTP-specific features. Each HttpURLConnection instance is used to make a single request however it can be shared by other instances at the server. The most common use of HttpURLConnection is to make HTTP connection with Cookies, CustomHeader, Set GET/POST Methods, etc...

I used HttpURLConnection to make HTTP call from Servlet, I also required current session to be forwarded to called Servlet. You may have your different scenario.

Source Code
try {
 /* ID of Session you want to forward */
 String sessionId = "";
 /* Reading response data */
 String inputLine = "";

 URL data = new URL("http://www.your-domain.com/your-page.jsp");
 /* comment below line in case of Proxy */
 HttpURLConnection con = (HttpURLConnection) data.openConnection();
 /* Forward current session in request */
 con.setRequestProperty("Cookie", "JSESSIONID=" + URLEncoder.encode(sessionId, "UTF-8"));
 /* Read webpage coontent */
 BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
 /* Read line by line */
 while ((inputLine = in.readLine()) != null) {
  System.out.println(inputLine);
 }
 /* close BufferedReader */
 in.close();
 /* close HttpURLConnection */
 con.disconnect();
} catch (Exception e) {
 e.printStackTrace();
}

How Session forwarded/passed in HttpURLConnection request?
Server access Cookies to get Session ID value. JSESSIONID cookie used by server to identify session. If Session ID is valid then server allows you to access that session. This is how it works.

I tested code with Apache Tomcat and JBoss and its working fine. I don't know about other web server but It should work because all web server uses common standards.

Java Documentation: http://docs.oracle.com/javase/7/docs/api/java/net/HttpURLConnection.html

Sample Client - Server Chat Application in Java

Client Server ChatApplication

Wikipedia: A network socket is an endpoint of an inter-process communication flow across a computer network.

Difference between Server and Client
Server Socket is one that accept connection on specific port and can respond. Where client can send message to server on specified port and can get response from server.

We will send messages over network only. In this demo application I'm sending and receiving messages on localhost. To create full-fledged chat application you need to modify many things like...

  • Every system must have Socket Server running on local system to accept messages from another system.
  • Get list of all system which is running your application. 
  • If you are planning to create rich chat application, provide advance settings like Save chat log, Play sound when receives message, Send encrypted messages, etc... can be lot more.

Note: There will be plenty of code which is not explained in all source code which was generated by NetBeans IDE. NetBeans project code attached at the end of article.

Socket Server
It will accept connection and listen for messages and pass it to desired frame/user chat window. I create Server in form JFrame just to give better look.
/*
 * mainFrame.java
 * This program demonstarte client server message application.
 * mainFrame.java will act as a server program aimed to receive messages and respond to client.
 */
package com.javaquery.frames;

import java.awt.Frame;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.UIManager;
import org.json.JSONObject;

public class mainFrame extends javax.swing.JFrame {

    /* Inner class to create socket server */
    private class mainServer extends Thread {

        /* Create ServerSocket variable */
        private ServerSocket serverSocket;

        /* Constructor to initialize serverSocket */
        public mainServer() throws IOException {
            serverSocket = new ServerSocket(6666);
        }

        /* Implement run() for Thread */
        public void run() {
            /* Keep Thread running */
            while (true) {
                try {
                    /* Accept connection on server */
                    Socket server = serverSocket.accept();
                    /* DataInputStream to get message sent by client program */
                    DataInputStream in = new DataInputStream(server.getInputStream());
                    /* We are receiving message in JSON format from client. Parse String to JSONObject */
                    JSONObject clientMessage = new JSONObject(in.readUTF());
                    
                    /* Flag to check chat window is opened for user that sent message */
                    boolean flagChatWindowOpened = false;
                    /* Reading Message and Username from JSONObject */
                    String userName = clientMessage.get("Username").toString();
                    String message = clientMessage.getString("Message").toString();
                    
                    /* Get list of Frame/Windows opened by mainFrame.java */
                    for(Frame frame : Frame.getFrames()){
                        /* Check Frame/Window is opened for user */
                        if(frame.getTitle().equals(userName)){
                            /* Frame/ Window is already opened */
                            flagChatWindowOpened = true;
                            /* Get instance of ChatWindow */
                            ChatWindow chatWindow = (ChatWindow) frame;
                            /* Get previous messages from TextArea */
                            String previousMessage = chatWindow.getjTextArea1().getText();
                            /* Set message to TextArea with new message */
                            chatWindow.getjTextArea1().setText(previousMessage+"\n"+message);
                        }
                    }
                    
                    /* ChatWindow is not open for user sent message to server */
                    if(!flagChatWindowOpened){
                        /* Create an Object of ChatWindow */
                        ChatWindow chatWindow = new ChatWindow();
                        /**
                         * We are setting title of window to identify user for next message we gonna receive
                         * You can set hidden value in ChatWindow.java file.
                         */
                        chatWindow.setTitle(userName);
                        /* Set message to TextArea */
                        chatWindow.getjTextArea1().setText(message);
                        /* Make ChatWindow visible */
                        chatWindow.setVisible(true);
                    }
                    
                    /* Get DataOutputStream of client to repond */
                    DataOutputStream out = new DataOutputStream(server.getOutputStream());
                    /* Send response message to client */
                    out.writeUTF("Received from "+clientMessage.get("Username").toString());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * To start SocketServer when mainFrame.java loads
     */
    public void startServer() {
        try {
            /* Create thread of Inner class mainServer */
            Thread t = new mainServer();
            /* Start Thread */
            t.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /** Creates new form mainFrame */
    public mainFrame() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    //                           
    private void initComponents() {

        lblInformation = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Server");
        setAlwaysOnTop(true);

        lblInformation.setText("Client - Server Sample Application");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lblInformation)
                .addContainerGap(229, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lblInformation)
                .addContainerGap(275, Short.MAX_VALUE))
        );

        pack();
    }//                         

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                /* To set new look and feel */
                JFrame.setDefaultLookAndFeelDecorated(true);
                try {
                    /**
                     * Change look and feel of JFrame to Nimbus 
                     * For other look and feel check
                     * 
                     */
                    UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
                } catch (Exception ex) {
                   ex.printStackTrace();
                }
                /* Create an Object of mainFrame */
                mainFrame mFrame = new mainFrame();
                /* make mainFrame visible */
                mFrame.setVisible(true);
                /* Call startServer method  */
                mFrame.startServer();
            }
        });
    }
    // Variables declaration - do not modify                     
    private javax.swing.JLabel lblInformation;
    // End of variables declaration                   
}

Chat Window Source Code
ChatWindow.java is common class which creates Chat window for user. We are identify particular user's chat window by its title. You can have your logic.
package com.javaquery.frames;

public class ChatWindow extends javax.swing.JFrame {

    /** Creates new form ChatWindow */
    public ChatWindow() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    //                           
    private void initComponents() {

        lblInfo = new javax.swing.JLabel();
        scrollPane = new javax.swing.JScrollPane();
        chatArea = new javax.swing.JTextArea();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Message Box");

        lblInfo.setText("Messages");

        chatArea.setColumns(20);
        chatArea.setRows(5);
        scrollPane.setViewportView(chatArea);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE)
                    .addComponent(lblInfo))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lblInfo)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 253, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }//                         

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new ChatWindow().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify                     
    private javax.swing.JTextArea chatArea;
    private javax.swing.JLabel lblInfo;
    private javax.swing.JScrollPane scrollPane;
    // End of variables declaration                   

    /**
     * @return the chatArea
     */
    public javax.swing.JTextArea getjTextArea1() {
        return chatArea;
    }

    /**
     * @param chatArea the chatArea to set
     */
    public void setjTextArea1(javax.swing.JTextArea jTextArea1) {
        this.chatArea = jTextArea1;
    }
}

Client Source Code
This will send message to sever and get response. We are sending 3 messages to server. Two messages from same username.
/*
 * client.java
 * This program demonstarte client server message application.
 * client.java will act as a client program aimed to send messages and get server response
 */

package com.javaquery.network;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import org.json.JSONObject;

public class client {

    public static void main(String[] args) {
        client c = new client();
        /* Create JSON variable */
        JSONObject transmitJSON = new JSONObject();

        /**
         * This is sample program so we are sending three messages from same system with different username.
         * In your case you'll receive message from multiple systems.
         */
        /* Fill up JSON variable with message and username */
        transmitJSON.put("Message", "Hello JavaQuery!");
        transmitJSON.put("Username", "Vicky.Thakor");
        /* Send message to server */
        c.sendMessage("localhost", transmitJSON.toString());
        
        transmitJSON.put("Message", "Hello Apple!");
        transmitJSON.put("Username", "Steve.Jobs");
        /* Send message to server */
        c.sendMessage("localhost", transmitJSON.toString());
        
        transmitJSON.put("Message", "How are you?");
        transmitJSON.put("Username", "Steve.Jobs");
        /* Send message to server */
        c.sendMessage("localhost", transmitJSON.toString());
    }

    /**
     * @author javaQuery
     * @param host
     * @param message 
     */
    public void sendMessage(String host, String message) {
        try {
            /* Create new socket connection with server host using port 6666 (port can be anything) */
            Socket client = new Socket(host, 6666);
            /* Get server's OutputStream */
            OutputStream outToServer = client.getOutputStream();
            /* Get server's DataOutputStream to write/send message */
            DataOutputStream out = new DataOutputStream(outToServer);
            /* Write message to DataOutputStream */
            out.writeUTF(message);
            /* Get InputStream to get message from server */
            InputStream inFromServer = client.getInputStream();
            /* Get DataInputStream to read message of server */
            DataInputStream in = new DataInputStream(inFromServer);
            /* Print message received from server */
            System.out.println("Server says..." + in.readUTF());
            /* Close connection of client socket */
            client.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


Download Project

java.net.ConnectException: Connection timed out: connect

internet disconnected

This exception caused by several issues. Issue may be solved by ensuring following checklist.

- Connected to Internet / Local Area Network (LAN)
Make sure you are connected to internet or local area network.

- Behind Firewall
Firewall is common issue faced by many developer. We were facing same issue.
java.net.ConnectException: Connection timed out: connect
 at java.net.PlainSocketImpl.socketConnect(Native Method)
 at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
 at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
 at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
 at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
 at java.net.Socket.connect(Socket.java:529)
 at java.net.Socket.connect(Socket.java:478)
 at sun.net.NetworkClient.doConnect(NetworkClient.java:163)
 at sun.net.www.http.HttpClient.openServer(HttpClient.java:394)
 at sun.net.www.http.HttpClient.openServer(HttpClient.java:529)
 at sun.net.www.http.HttpClient.(HttpClient.java:233)
 at sun.net.www.http.HttpClient.New(HttpClient.java:306)
 at sun.net.www.http.HttpClient.New(HttpClient.java:323)
 at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:970)
 at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:911)
 at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:836)
 at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1172)
 at ReadWebpage.main(ReadWebpage.java:24)

Scenario
We were writing an applet program in Java to read webpage from internet. We can't even make request to well know search engine www.google.com even if its allowed in firewall rule. We called upon our network admin he said you must pass your request through proxy server. We set proxy in our Java code for HttpURLConnection and all went good.

Code
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("192.168.0.202", 8080));
HttpURLConnection con = (HttpURLConnection) data.openConnection(proxy);
Use of Proxy
You need to take care for proxy connection and it depends upon whether you are write program for applet or desktop application. If you are writing code for applet then in production applet, you don't need proxy connection as server will have all access and will work without proxy. If you are working on desktop application that run within the Local Area Network then you must set proxy in case of firewall.