Aspectj: get Response body (HTML Text) from HttpServletRresponse - java

I m trying to use aspectJ to intercept HttpServlet.do*(request, response) and get the HTML text ( need to extract the title and maybe store the html to a file).
What is the best way to access the response body (html text) once I have a reference to the HttpServletResponse?
Here is my staring code.
public aspect HttpRequestHandlerAspect {
pointcut getRequest(HttpServletRequest request, HttpServletResponse response)
: execution(protected * javax.servlet.http.HttpServlet.*(HttpServletRequest, HttpServletResponse))
&& args(request, response);
Object around(HttpServletRequest request, HttpServletResponse response) : getRequest(request, response) {
Object ret = proceed(request, response);
// now how do I access the HTML response text ( and get the title of the page) in here?
}
}

This might not be the precise answer for your question, but try extracting the response as suggested here: How can I read an HttpServletReponses output stream?
You don't have to create a filter, only an HttpServletResponseWrapper which you pass to
proceed(request, wrapper).
Object around(HttpServletRequest request, HttpServletResponse response): getRequest(request, response) {
MyHttpServletResponseWrapper wrapper = new MyHttpServletResponseWrapper(response);
Object ret = proceed(request, wrapper);
// The MyHttpServletReponseWrapper class captures everything and doesn't forward to the original stream, so we have to do this
response.getWriter().write(wrapper.toString());
// use wrapper.toString() to access response
}

Related

Return Response (HttpServletResponse) to HttpServletRequest

I always end up with a ClassCastException when trying to cast javax.ws.rs.core.Responseinto ajavax.servlet.http.HttpServletResponse
My Servlet looks like this:
#GET
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Response myResponse = processRequest(request);
//myResponse -> response
}
The servlet is hosted on a a jetty:
context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.addServlet(new ServletHolder(servlet),"/*");
I want to return the content of myResponse (basically some json body if it matters) if this is possible.
Can someone help?
I don't think you can send the response from servlet to upstream in Response(Custom) format.
You need to set the value in HttpServletrequest and HttpServletResponse while sending the response to upstream.
Below is my suggestion for sending the data in json format in servlet.
Put your JSON data as a string in a String object.
Set this object in request.setAttribute(); and use the name of the attribute to fetch the value in your ajax function. use JSON.parse() to convert the string to JSON.

Render HTML response from remote call to the client

I have a working servlet wich originates back from this template:
http://www.objectdb.com/tutorial/jpa/eclipse/web/servlet
So the basic rountrip works.
I added a new feature where I POST data to the servlet, construct a call/request out of the data to a remote http server, retrieve the response-html-string (the content of the website I requested) and want to show this HTML String now as response to my original POST call.
I tried it like this:
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
boolean showDetails = Boolean.valueOf(request.getParameter("showDetails"));
if (showDetails) {
String details = detailsLoader.loadDetails(String.valueOf(request.getParameter("value1")),
String.valueOf(request.getParameter("value2")));
response.getWriter().println(details);
response.getWriter().flush();
response.getWriter().close();
return; // <----------------- if showDetails then this is the end of doPost
}
// Display the list of guests:
doGet(request, response);
}
When I press the link that creates the POST event I see in the logfile, that "loadDetails" has succesfully loaded the content from the remote server, but the browser window does not refresh. Why?
PS: a simple redirect to the other side is not possible for technical reasons.
Try making a ajax request to your servlet which gives to html content as string sent it back to ajax call and set it to innerHTML of a div element.
I changed to use GET instead of POST and I used a separate Servlet for this kind of call. This solved my problem.
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String details = detailsLoader.loadDetails(String.valueOf(request.getParameter("value1")),
String.valueOf(request.getParameter("value2")));
response.getWriter().println(details);
response.getWriter().flush();
response.getWriter().close();
}

handle ajax request and send response java servlet

I have an ajax request function (written in JavaScript) and Java Servlet that handles this request. I need to get all request parameters and if it succeeded then send back a confirmation that it has succeeded. How I can send a confirmation message? As an attribute, like {isSuccess: true}. My code:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
Enumeration<?> paramNames = request.getParameterNames();
while (paramNames.hasMoreElements()) {
String paramName = (String) paramNames.nextElement();
// storing data fn
}
// how to send back a message here?
}
Get PrintWriter object by calling HttpServletResponse#getWriter and write your String.
response.getWriter().write("{isSuccess: true}");

reading custom headers in servlets

I have a requirement to set custom headers in http response and read them whenever required. I use the following code to read the header.
servlet1:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.addHeader("cust-header", "cust-value");
RequestDispatcher rd = request.getRequestDispatcher("servlet2");
rd.include(request, response);
}
servlet2:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println(request.getHeader("cust-header"));
}
When I tried to read the custom header value, I got "null" in the console. Why this is happening? How can I read custom headers set in response whenever required?
From the RequestDipatcher include method API doc:
[...]
The ServletResponse object has its path elements and parameters remain
unchanged from the caller's. The included servlet cannot change the
response status code or set headers; any attempt to make a change is
ignored.
[...]
So, if you look at your code, you are setting the header at the response object, but trying to get it from the request.
As they remain unchanged, it won't work.
The most common way to pass values from a servlet to another in a forward or include redirection, is passing it as a request attribute:
servlet1:
//set a request attribute
request.setAttribute("cust-header", "cust-value");
RequestDispatcher rd = request.getRequestDispatcher("servlet2");
rd.include(request, response);
servlet2:
System.out.println(request.getAttribute("cust-header"));

Configure tomcat to accept post request

How can I configure tomcat so when a post request is made the request parameters are outputted to a jsp file? Do I need a servlet which forwards to a jsp or can this be handled within a jsp file ?
Here is my method which sends the post request to the tomcat server -
public void sendContentUsingPost() throws IOException {
HttpConnection httpConn = null;
String url = "http://LOCALHOST:8080/services/getdata";
// InputStream is = null;
OutputStream os = null;
try {
// Open an HTTP Connection object
httpConn = (HttpConnection)Connector.open(url);
// Setup HTTP Request to POST
httpConn.setRequestMethod(HttpConnection.POST);
httpConn.setRequestProperty("User-Agent",
"Profile/MIDP-1.0 Confirguration/CLDC-1.0");
httpConn.setRequestProperty("Accept_Language","en-US");
//Content-Type is must to pass parameters in POST Request
httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
// This function retrieves the information of this connection
getConnectionInformation(httpConn);
String params;
params = "?id=test&data=testdata";
System.out.println("Writing "+params);
// httpConn.setRequestProperty( "Content-Length", String.valueOf(params.length()));
os = httpConn.openOutputStream();
os.write(params.getBytes());
} finally {
if(os != null)
os.close();
if(httpConn != null)
httpConn.close();
}
}
Thanks
First of all, your query string is invalid.
params = "?id=test&data=testdata";
It should have been
params = "id=test&data=testdata";
The ? is only valid when you concatenate it to the request URL as a GET query string. You should not use it when you want to write it as POST request body.
Said that, if this service is not supposed to return HTML (e.g. plaintext, JSON, XML, CSV, etc), then use a servlet. Here's an example which emits plaintext.
String id = request.getParameter("id");
String data = request.getParameter("data");
response.setContentType("text/plain");
response.setContentEncoding("UTF-8");
response.getWriter().write(id + "," + data);
If this service is supposed to return HTML, then use JSP. Change the URL to point to the JSP's one.
String url = "http://LOCALHOST:8080/services/getdata.jsp";
And then add the following to the JSP template to print the request parameters.
${param.id}
${param.data}
Either way, you should be able to get the result (the response body) by reading the URLConnection#getInputStream().
See also:
How to use URLConnection to fire and handle HTTP requests?
Unrelated to the concrete problem, you are not taking character encoding carefully into account. I strongly recommend to do so. See also the above link for detailed examples.
A servlet can handle both get and post request in following manner:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//remaning usedefinecode
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
If you have a tomcat installation from scratch, don't forget to add the following lines to web.xml in order to let the server accept GET, POST, etc. request:
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
...
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
...
</servlet>

Categories