Send parameter from servlet to servlet - servlets

I have a servlet load_plan, which its doPost method loads a plan with this code:
int id = Integer.parseInt(request.getParameter("id"));
I have another servlet hire_new_plan, which its doGet method sends the id to the load_plan servlet.
hire_new_plan doPost() --> load_plan doGet().
How can I send the id from the doGet method so that I can capture it with the request.getParameter() in the doPost method of the receiver servlet?
There are two problems as I have read.
First of all, I can't call the doPost method from another servlet's doGet method.
Secondly, it seems as if the request.setAttribute("id", id) doesn't match with the int id = Integer.parseInt(request.getParameter("id"));. I execute in the receiver servlet.
What can I do to fix this?

You can use RequestDispatcher to forward to other servlet.
RequestDispatcher rd = request.getRequestDispatcher("load_plan");
rd.forward(request, response);
//or rd.include(request, response);
While forwarding same request object is sent to the called servlet.So you do not need to do anything.It will be available in that request object by default.
If you go this way,doGet will get called of another servlet.
If you can't move your logic in that,I would suggest you to use HttpURLConnection object.You can fire POST request programmatically like this
HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8080/WebAppName/SecondServlet").openConnection();
connection.setRequestMethod("POST");
InputStream response = connection.getInputStream();
// ... Write to OutputStream of your HttpServletResponse
See More
Using java.net.URLConnection to fire and handle HTTP requests

Related

Spring interceptor read response OutputStream

Inside spring controller writes an excel stream into response
HSSFWorkbook workbook = getWorkbook();
OutputStream out = response.getOutputStream();
response.setHeader("pragma", "public");
response.setHeader("Cache-Control", "public");
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;filename=sampleexcel.xls");
workbook.write(out);
out.close();
// response.flushBuffer();
As per this link How to read and copy the HTTP servlet response output stream content for logging
implementated responsewrapper.
Below is Interceptor code,
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
HttpServletResponseCopier resp= new HttpServletResponseCopier(response) ;
byte[] responseData = resp.getCopy();
System.out.println("length "+responseData.length); // its 0 bytes
}
Basically want to read the Outputstream contents into a temp file. Then add encryption information in it. Finally write this encrypted file into response stream.
In above code,resp.getCopy() is empty,hence it writes 0 bytes into temp file.
Any pointers what is wrong.Is there alternate way to do achive this.
Spring 3.1, JDK 1.7
Oups, a spring-mvc interceptor is not a filter. It provides hooks to be called before controller execution, after controller execution and after view generation, but cannot replace the response.
The filter used in the referenced post actually replace the response with a wrapper so that everything that is written to the response actually goes into the wrapper and is processed at the time it is written. Here you only create the wrapper once everything has been written so it can only intercept... nothing.
You will have to implement a filter and a custom response wrapper to achieve your goal.

Liferay: how to get the current login user details in servlet?

I'm completely new to Liferay. I have configured Orbeon Forms in Liferay by using the Proxy Portlet, finally I created an Orbeon form and sent the form data to a demo portlet (custom portlet). In the portlet I have created a servlet. If user save the orbeon form data then my servlet getting called and I'm able to get the form data. Now I need to get the current user name or userid in the servlet.
In form builder I have send the orbeon form data to my servlet.
properties-local.xml
<property
as="xs:string"
name="oxf.fr.detail.process.send.*.*"
value='require-valid
then send(uri = "http://localhost:9090/FRunner-portlet/html/jsp/formData.jsp?username={xxf:get-request-header('Orbeon-Username')}", method="POST", content="metadata")
then success-message("save-success")
recover error-message("database-error")'/>
If I tried the above code I got the following errors,
SEVERE: Exception sending context initialized event to listener instance of class org.orbeon.oxf.webapp.OrbeonServletContextListener
javax.servlet.ServletException: org.orbeon.oxf.common.ValidationException: line 80, column 122 of oxf:/config/properties-local.xml: Fatal error: Element type "property" must be followed by either attribute specifications, ">" or "/>".
at org.orbeon.oxf.webapp.OrbeonServletContextListener$$anonfun$contextInitialized$2.apply(OrbeonServletContextListener.scala:39)
at org.orbeon.oxf.webapp.OrbeonServletContextListener$$anonfun$contextInitialized$2.apply(OrbeonServletContextListener.scala:39)
at org.orbeon.oxf.util.ScalaUtils$.withRootException(ScalaUtils.scala:87)
at org.orbeon.oxf.webapp.OrbeonServletContextListener.contextInitialized(OrbeonServletContextListener.scala:39)
Caused by: org.orbeon.oxf.common.ValidationException: line 80, column 122 of oxf:/config/properties-local.xml: Fatal error: Element type "property" must be followed by either attribute specifications, ">" or "/>".
at org.orbeon.oxf.xml.XMLParsing$ErrorHandler.fatalError(XMLParsing.java:215)
at orbeon.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
at orbeon.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at orbeon.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at orbeon.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at orbeon.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
SEVERE: Exception sending context destroyed event to listener instance of class org.orbeon.oxf.webapp.OrbeonServletContextListener
javax.servlet.ServletException: java.lang.NullPointerException
at org.orbeon.oxf.webapp.OrbeonServletContextListener$$anonfun$contextDestroyed$2.apply(OrbeonServletContextListener.scala:44)
at org.orbeon.oxf.webapp.OrbeonServletContextListener$$anonfun$contextDestroyed$2.apply(OrbeonServletContextListener.scala:44)
at org.orbeon.oxf.util.ScalaUtils$.withRootException(ScalaUtils.scala:87)
at org.orbeon.oxf.webapp.OrbeonServletContextListener.contextDestroyed(OrbeonServletContextListener.scala:44)
at org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:4819)
at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5466)
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:160)
Caused by: java.lang.NullPointerException
at org.orbeon.oxf.pipeline.InitUtils$.org$orbeon$oxf$pipeline$InitUtils$$fromProperty$1(InitUtils.scala:195)
at org.orbeon.oxf.pipeline.InitUtils$.processorDefinitions$lzycompute(InitUtils.scala:196)
at org.orbeon.oxf.pipeline.InitUtils$.processorDefinitions(InitUtils.scala:179)
at org.orbeon.oxf.webapp.Orbeon$.initialize(Orbeon.scala:84)
at org.orbeon.oxf.webapp.OrbeonWebApp$$anonfun$1.apply(WebAppContext.scala:117)
at org.orbeon.oxf.webapp.OrbeonWebApp$$anonfun$1.apply(WebAppContext.scala:117)
at scala.collection.mutable.MapLike$class.getOrElseUpdate(MapLike.scala:189)
at org.orbeon.oxf.webapp.ParametersAndAttributes$$anon$1.getOrElseUpdate(WebAppContext.scala:93)
at org.orbeon.oxf.webapp.OrbeonWebApp$class.$init$(WebAppContext.scala:117)
Update
xxf:get-request-header('orbeon-liferay-user-email')
With the above statement I am able to get the liferay login user mail id. Now I need to pass this username to my portlet as a parameter. Can you please let me know what is the procedure to pass the mailid to my portlet. I tried in different ways but it is not happen. Please suggest me something to send the liferay user mail id to my portlet.
FormData Servlet code
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
try {
DataInputStream in = new DataInputStream (request.getInputStream());
StringBuffer buffer = new StringBuffer();
int value;
while ((value=in.read()) != -1) {
buffer.append((char)value);
}
String formData = buffer.toString();
System.out.println("Form Data==========>"+ formData);
} catch (Exception e) {
System.out.println("ERROR2=====>"+e);
}
}
How to get the current user details when servlet getting called?
One way is to explicitly pass it to the URL of the send action, for example:
uri = ".../FormData?username={xxf:get-request-header('Orbeon-Username')}"
In Orbeon Forms 4.9, there is a new xxf:username() function which is more direct.
On the servlet side, you can retrieve a URL parameter using:
request.getParameter("username")

How to Read the message Body in a HTTP POST in Netty (version >= 4.x)

In my server handler;
- channelRead() always gets the msg as HTTPRequest and there I cannot find any place to get the POST request payload.
Then I tried following in my handler to check if it works. The decoder has 0 elements.
HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), request);
In my server pipeline I have HttpServerCodec and a custom handler only.
It's likely that your HTTP request is chunked. You should try to add an io.netty.handler.codec.http.HttpObjectAggregator to your pipeline, just after the codecs. It will give a FullHttpRequest to your handler.
ChannelPipeline p = ...;
...
p.addLast("encoder", new HttpResponseEncoder());
p.addLast("decoder", new HttpRequestDecoder());
p.addLast("aggregator", new HttpObjectAggregator(1048576));
...
p.addLast("handler", new MyServerHandler());
Alternatively, you could check this example where HttpRequest and HttpContent are handled separately.
As Leo Gomes mentioned, HTTP Request maybe chunked. so add HttpObjectAggregator before your own handler in pipeline.
if HTTP POST request body is Simple Json String. You can parse it in your own handler like this:
private String parseJosnRequest(FullHttpRequest request){
ByteBuf jsonBuf = request.content();
String jsonStr = jsonBuf.toString(CharsetUtil.UTF_8);
return jsonStr;
}

Spring MVC with HttpPutFormContentFilter can't get RequestBody when use PUT method

I have added the HttpPutFormContentFilter in web.xml.
Here is an action for reveiving both GET,POST,DELETE and PUT method.
#RequestMapping(value = "/**")
public ResponseEntity<byte[]> proxy(HttpServletRequest request,#RequestParam MultiValueMap<String, String> params, #RequestBody byte[] body, #RequestHeader MultiValueMap<String, String> headers) {
When I use POST and add the application/x-www-form-urlencoded header,I can get both the request body and request param.
When I use PUT and add the application/x-www-form-urlencoded header,I can get the request param,but I can't get request body!
There is any bug in the HttpPutFormContentFilter?
According to the Servlet specification (see chapters 1.1 and 3.1.1), when you receive a POST request and the content type is application/x-www-form-urlencoded, that form data needs to be made available through the HttpServletRequest#getParameterXXX() methods. This is not true for PUT requests.
In all cases, the body of the HttpServletRequest is available as an InputStream to Servlet and Filter instances.
For POST, when Spring sees
#RequestParam MultiValueMap<String, String> params
it uses a RequestParamMapMethodArgumentResolver to resolve the argument. This reads directly from the HttpServletRequest parameter map. When Spring sees
#RequestBody byte[] body
it uses a RequestResponseBodyMethodProcessor which reads from the HttpServletRequest InputStream using a ByteArrayHttpMessageConverter to fill up a byte[].
Once you've read the HttpServletRequest InputStream, you cannot re-read (in the default configuration).
For PUT, because the Servlet container doesn't store form parameters in the HttpServletRequest for PUT requests, Spring decided to introduce the HttpPutFormContentFilter. This Filter reads the HttpServletRequest body to populate its own parameter map in an HttpServletRequestWrapper which it hands you.
Once this is done, the request parameters are available to the RequestParamMapMethodArgumentResolver, but when the RequestResponseBodyMethodProcessor tries to fill up the byte[], there are no bytes left in the InputStream so it leaves it empty.
One workaround is to create your own Filter (which must execute before the HttpPutFormContentFilter, so it's kind of bad practice), which wraps the HttpServletRequest in a HttpServletRequestWrapper which buffers the InputStream in a ByteArrayInputStream so you can re-read it as many times as necessary.

RequestDispatcher ending in infinite loop

I have two WAR applications and the mode of communication between them is via servlets.
My application (WAR A) opens a child window with the URL of a servlet in another WAR (lets say WAR B).
The servlet (in WAR B) processes the data and should send the processed data back to original application's servlet (i.e WAR A's servlet).
But this process ends in an infinite loop and also the URL parameters sent from WAR-A are null.
Here is the code snippet :
The below script opens a child window with the URL of servlet in WAR-B also passing some URL parameters.
function invokePlugin(invokeURL, custValJSON, meaCompPartJSON) {
window.open(invokeURL + '?custValJSON=' + custValJSON,'');
}
Below is servlet code in WAR-B which extracts the URL parameters and process the data and again send the request back to WAR-A's servlet...
private void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String custValJSON = request.getParameter("custValJSON");
System.out.println("custValJSON : " + custValJSON);
CustomValues custVal = gson.fromJson(custValJSON, CustomValues.class);
if(custVal != null) {
System.out.println("Cust val details : " + custVal.getName());
custVal.setValue("Satya");
}
String destination = "/testPlannerPluginResult";
RequestDispatcher reqDispatch = request.getRequestDispatcher(destination);
request.setAttribute("custValJSON", gson.toJson(custVal));
if(reqDispatch != null) {
reqDispatch.forward(request, response);
}
}
Does anybody have idea on this?
Regards,
Satya
That then just means that the servlet is basically calling itself everytime. I don't immediately see the cause in the information given so far, but apparently the URL which you passed into the getRequestDispatcher() matches the URL of the servlet itself.
I however see a major mistake here:
RequestDispatcher reqDispatch = request.getRequestDispatcher(destination);
request.setAttribute("custValJSON", gson.toJson(custVal));
That can impossibly invoke the servlet which runs in another servlet context (read: another WAR). You need ServletContext#getContext() first to get the other servlet context and then use ServletContext#getRequestDispatcher() to dispatch the request to there.
ServletContext otherServletContext = getServletContext().getContext("/otherContextPath");
RequestDispatcher dispatcher = otherServletContext.getRequestDispatcher(destination);
This only requires that the both WARs are configured to expose the context for sharing. On Tomcat for example, this is to be done by adding crossContext="true" to the <Context>.

Resources