Blog Archive

JQuery Cross Domain Java Servlet AJAX Request with JSONP example

How to avoid Access-Control-Allow-Origin error

Issue at hand: XMLHttpRequest cannot load http:/URL/.... Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.

If you try to make an AJAX request to a Web service that's not in the same domain as your original request you will get the  Access-Control-Allow-Origin error or if on Internet Explorer Access denied error. The fix is pretty easy for browsers such as Chrome, Firefox, Opera, Safari, etc as they implement CORS. If you are interested in implementing CORS please review this link given below
Java Servlet to solve Origin not allowed by Access-Control-Allow-Origin issue

But IE is a completely different animal, they are so behind on HTML standards that it's pathetic but what can a programmer do, we still have to support IE. The help comes from making an AJAX call using JavaScript callback known as JSONP.  JSONP or "JSON with padding" is a complement to the base JSON data format. It provides a method to request data from a server in a different domain, something prohibited by typical web browsers because of the Same origin policy.

Under the same origin policy, a web page served from server1.domain.com cannot normally connect to or communicate with a server other than server1.domain.com. An exception is the HTML <script> element. Exploiting the open policy for <script> elements, some pages use them to retrieve JavaScript code that operates on dynamically generated JSON-formatted data from other origins. This usage pattern is known as JSONP. Requests for JSONP retrieve not JSON, but arbitrary JavaScript code. They are evaluated by the JavaScript interpreter, not parsed by a JSON parser.


In this example we use JSONP as datatype and provide a Callback function for the jQuery.ajax() method.

jQuery cross domain ajax request using Java Servlet
jQuery cross domain ajax request using Java Servlet
Sample Response for the AJAX request with country code = USA 
jsonpCallback({"success":true,"countryInfo":{"code":"USA","name":"United States",
"continent":"North America","region":"North America","lifeExpectancy":77.1,"gnp":8510700.0}});

If your are familiar with the jQuery AJAX request then it should be pretty easy for you. Just look at the BOLD lines. If you need a refresher on jQuery AJAX tutorial then click on the link below
jQuery AJAX request and response example - Java Servlets, MySQL and JSON

Application HTML file - index.html

<html>
<head>
    <title>jQuery Cross Domain AJAX request to Java Servlet using JSONP</title>

    <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
   
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js" type="text/javascript"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js" type="text/javascript"></script>
    <script type="text/javascript" src="app.js"></script>

</head>
<body>

    <form id="myAjaxRequestForm">
        <fieldset>
            <legend>jQuery Ajax Form data Submit Request</legend>

                <p>
                    <label for="countryCode">Country Code:</label><br />
                    <input id="countryCode" type="text" name="countryCode" />
                </p>
                <p>
                    <input id="myButton" type="button" value="Submit" />
                </p>
        </fieldset>
    </form>
    <div id="anotherSection">
        <fieldset>
            <legend>Response from jQuery Ajax Request</legend>
                 <div id="ajaxResponse"></div>
        </fieldset>
    </div>    

</body>
</html>

Application JavaScript file using jQuery - apps.js

$(document).ready(function() {

    //Stops the submit request
    $("#myAjaxRequestForm").submit(function(e){
           e.preventDefault();
    });
   
    //checks for the button click event
    $("#myButton").click(function(e){
           
            //get the form data and then serialize that
            dataString = $("#myAjaxRequestForm").serialize();
            
            //make the AJAX request, dataType is set to json
            //meaning we are expecting JSON data in response from the server
            $.ajax({
                type: "POST",
                url: "http://demo.mysamplecode.com/JQuery/CountryInfo",
                data: dataString,
                dataType: 'jsonp',
                jsonp: 'callback',
                jsonpCallback: 'jsonpCallback',
                
                //if received a response from the server
                success: function( data, textStatus, jqXHR) {
                    //our country code was correct so we have some information to display
                     if(data.success){
                         $("#ajaxResponse").html("");
                         $("#ajaxResponse").append("<b>Country Code:</b> " + data.countryInfo.code + "\n");
                         $("#ajaxResponse").append("<b>Country Name:</b> " + data.countryInfo.name + "\n");
                         $("#ajaxResponse").append("<b>Continent:</b> " + data.countryInfo.continent + "\n");
                         $("#ajaxResponse").append("<b>Region:</b> " + data.countryInfo.region + "\n");
                         $("#ajaxResponse").append("<b>Life Expectancy:</b> " + data.countryInfo.lifeExpectancy + "\n");
                         $("#ajaxResponse").append("<b>GNP:</b> " + data.countryInfo.gnp + "\n");
                     } 
                     //display error message
                     else {
                         $("#ajaxResponse").html("<div><b>Country code in Invalid!</b></div>");
                     }
                },
                
                //If there was no resonse from the server
                error: function(jqXHR, textStatus, errorThrown){
                     console.log("Something really bad happened " + textStatus);
                      $("#ajaxResponse").html(jqXHR.responseText);
                },
                
                //capture the request before it was sent to server
                beforeSend: function(jqXHR, settings){
                    //disable the button until we get the response
                    $('#myButton').attr("disabled", true);
                },
                
                //this is called after the response or error functions are finsihed
                //so that we can take some action
                complete: function(jqXHR, textStatus){
                    //enable the button 
                    $('#myButton').attr("disabled", false);
                }
    
            });         
    });
    
    function jsonpCallback(data) {
        console.log("callback",data);
        //do nothing    
    }

});

Java Country Information bean - Country.java

package com.as400samplecode.util;

public class Country {
   
    String code = null;
    String name = null;
    String continent = null;
    String region = null;
    Double lifeExpectancy = null;
    Double gnp = null;
   
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getContinent() {
        return continent;
    }
    public void setContinent(String continent) {
        this.continent = continent;
    }
    public String getRegion() {
        return region;
    }
    public void setRegion(String region) {
        this.region = region;
    }
    public Double getLifeExpectancy() {
        return lifeExpectancy;
    }
    public void setLifeExpectancy(Double lifeExpectancy) {
        this.lifeExpectancy = lifeExpectancy;
    }
    public Double getGnp() {
        return gnp;
    }
    public void setGnp(Double gnp) {
        this.gnp = gnp;
    }

   
}

Java Servlet processing jQuery AJAX request - CountryInfo.java

package com.as400samplecode;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

import com.as400samplecode.util.Country;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

public class CountryInfo extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public CountryInfo() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String countryCode = request.getParameter("countryCode");
        String callback = request.getParameter("callback");
       
        PrintWriter out = response.getWriter();
        response.setContentType("text/html");
        response.setHeader("Cache-control", "no-cache, no-store");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Expires", "-1");

        Gson gson = new Gson(); 
        JsonObject myObj = new JsonObject();

        Country countryInfo = getInfo(countryCode);
        JsonElement countryObj = gson.toJsonTree(countryInfo);
        if(countryInfo.getName() == null){
            myObj.addProperty("success", false);
        }
        else {
            myObj.addProperty("success", true);
        }
        myObj.add("countryInfo", countryObj);
        if(callback != null) {
            out.println(callback + "(" + myObj.toString() + ");");
        }
        else {
            out.println(myObj.toString());
        }
       
        out.close();

    }

    //Get Country Information
    private Country getInfo(String countryCode) {

        Country country = new Country();
        Connection conn = null;            
        PreparedStatement stmt = null;     
        String sql = null;

        try {      
            Context ctx = (Context) new InitialContext().lookup("java:comp/env");
            conn = ((DataSource) ctx.lookup("jdbc/mysql")).getConnection(); 

            sql = "Select * from country where code = ?"; 
            stmt = conn.prepareStatement(sql);
            stmt.setString(1, countryCode.trim());
            ResultSet rs = stmt.executeQuery(); 

            while(rs.next()){ 
                country.setCode(rs.getString("code").trim());
                country.setName(rs.getString("name").trim());
                country.setContinent(rs.getString("continent").trim());
                country.setRegion(rs.getString("region").trim());
                country.setLifeExpectancy(rs.getString("lifeExpectancy") == null ? new Double(0) : Double.parseDouble(rs.getString("lifeExpectancy").trim()));
                country.setGnp(rs.getString("gnp") == null ? new Double(0)  : Double.parseDouble(rs.getString("gnp").trim()));
            }                                                                         

            rs.close();                                                               
            stmt.close();                                                             
            stmt = null;                                                              


            conn.close();                                                             
            conn = null;                                                   

        }                                                               
        catch(Exception e){
            country.setName(getMyStackTrace(e));
            System.out.println(e);
        }                      

        finally {                                                       

            if (stmt != null) {                                            
                try {                                                         
                    stmt.close();                                                
                } catch (SQLException sqlex) {                                
                    // ignore -- as we can't do anything about it here           
                }                                                             

                stmt = null;                                            
            }                                                        

            if (conn != null) {                                      
                try {                                                   
                    conn.close();                                          
                } catch (SQLException sqlex) {                          
                    // ignore -- as we can't do anything about it here     
                }                                                       

                conn = null;                                            
            }                                                        
        }              

        return country;

    }   

    public static String getMyStackTrace(Exception e) {

        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter, true);
        e.printStackTrace(printWriter);
        return stringWriter.toString();

    }


}