Redirect saving POST parameters using HTTP - java

I have 2 web-pages.
So, 1st page takes some POST parameters, and then process it. I want to redirect this query(with all POST params) to my own 2nd page, if parameter "appId" = "myApp";
In start of 1st page I make next:
if (getParameter("id") == "myApp")
{
request.setHttpHeader("") - ??? WHAT MUST BE HERE? WHICH HEADERS?
}
P.S. I need only HTTP solution, using native (java) methods (like forward and redirect) don't help me.
Thanks.

You have to user RequestDispatcher.forward. Here is an example.
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ForwardServlet extends HttpServlet{
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
/*
* You can do any processing here.
* We will simply output the value of name parameter on server console.
*
*/
System.out.println(name);
String destination = "/DestinationServlet";
RequestDispatcher rd = getServletContext().getRequestDispatcher(destination);
rd.forward(request, response);
}
}

What you're asking for can't be done with pure HTTP. You can only redirect GETs with HTTP. See this answer to a similar question https://stackoverflow.com/a/1310897/116509

Related

Handling POST requests from a remote website/Sigfox with Jetty 9.4.1

I'm new to Jetty and networking with Java so please bear with me and my beginners questions.
What I want to do is process a payload sent from Sigfox in the application/x-www-form-urlencoded format i.e. the data will come as "device={device}&data={data}&time={time}".
I've learnt that I can actually make a Sigfox Callback to a Java app server. Correct me if I'm wrong but I was thinking that a servlet can serve just the same purpose?
This is why I decided to embed Jetty into my Java application (I'm using the latest Jetty 9.4.1).
Following the Embedded Jetty tutorial I've made this program:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import java.net.InetSocketAddress;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler;
public class MinimalServlets
{
public static void main( String[] args ) throws Exception
{
// Create a basic jetty server object that will listen on port 9081.
// Note that if you set this to port 0 then a randomly available port
// will be assigned that you can either look in the logs for the port,
// or programmatically obtain it for use in test cases.
Server server = new Server(new InetSocketAddress("MY_IP", 9081));
// The ServletHandler is a dead simple way to create a context handler
// that is backed by an instance of a Servlet.
// This handler then needs to be registered with the Server object.
ServletHandler handler = new ServletHandler();
server.setHandler(handler);
// Passing in the class for the Servlet allows jetty to instantiate an
// instance of that Servlet and mount it on a given context path.
// IMPORTANT:
// This is a raw Servlet, not a Servlet that has been configured
// through a web.xml #WebServlet annotation, or anything similar.
handler.addServletWithMapping(HelloServlet.class, "/*");
// Start things up!
server.start();
// The use of server.join() the will make the current thread join and
// wait until the server is done executing.
// See
// http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#join()
server.join();
}
#SuppressWarnings("serial")
public static class HelloServlet extends HttpServlet
{
#Override
protected void doGet( HttpServletRequest request,
HttpServletResponse response ) throws ServletException,
IOException
{
response.setContentType("text/html");
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().println("<h1>Hello from HelloServlet</h1>");
// System.out.println("\nConnected");
// System.out.println(request.getParameter("data"));
}
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
// Get POST parameters
String val = req.getParameter("data");
System.out.println(val); //print value of 'data'
// Write a response
resp.setContentType("text/html");
resp.setCharacterEncoding("UTF-8");
resp.setStatus(HttpServletResponse.SC_OK); //respond with "200"
resp.getWriter().printf("data = %s",val);
}
}
}
However it doesn't receive the payload from Sigfox nor does it respond with "200". On the Sigfox end it says the "connection has timed out":
Screenshot of callback error
From my reading of the Jetty architecture, HttpServlet and ServletHandler is the right way to go? So where am I going wrong with my understanding and code?
Thanks in advance!

Invisible HeaderFilter after invoking chain.doFilter()

I have a HeaderFilter containing simple String which I want to add to a servlet's html.
When I invoke chain.doFilter(req, resp) in HeaderFilter doFilter() method, the mentioned text is invisible and I thought it could be somehow overwritten? However, when I do not invoke chain.doFilter(req, resp), the text is visible but the rest is not.
What is the problem?
So that's my code in HeaderFilter class:
package com.example;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
public class HeaderFilter implements Filter {
private String header = "<table cellpadding='2' cellspacing='2' border='1' width='100%'>"
+ "<tbody><tr><td valign='Top' bgcolor='#000099'>"
+ "<div align='Center'><font color='#ffffff'>Header</font></div></td>"
+ "</tr></tbody></table>";
private Properties encodings = new Properties();
public void init(FilterConfig fc) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
Locale locale = req.getLocale();
String charset = (String) encodings.get(locale);
if (charset == null)
charset = "windows-1250";
resp.setContentType("text/html; charset=" + charset);
PrintWriter out = resp.getWriter();
out.println(header);
chain.doFilter(req, resp);
}
public void destroy() {
}
}
Not sure if I should post any other code?
If you read filter essentials, there is written:
Modifying the response headers and data. You do this by providing a
customized version of the response.
and
A filter that modifies a response must usually capture the response
before it is returned to the client. The way to do this is to pass the
servlet that generates the response a stand-in stream. The stand-in
stream prevents the servlet from closing the original response stream
when it completes and allows the filter to modify the servlet's
response.
So the explanation is easy:
When you do not call next item in the filter chain, your code will be written and returned to the browser. But when you pass control to the next filter, it will be replaced.
To achieve your effect, you need to:
call filter chain
grab final response to StringBuilder
find the location of HTML table tag
insert your HTML code
write modified response
See the linked document for code samples.

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.

Get client environment information by cookies

I just started with Java servlets few days ago. I am trying to develop a program just for practice and to get to know the the stuff we can do with Java servlets.
Trying to have a program that generates a cookie and sends it back to the client in response.
Sending back the cookie and getting cookie info back is fine, but what I want to do is that can we get information about the clients environment using cookies as well as can we get the browser information using cookies, such as which browser, its version, OS, etc.
I know they store state information since HTTP is stateless. So I was just wondering and trying is there a way to get client's environment information and browser information by cookies in servlets.
Cookies are not designed to get client information. You have to use javax.servlet.http.HttpServletRequest methods - getHeader() or getHeaders() method to read request header key-value.
Enumeration names=request.getHeaderNames();
while(names.hasMoreElements())
{
String key=names.nextElement().toString();
String value=request.getHeader(key);
}
Want to get value of user-agent key.
String userAgent=request.getHeader("user-agent");
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GetCookiesServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
response.setContentType("text/html");
PrintWriter pw = response.getWriter();
pw.println("<B>");
for (int i = 0; i < cookies.length; i++) {
String name = cookies[i].getName();
String value = cookies[i].getValue();
pw.println("name = " + name + "; value = " + value);
}
pw.close();
}
}
Please visit this link

How to recursively call servlet from same servlet

I would like to recursively call a servlet from itself until my operation completes. The reason I need to do this is because my hosting service has a hard deadline that must be met for all RPC calls. Therefore, I need to break up the operation in managable chunks and call the servlet recursively for each chunk until the operation completes.
I feel like the following code should work, but it is not calling the servlet when the HttpURLConnection is opened and connected. No errors are being thrown either. Any help would be greatly appreciated.
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#SuppressWarnings("serial")
public class ServletExample extends HttpServlet {
HttpServletRequest request;
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
request = req;
String strRequestIndex = request.getParameter("requestIndex");
int intRequestIndex = 0;
if (strRequestIndex != null) {
intRequestIndex = Integer.parseInt(strRequestIndex);
}
if (intRequestIndex < 10) {
try {
callSameServlet(intRequestIndex);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void callSameServlet(int requestIndex) throws Exception {
URL recursiveUrl = new URL(request.getRequestURL().toString()
+ "?requestIndex=" + (requestIndex + 1));
HttpURLConnection connection = (HttpURLConnection) recursiveUrl
.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.connect();
DataOutputStream dos = new DataOutputStream(
connection.getOutputStream());
dos.flush();
dos.close();
}
}
As to the technical problem as exposed in your question: the URLConnection is lazily executed. The URLConnection#getOutputStream() in your code only returns a handle to write the request body. You need to use URLConnection#getInputStream() to actually fire the HTTP request and obtain the response body.
See also:
How to use URLConnection to fire and handle HTTP requests?
There are however more problems in your code:
You're firing a POST request, but there's nowhere a doPost() method in your servlet definied. You need to either fire a normal GET or to implement doPost(). But that'll be obvious by investigating the obtained error response as described in the above link.
Also, your servlet is not threadsafe. You should never declare/assign request/session scoped data as instance variable of the servlet. Read this answer to learn more.
Finally, did you consider using RequestDispatcher#include() instead? That will be handled internally and saves you the cost/overhead of firing HTTP requests.
request.getRequestDispatcher("servleturl").include(request, response);
You can then use request attributes instead of request parameters. The whole functional requirement makes little sense by the way. I'd just use a for or while loop on the code you'd like to execute recursively. But that's a different problem.

Categories