Java servlet and server sent events - java

Is it possible to create a server sent event using java servlets so that a client could receive updates using:
<script>
var source = new EventSource('/events');
source.onmessage = function(e) {
document.body.innerHTML += e.data + '<br>';
};
</script>
All examples I have found on the web are using PHP but I would assume that it should work using Java's HTTP Servlet.

this does the trick.
HTML
<!DOCTYPE html>
<html>
<body onload ="registerSSE()" >
<script>
function registerSSE()
{
alert('test 1');
var source = new EventSource('http://frewper:8080/hello/sse');
alert('Test2');
source.onmessage=function(event)
{
document.getElementById("result").innerHTML+=event.data + "<br />";
};
/*source.addEventListener('server-time',function (e){
alert('ea');
},true);*/
}
</script>
<output id ="result"></output>
</body>
</html>
Servlet :
import java.io.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class sse extends HttpServlet
{
public void doPost(HttpServletRequest request, HttpServletResponse response)
{
try
{
System.out.println("SSE Demo");
response.setContentType("text/event-stream");
PrintWriter pw = response.getWriter();
int i=0;
while(true)
{
i++;
pw.write("event: server-time\n\n"); //take note of the 2 \n 's, also on the next line.
pw.write("data: "+ i + "\n\n");
System.out.println("Data Sent!!!"+i);
if(i>10)
break;
}
pw.close();
}catch(Exception e){
e.printStackTrace();
}
}
public void doGet(HttpServletRequest request,HttpServletResponse response)
{
doPost(request,response);
}
}

Server-Sent Events is a HTML5 feature. We say "HTML5", therefore it's just client side feature.
So long server can set https respnse header "text/event-stream;charset=UTF-8","Connection", "keep-alive", then it is supported by server. You can set such header with Java Servlet.
Here you can find a step for step guide on SSE with servlet

I have created a very simple library that can be integrated within plain Java Servlets in Asynchronous mode, so no extra server threads are required for each client: https://github.com/mariomac/jeasse
It integrates the SseDispatcher (for point-to-point SSEs) and SseBroadcaster (for event broadcasting). An example of use:
public class TestServlet extends HttpServlet {
SseBroadcaster broadcaster = new SseBroadcaster();
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Scanner scanner = new Scanner(req.getInputStream());
StringBuilder sb = new StringBuilder();
while(scanner.hasNextLine()) {
sb.append(scanner.nextLine());
}
System.out.println("sb = " + sb);
broadcaster.broadcast("message",sb.toString());
}
//http://cjihrig.com/blog/the-server-side-of-server-sent-events/
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
broadcaster.addListener(req);
}
}

Related

HttpServletResponse output desination when called from outside browser

I have a Java web application running under Apache Tomcat (8.0.21.0). Its function is to monitor various external processes and display alerts and periodic updated statuses in a browser. The main HTTP request handler is simple enough.
public class MyApplication extends HttpServlet
{
.
.
.
public void doPost (HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
processRequest (request, response);
}
public void doGet (HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
processRequest (request, response);
}
private static void processRequest (HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
String strOption = request.getParameter ("option");
int nOption = Integer.parseInt (strOption);
response.setContentType ("text/html");
PrintWriter out = response.getWriter ();
outputPage (out, nOption);
}
private void outputPage (PrintWriter out, int nOption)
{
out.println ("<!DOCTYPE html>");
out.println ("<html>");
out.println ("<head>");
switch (nOption)
{
// title, style and <body> content depend on option passed in request
.
.
.
}
out.println ("</body>);
out.println ("</html>");
}
}
However, the application also includes a TCP Listener and socket, to receive IoT (Internet of Things) messages:
public class MyTCPconnection extends Thread
{
public Socket clientSocket; // socket created by listener
private String url = "[local host address and servlet name]";
.
.
.
public void run ()
{
int RC = 400; // default value = "Bad Request"
try
{
// get bytes from remote process
int receiveBufferSize = clientSocket.getReceiveBufferSize ();
byte[] receiveBuffer = new byte[receiveBufferSize];
int bytesRead = TCPreceive (clientSocket, receiveBuffer); // not shown
if (bytesRead != -1 && bytesRead != 0)
{
String strOption = getOption (receiveBuffer); // not shown
}
HttpPost httpPost = new HttpPost (url);
httpPost.setHeader ("Accept", "text/html,application/xhtml+xml,application/xml");
httpPost.setHeader ("Content-Type", "application/x-www-form-urlencoded");
List<NameValuePair> requestParams = new ArrayList<NameValuePair>();
reqestParams.add (new BasicNameValuePair ("option", value));
CloseableHttpClient httpClient = HttpClients.createDefault ();
CloseableHttpResponse response = httpClient.execute (httpPost);
RC = response.getStatusLine().getStatusCode();
String responseBody = EntityUtils.toString (response.getEntity ());
system.out.println (responseBody);
}
catch (UnknownHostException e)
{
RC = 404;
}
catch (IOException e)
{
RC = 400;
}
TCPsend (clientSocket, RC); // reply to remote process, not shown
}
}
Take for granted that MyTCPconnection.run () generates a valid HTTP request body and submits a POST request to the main application. The problem I have encountered is that, where the POST is made from a web browser (IExplorer, Firefox etc), the application outputs a web page in the browser, but on receiving the POST request from the internal MyTCPconnection instance, it outputs nothing to any browser. Instead, it redirects the entire output to the responseBody.
I thought at first that I merely needed to save the HttpServletResponse and PrintWriter variables from a request from the browser, and pass the saved PrintWriter instance to the function outputPage. However, when I logged these, the results were:
Request from browser:
HttpServletResponse response = org.apache.catalina.connector.ResponseFacade#3e1d266b
PrintWriter out = org.apache.catalina.connector.CoyoteWriter#6bc55aa8
Request from MyTCPconnection.run ():
HttpServletResponse response = org.apache.catalina.connector.ResponseFacade#3e1d266b
PrintWriter out = org.apache.catalina.connector.CoyoteWriter#6bc55aa8
Any hints or hlp would be appreciated

Jetty Embedded - PUT Verb - Process headers before the body arrives

I'm using Jetty 9 and I'm trying to process the headers of a PUT request before all the body has arrived on the server. Here's what I've done:
Server.java:
public class SimplestServer
{
public static void main(String[] args) throws Exception
{
Server server = new Server(9080);
ServletHandler handler = new ServletHandler();
server.setHandler(handler);
handler.addServletWithMapping(HelloServlet.class, "/*");
handler.addFilterWithMapping(HelloPrintingFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
server.start();
server.dumpStdErr();
server.join();
}
public static class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println(System.currentTimeMillis() + ": Hello from HelloServlet GET");
}
#Override
protected void doPut(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println(System.currentTimeMillis() + ": Hello from HelloServlet PUT");
}
}
public static class HelloPrintingFilter implements Filter {
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println(System.currentTimeMillis() + ": Hello from filter");
chain.doFilter(request, response);
}
#Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println(System.currentTimeMillis() + ": Init from filter");
}
#Override
public void destroy() {
System.out.println(System.currentTimeMillis() + ": Destroy from filter");
}
}
}
Client.java
public class SimplestClient
{
public static void main(String[] args) throws Exception
{
URL url = new URL("http://localhost:9080/resource");
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
httpCon.setDoOutput(true);
httpCon.setRequestMethod("PUT");
OutputStream out = httpCon.getOutputStream();
byte[] b = new byte[65536];
Random r = new Random();
r.nextBytes(b);
for (int i = 0; i < 1024; i++) {
out.write(b);
}
System.out.println(System.currentTimeMillis() + ": Data sent. Waiting 5 seconds...");
try {
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
out.close();
System.out.println(System.currentTimeMillis() + ": Done!");
httpCon.getInputStream();
}
}
In a nutshell, the server program listens for connections on port 9080, when a request arrives the filter HelloPrintingFilter gets executed, then the request is processed by the HelloServlet. The client, instead, connects to the server, sends a bunch of data, then sleeps for 5 seconds and finally closes the connection with the server.
A run of both programs yields the following result:
Client:
1469613522350: Data sent. Waiting 5 seconds...
1469613527351: Done!
Server:
1469613527373: Hello from filter
1469613527373: Hello from HelloServlet PUT
Looking at the timestamps I can only get my filter code executed after all the body has arrived. Could anyone explain me how to do it? A typical use case is: a client tries to upload a 5GB file. As soon as the headers arrive, I want to check if they are OK (e.g. by checking if the Content-MD5 header, or whatever custom header I need to check, is present). If the request is OK then start processing the body. If the request is not OK then close the connection.
Thanks.
Use multiple requests. e.g. first request includes custom header and subsequent requests are used to upload a 5GB file.
You aren't doing anything in your HelloServlet.doPut(), so you are basically telling the Servlet container (aka Jetty) that you are done handling that request.
The request processing in Jetty is handled by a series of buffers from the network.
Your PUT headers and the start of your body content likely fit in a single buffer.
Jetty will parse the headers out, and then start the dispatch of the request to the Servlet chain, hitting your HelloFilter, and then your filter moves it along the chain with the chain.doFilter(request, response);
The point in time when HelloServlet.doPut() is reached, the headers have been processed, and the start of the body content hasn't, waiting for your implementation in doPut() to call HttpServletRequest.getInputStream() and start processing it, at which point Jetty is free to start reading more buffers off the network.
Note: if your servlet exits without reading the request input stream, and the response hasn't indicated a Connection: close, then Jetty will be forced to read the entire request to completion looking for the next request after it (known as a persistent connection in HTTP/1.1 spec)
The closest you'll get to reaching your stated goal to reject the Request body content is to use what you have available in the HTTP/1.1 spec (assuming this is a HTTP/1.1 request). Namely a proper response status code and a server initiated Connection: close response header.
Here's a complete example:
package jetty;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.Uptime;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class PutRejectExample
{
public static class RejectServlet extends HttpServlet
{
#Override
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
timedLog("doPut() - enter");
if (req.getHeader("X-Key") == null)
{
resp.setHeader("Connection", "close");
resp.sendError(HttpServletResponse.SC_FORBIDDEN);
timedLog("doPut() - rejected");
return;
}
File output = File.createTempFile("reject-", ".dat");
try (FileOutputStream out = new FileOutputStream(output))
{
IO.copy(req.getInputStream(), out);
}
resp.setStatus(HttpServletResponse.SC_OK);
resp.setHeader("Connection", "close"); // be a good HTTP/1.1 citizen
timedLog("doPut() - exit");
}
}
private static Server server;
private static int port;
private static void timedLog(String format, Object... args)
{
System.out.printf(Uptime.getUptime() + "ms " + format + "%n", args);
}
#BeforeClass
public static void startServer() throws Exception
{
server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(0);
server.addConnector(connector);
// collection for handlers
HandlerCollection handlers = new HandlerCollection();
server.setHandler(handlers);
// servlet context
ServletContextHandler context = new ServletContextHandler();
context.addServlet(RejectServlet.class, "/reject");
handlers.addHandler(context);
// default handler
handlers.addHandler(new DefaultHandler());
// start server
server.start();
// grab port
port = connector.getLocalPort();
}
#AfterClass
public static void stopServer() throws Exception
{
server.stop();
}
private void performPUT(int requestSize, String... extraRequestHeaders) throws IOException
{
StringBuilder req = new StringBuilder();
req.append("PUT /reject HTTP/1.1\r\n");
req.append("Host: localhost:").append(port).append("\r\n");
req.append("Content-Length: ").append(requestSize).append("\r\n");
for (String extraHeader : extraRequestHeaders)
{
req.append(extraHeader);
}
req.append("\r\n");
timedLog("client open connection");
try (Socket socket = new Socket())
{
socket.connect(new InetSocketAddress("localhost", port));
try (OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();
InputStreamReader reader = new InputStreamReader(in))
{
timedLog("client send request (headers + body)");
try
{
// write request line + headers
byte headerBytes[] = req.toString().getBytes(StandardCharsets.UTF_8);
out.write(headerBytes);
out.flush();
// write put body content
int bufSize = 65535;
byte[] buf = new byte[bufSize];
int sizeLeft = requestSize;
while (sizeLeft > 0)
{
int writeSize = Math.min(sizeLeft, bufSize);
ThreadLocalRandom.current().nextBytes(buf);
out.write(buf, 0, writeSize);
out.flush();
sizeLeft -= writeSize;
try
{
// simulate a slower connection
TimeUnit.MILLISECONDS.sleep(10);
}
catch (InterruptedException ignore)
{
// ignore
}
}
}
catch (IOException e)
{
timedLog("client request send exception");
e.printStackTrace(System.out);
}
timedLog("client send request complete");
timedLog("client read response");
try
{
StringWriter respStream = new StringWriter();
IO.copy(reader, respStream);
timedLog("client response: %s", respStream.toString());
}
catch (IOException e)
{
timedLog("client read response exception");
e.printStackTrace(System.out);
}
}
}
timedLog("client connection complete");
}
#Test
public void testBadPost() throws IOException
{
timedLog("---- testBadPost()");
performPUT(1024 * 1024 * 10);
}
#Test
public void testGoodPost() throws IOException
{
timedLog("---- testGoodPost()");
performPUT(1024 * 1024 * 10, "X-Key: foo\r\n");
}
}
This uses raw Socket and raw streams to avoid getting confused by all of the buffering present in the HttpUrlConnection.
The output you'll see for the normal / happy case is like this ...
416ms ---- testGoodPost()
416ms client open connection
2016-07-27 06:40:22.180:INFO:oejs.AbstractConnector:main: Started ServerConnector#55f3ddb1{HTTP/1.1,[http/1.1]}{0.0.0.0:46748}
2016-07-27 06:40:22.181:INFO:oejs.Server:main: Started #414ms
421ms client send request (headers + body)
494ms doPut() - enter
2084ms doPut() - exit
2093ms client send request complete
2093ms client read response
2094ms client response: HTTP/1.1 200 OK
Date: Wed, 27 Jul 2016 13:40:22 GMT
Connection: close
Server: Jetty(9.3.11.v20160721)
2094ms client connection complete
The output for the rejected case will look like this ...
2095ms ---- testBadPost()
2095ms client open connection
2096ms client send request (headers + body)
2096ms doPut() - enter
2101ms doPut() - rejected
2107ms client request send exception
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at jetty.PutRejectExample.performPUT(PutRejectExample.java:137)
at jetty.PutRejectExample.testBadPost(PutRejectExample.java:180)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
2109ms client send request complete
2109ms client read response
2109ms client response: HTTP/1.1 403 Forbidden
Date: Wed, 27 Jul 2016 13:40:23 GMT
Cache-Control: must-revalidate,no-cache,no-store
Content-Type: text/html;charset=iso-8859-1
Content-Length: 322
Connection: close
Server: Jetty(9.3.11.v20160721)
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/>
<title>Error 403 </title>
</head>
<body>
<h2>HTTP ERROR: 403</h2>
<p>Problem accessing /reject. Reason:
<pre> Forbidden</pre></p>
<hr />Powered by Jetty:// 9.3.11-SNAPSHOT<hr/>
</body>
</html>
2109ms client connection complete
Gotcha! The problem was not in the server side, but in the client side, which was only intended as a stub. Specifically, the problem was the buffering in the HttpUrlConnection.
Recalling my client.java, I have:
for (int i = 0; i < 1024; i++) {
out.write(b);
}
and if I change the loop to something like
for (int i = 0; i < 1024*1024; i++) {
out.write(b);
}
I immediately get an OutOfMemoryError exception, getting nothing on the server side, indicating that no single byte was transferred. And of course it is right, because BEFORE putting the headers on the wire the HttpUrlConnection needs to know the body length since it must emit the Content-Length header. Changing the client implementation to raw sockets, effectively controlling when bytes go to the wire, resolved the issue.
As a side note, the server code can be further simplified by removing the filter class. The complete server-side code is:
server.java:
public class SimplestServer
{
public static void main(String[] args) throws Exception
{
Server server = new Server(9080);
ServletHandler handler = new ServletHandler();
server.setHandler(handler);
handler.addServletWithMapping(HelloServlet.class, "/*");
server.start();
server.dumpStdErr();
server.join();
}
public static class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println(System.currentTimeMillis() + ": Hello from HelloServlet GET");
}
#Override
protected void doPut(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println(System.currentTimeMillis() + ": Hello from HelloServlet PUT");
// Perform some checks here
if (request.getHeader("X-Key") == null)
{
response.setHeader("Connection", "close");
response.sendError(HttpServletResponse.SC_FORBIDDEN);
System.out.println(System.currentTimeMillis() + ": Filter --> X-Key failed!");
return;
}
// Everything OK! Read the stream.
System.out.println(System.currentTimeMillis() + ": Proceded!!");
InputStream body = request.getInputStream();
long bytesReadSoFar = 0;
byte[] data = new byte[65536];
while (true) {
int bytesRead = body.read(data);
if (bytesRead < 0)
break;
bytesReadSoFar += bytesRead;
}
System.out.println(System.currentTimeMillis() + ": Finished! Read " + bytesReadSoFar + " bytes.");
response.setHeader("Connection", "close");
response.setStatus(HttpServletResponse.SC_OK);
}
}
}

Server Sent Event HTML5 error(the resource from this url is not text)

I wrote this Servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
response.setContentType("text/event-stream;charset=UTF-8");
response.setHeader("Cache-Control","no-cache");
PrintWriter printWriter=response.getWriter();
printWriter.write("Hello!");
}
and also this java script in index.jsp:
<script>
var resource = new EventSource("/servlet");
resource.onmessage = function (e) {
document.getElementById("container").innerHTML = e.data;
}
</script>
in order to create demo on server-sent events in html5. I inspected the jsp page in firefox and I got this error: the resource from this url is not text and nothing shows up. by the way request status is 200, OK. What is wrong with that?
Try to change the response header
response.setContentType("text/event-stream");

use of servlet in javascript

I would like to use a java servlet in javascript. For the moment I use this code in javascript:
var req = new XMLHttpRequest();
req.open("GET", "http://localhost:8080/FPvisualizer/test.java" + "?action=test", true);
req.send(null);
req.onreadystatechange = function() {processRequest()};
function processRequest() {
if (req.readyState == 4) {
if (req.status == 200) {
document.getElementById("target").innerHTML = req.responseText;
}
}
}
which communicates with this java servlet:
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class LoadOntology2 extends HttpServlet{
public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String action = request.getParameter("action");
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
response.getWriter().write("<message>valid</message>");
}
}
the req.responseText contains the whole contents of the servlet file (i.e. all the code of that file is displayed on the webpage). Does anybody know what I am doing wrong here?
You are requesting the Java source file itself. You haven't compiled it and installed it on a server configured to execute it for the URL you are using.
I don't have any experience with setting up Java Servlets, but the tutorial at Oracle looks like a good starting point. In particular, the part where it says you need an application server.

I can't retrieve responseText from servlet using AJAX

I have a servlet file called NewServlet.java. This servlet is called by my AJAX script to retrieve the response.
I have verified the servlet by testing it in a browser.
But when I call it from my AJAX script it gives me a blank responseText and an error that says
XMLHttpRequest cannot load
http://localhost:8084/WebApplication1/NewServlet.
Origin null is not allowed by
Access-Control-Allow-Origin
NewServlet.java
import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class NewServlet extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<option value='1'>one</option>");
out.println("<option value='2'>two</option>");
out.println("<option value='3'>three</option>");
out.println("<option value='4'>four</option>");
out.println("<option value='5'>five</option>");
out.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
public String getServletInfo() {
return "Short description";
}
}
test.html
<html>
<head>
<script language = "javascript">
var xmlDoc = 0;
var xhttp = 0;
function reciveData()
{
if (window.XMLHttpRequest)
{
xhttp=new XMLHttpRequest();
}
else // IE 5/6
{
xhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.onreadystatechange = redirectUser;
xhttp.open("GET","http://localhost:8084/WebApplication1/NewServlet",true);
xhttp.send();
}
function redirectUser()
{
if (xhttp.readyState == 4)
{
log = 0;
xmlDoc = xhttp.responseText;
alert(xmlDoc);
}
}
</script>
</head>
<body onload="reciveData()">
</body>
</html>
Can some one point me in a right direction ?
Thanks.
That's on the browser side...the security model only allows AJAX requests to the same host/port that you fetched the page from. Make sure that you've fetched your page via the server (e.g. http://localhost:8084/test.html) and not loaded it via the filesystem. Then you should be good to go...or at least continue debugging. ;)
This can indeed happen when the servlet runs on a different port than where the ajax request is coming from. This violates the Same Origin Policy for ajax requests and thus the browser won't process the ajax response. Apart from hosting the servlet behind the same port, other solutions are to return JSONP instead or to let the servlet set the HTTP Access-Control headers.
response.setHeader("Access-Control-Allow-Origin", "*");
You however need to keep in mind that this way your servlet is by Ajax accessible to everyone. If the servlet returns sensitive information, then this is a security hole. But if it does not and it is supposed to be a public webservice, then it's safe.
in my experience, if you want to load data with ajax, send your request to a jsp file, and get your response text from that jsp file. it is a lot easier to handel. see this example if you like
EDITED<<
==========================
ajax_load.js :
var xmlhttp;
function loadAdminRight(category){
xmlhttp = GetXmlHttpObject();
if (xmlhttp == null) {
alert("Your browser does not support Ajax HTTP");
return;
}
var url = "load.jsp";
url = url + "?category="+category;
xmlhttp.onreadystatechange = getLoad;
xmlhttp.open("GET", url, true);
xmlhttp.send(null);
}
function getLoad(){
if (xmlhttp.readyState == 4) {
document.getElementById("right_content").innerHTML = xmlhttp.responseText;
//or what you want to do
}
}
===========================
load.jsp :
<%# page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
String l_category = request.getParameter("category");
if(l_category.equals("article")){
out.write("You have choosen article category");
out.write("<br/>");
}
}else if(l_category.equals("news")){
out.write("You have choosen article category");
out.write("<br/>");
}
%>
and to make the ajax going you just need to call the .js function from where you want, for example on a button click action :
onClick="loadAdminRight("article");"
and you can import your java classes in a jsp file with adding <%page import="" %> to the top of your jsp page for example :
<%#page import="com.omicc.classes.Article"%>
write your own load.jsp file which handles the response, then use out.write in your jsp file to write the response text.
i wish it helps you
This will solve your issue..
// Ajax response
res.setContentType("text/javascript");
res.setCharacterEncoding("UTF-8");
res.setHeader("Cache-Control", "no-cache");
PrintWriter out = res.getWriter();
out.print("GRANTED");
out.close();

Categories