Showing servlet's list output in table using ajax asynchronously - java

I'm new to ajax and don't know how to use it for displaying my data from sevlet on page asynchronously.Moreover I must not to use additional libraries like jquery. So I have to "reinvent a wheel" not knowing how it wheel looks like. So I have simple servlet which sends to my request List of plain beans, here is it's doGet:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
List<Category> categoryList = dao.getCategoryList();
request.setAttribute(PARAM_NAME_CATEGORY_LIST, categoryList);
RequestDispatcher dispatcher = getServletContext()
.getRequestDispatcher(PRODUCT_PAGE);
dispatcher.forward(request, response);
}
And after forwarding to my page I need to represent data in table with help of ajax.

Loading data and displaying it in AJAX is made in several steps:
The page sends an AJAX request to a URL of the wabapp. It registers a JavaScript callback function that will be called when the response to the request is received.
The webapp generates a response to this request. The content of the response could be HTML, XML, JSON or anything else.
The JavaScript callback function is called.
The JavaScript callback function gets the data from the response, and updates the DOM tree of the page to display the received data.
Googling for "AJAX example" will lead you to plenty of tutorials explaining how to do that. If you have a more specific problem, come back.

Related

How to handle a POST request with a Servlet API

I am trying to make an API with Jetty Server, and I have this simple GET request:
#GET
public String helloWorld(){
return "Hello world";
}
In order to make a POST request, I assume that one must save the input to the Jetty server. I have tried to research for quite a while, but found nothing.
I imagine something like this:
#POST
public void Save(String stringToSave) {
// Save to DB?
}
You could likely google this but let me give you a quick overview. A Servlet is a chunk of code that is normally run during an HTTP action - GET, POST, etc. It is the original technology of the JavaEE world, having been released in the late 1990's.
A simple Java servlet, using modern annotations, would look something like:
#WebServlet(name = "SampleServlet", urlPatterns = "/sampleServlet")
public class SampleServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// called when an HTTP POST is sent
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// called when an HTTP GET is sent
}
}
The important parts to note are that the class extends HttpServlet and that you have to write code to pull data out of the request and push it into the response. This isn't bad to do but it does have to be done.
JAX-RS is a newer standard, aimed simplifying the creation of REST services. It too is a chunk of code that runs during an HTTP interaction.
A simple example of this would be:
#Path("/sampleService")
public class SampleService{
#Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
#Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
#POST
#Path("/v1/hello")
public Response sayHello( SomeObject someobject ) {
The code here is both simpler and a bit more complex. The use of annotations helps determine the path that the service exists on a URL (in this case /sampleService/v1/hello), the HTTP method, and the Content-Type for both the request and response. Additionally, if the SomeObject object is defined correctly, the JAX-RS framework will automatically deserialize the incoming JSON or XML payload into an object for you.
The Response object contains the HTTP response code (perhaps a teapot) and a response body. In this example, the body will be automatically serialized back to the requestor in a way that matches the Accept header of the HTTP request (i.e., JSON for an application/json Accept header and XML for application/xml).
Note that while not directly related the JAX-RS framework takes advantage of the Servlet framework. Indeed in JAX-RS you can access the HttpServletRequest and HttpServletResponse object in your methods.
Which way is "better"? In general I would recommend using JAX-RS where possible as it is the newer standard and is a bit easier to implement. However, if you do any work in the JavaEE world you're very likely to run into Servlet code so it's important to understand it too.
Note that both Servlets and JAX-RS require an application server of some sort. Jetty is one of those. Another very common one is Tomcat. The application server sets up the environment for your code and listens for incoming HTTP messages. When it gets one it looks to see if it knows how to handle the URL and routes to the appropriate place. In the servlet world the server routes solely on the URL. In the JAX-RS world the server routes on the URL and, if specified by the #Consumes annotation, the HTTP Content-Type header too.
There is much more but let's start there and see if it answers what you're after.

HttpServletRequest stored in model gets replaced

I'm working on a legacy code (Spring 2.5.x, Java 1.5), where controller passes Http Servlet Request to view like this:
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
Map attributes = new HashMap();
attributes.put("httpRequest", request);
return new ModelAndView("/path/to/page.jsp", attributes);
}
However what happens is that httpRequest attribute does indeed exist in the JSP Page context, but it contains current request (JSP page) and not the original (controller). The passed request is being used to extract some information from the URL. It appears that I can get around that problem by using a bunch of "javax.servlet.forward.*" attributes. This however puzzles me as it is pretty simple thing and I'd be happy to get it to work anyways or at least know exactly why it doesn't work now. Anybody has any ideas?
To begin with, it is a bad idea to store the request as attribute of request. If you need specific data for the current request, you can retrieve it directly using ${requestContext}, if you need to access to the URL, use ${requestContext.requestURL}. If you need to access to parts of this URL to display it in client side, it would be better to parse the url in server side (controller) by first obtaining it using StringBuffer url = request.getRequestURL(); and then setting the required data as attributes.

Code to get a Java servlet to act as a proxy?

I have two Java web applications that have a single servlet that gets mapped to a specific URL:
red.war/
WEB-INF/classes
com.me.myorg.red.RedServlet (maps to http://red.example.com/doStuff)
blue.war/
WEB-INF/classes
com.me.myorg.blue.BlueServlet (maps to http://blue.example.com/doStuff)
I want to put these application (I'm calling them my "backend apps") behind a "proxy app" (servlet) that will decide which of these two apps will ultimately service a client-side request.
This proxy web app would take an incoming HTTP request, and determines which of the 2 "backend apps" (red or blue) to forward the request onto. The request would then be forwarded on to either http://red.example.com/doStuff (and then processed by RedServlet#doGet(...)) or http://blue.example.com/doStuff (and then processed by BlueServlet#doGet(...)). The returned response from the backend app (again, either RedServlet#doGet(...) or BlueServlet#doGet(...)) would then be returned to the proxy servlet, and ultimately returned to the client.
In other words, in pseudo-code:
public class ProxyServlet extends HttpServlet {
#Override
public doGet(HttpServletRequest request, HttpServletResponse response) {
String forwardingAddress;
if(shouldBeRed(request))
forwardingAddress = "http://red.example.com/doStuff";
else
forwardingAddress = "http://blue.example.com/doStuff";
PrintWriter writer = response.getWriter();
writer.write(getResponseFromBackend(forwardingAddress, request));
}
private String getResponseFromBackend(String addr, HttpServletRequest req) {
// Somehow forward req to addr and get HTML response...
}
}
Is this possible? If so, how and what code would I need to write to make it work?
You could use a RequestDispatcher to forward your request in the following way:
RequestDispatcher dispatcher = httpRequest.getRequestDispatcher(forwardingAddress);
// here you have the choice whether to use include(..) or forward(..) see below
if(useInclude)
dispatcher.include(httpRequest, httpResponse);
else
dispatcher.forward(httpRequest, httpResponse);
... where useInlcude is set to your choice with the following options:
includeThis is probably what you want to do: Load the content from the forwardingAdress into your response.
This means you could even include multiple targets into a single response.
The client will not even realize this procedure nor does he need to be able to see the target document.
forwardSend a forward to the forwardingAddress. This will tell the client to submit a new request to the specified URL.
If you do it in a browser with developer tools, you will see a second request.
The client must be able to see and load the target URL.
You can only forward to a single target.
See, the following links, too:
RequestDispatcher javadoc, especially for the notes:
forward should be called before the response has been committed to the client (before response body output has been flushed). If the response already has been committed, this method throws an IllegalStateException. Uncommitted output in the response buffer is automatically cleared before the forward.
include: The request and response parameters must be either the same objects as were passed to the calling servlet's service method or be subclasses of the ServletRequestWrapper or ServletResponseWrapper classes that wrap them.
URLRewriteFilter examplealthough this example is implemented using a Filter instead of a Servlet the behavior is the same (Note: this example is part of a framework of mine and hence contains some overhead in the parent classes. Just have a look at the relevant section...)
Since there is not yet an approved answer I try to write how I see the solution to this request use apache-http-commons library. In addition I suggest to add a flush on writer.
public class ProxyServlet extends HttpServlet {
#Override
public doGet(HttpServletRequest request, HttpServletResponse response) {
String forwardingAddress;
if(shouldBeRed(request))
forwardingAddress = "http://red.example.com/doStuff";
else
forwardingAddress = "http://blue.example.com/doStuff";
PrintWriter writer = response.getWriter();
writer.write(getResponseFromBackend(forwardingAddress, request));
**writer.flush();**
}
private String getResponseFromBackend(String addr, HttpServletRequest req) {
HttpClient client = new HttpClient();
HttpMethod method = new GetMethod(url);
client.executeMethod(method);
String body=method.getResponseBodyAsString();
return body;
}
}

Accessing a HashMap of custom objects in request scope after a redirect

I have a HashMap of custom objects being passed to a JSP using RequestDispatcher and I am able to access the object and its properties using JSTL.
However the code fails in case the parameter is sent using response.sendRedirect() .
I am not sure what the reason is and how to make it work?
The response.sendRedirect() basically instructs the client (the webbrowser) to send a new request on the given URL. You'll also see this being reflected by a change in the browser address bar.
A new request does of course not contain the attribtues of the previous (or any other) request. That would otherwise have broken the whole concept of "request scope".
To preprocess a GET request, you need to do the job in doGet() method of a servlet and then redirect to the URL of that servlet instead.
E.g.
response.sendRedirect(request.getContextPath() + "/foo");
and
#WebServlet("/foo")
public class FooServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Map<String, Foo> foos = fooService.map();
request.setAttribute("foos", foos);
request.getRequestDispatcher("/WEB-INF/foo.jsp").forward(request, response);
}
}
Note that this problem is in no way related to having a hashmap of custom objects in the request scope.
See also:
Our servlets wiki page
You can not share a request attribute in response.sendRedirect as it creates a new request.
But, if you want that HashMap, in response.sendRedirect, you can put that in session like
request.getSession().setAttribute("myMap", [HashMap object]);
and can share between the servlet and JSP. This works in both RequestDispatcher and sendRedirect.

RequestDispatcher in Java

What exactly the main purpose of using RequestDispatcher, for example when it's executed in Filter like the following example:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws ServletException, IOException {
HttpServletRequest aHttpServletRequest = (HttpServletRequest) request;
aHttpServletRequest.getRequestDispatcher("/init.jsp").include(request, response);
chain.doFilter(request, response);
}
In your case, the output of JSP is prepended to every page that filter is attached. This is a technique to easily add a common header to all your pages.
It's a little bit confusing when RequestDispatcher is used int his context. Normally, when you want to dispatch your request to another servlet or JSP for process, you use RequestDispatcher to forward to another resource. In this case, your request is not dispatched anywhere else, instead you include output generated by another resource to your current response.
The javadoc says is better than I can:
RequestDispatcher:
Defines an object that receives
requests from the client and sends
them to any resource (such as a
servlet, HTML file, or JSP file) on
the server. The servlet container
creates the RequestDispatcher object,
which is used as a wrapper around a
server resource located at a
particular path or given by a
particular name.
In other words, you obtain a RequestDispstcher when you want to include from, or forward to, another resource on the server.

Categories

Resources