Is there a way to set request attributes in a ContentExchange object? What I have been doing so far is send information to the server in the Request body by using the setRequestContentSource(InputStream inputstream) method. But what should I do if I want to send information categorized by field names, say like, Content, Title, Author etc.?
The code that I have as of now is pasted below. Thanks for your help!
exchange.setRequestContentSource(new ByteArrayInputStream(
serialized.getBytes("UTF-8")));
exchange.setRequestContentType("text/html");
exchange.setMethod("POST");
exchange.setURL(("http://localhost:8089/"));
client.send(exchange);
To be more precise, by request attributes, I mean something equivalent to request.setAttribute("Name","ABC"). Only in this case, the request is sent is through the ContentExchange object.
Ah, so ServletRequest attributes are not part of the HTTP protocol.
There is no standard way to send those attributes via a HTTP protocol.
In fact, the servlet spec itself limits its use for application specific information (such as passing information from a filter to a servlet) and SSL certificate related information.
However, using standard POST and form data, via exchange.setRequestContentType("multipart/form-data"); and obtain those values using HttpServletRequest.getParameter("Content"), etc.. similar to how a FORM is submitted from a web browser. Benefit here, is that you can even provide a simple HTML FORM to test our your application.
Choice #2 is to send your data in a markup like JSON or XML and have the server parse it.
This has the benefit of allowing for hierarchical data.
If this interests you, I'd recommend you read about REST and maybe dig into a REST library like Jersey, Restlet, and standards like JAX-RS.
Related
How do I change HTTP method in javax,servlet.RequestDispatcher?
I have some old service APIs that support GET and POST, The new version supports DELETE method for removing a record which used to happen through POST earlier.
We are decommissioning old version APIs by setting RequestDispatcher.forward() for old end points (stop gap arrangement until clients change). everything was cool except this POST to DELETE mapping.
Any solution there for this problem without adding POST end point for delete operation in new API?>
Although I agree using the next layer after your servlets would be a better choice, this is interesting. It use to be common to wrap an incoming request to add request based functionality (IE: auth state, etc). The HttpServletRequestWrapper was used to accomplish this. You could do the following if you just need to change the method:
class PostDeleteAdapter extends HttpServletRequestWrapper {
public String getMethod(){ return "POST"; }
}
You may also change other aspects of the incoming request if you need to further adapt the request. This may play well with your servlet containers RequestDispatcher, however it's dependent upon the container entirely.
I think you can't do it using servlet API. You can do what you want creating a new request, processing it's response and sending it back through the original response (in the servlet).
Some http clientes might help you. See Apache HTTP client:
http://hc.apache.org/httpclient-3.x/methods/delete.html)
In Java servlets you read a JSON from a POST request e.g. via
new JSONObject(toString(httpRequest.getInputStream()))
Now additionally to the JSON I would like to specify parameters in the URL, they can be read via:
httpRequest.getParameterMap().get("someURLParam")
All is working (I'm using AJAX post requests and jetty for server side)
BUT
I'm concerned and confused if and when these two methods influence each other as the javadocs from javax.​servlet.​ServletRequest.getParamter(String) says:
If the parameter data was sent in the request body, such as occurs
with an HTTP POST request, then reading the body directly via
ServletRequest.getInputStream or ServletRequest.getReader can
interfere with the execution of this method.
What does it mean in my case? Or do they only interfere if content type is x-www-form-urlencoded? Or only if using getParameter and the method getParameterMap is fine?
If you are only using getParameter/getParameterMap, you will be fine. This is because, behind the scenes, those methods may call getInputStream. The spec says MAY because it's up to the implementation, so the behavior may vary from one container to another.
If your content isn't form encoded, or you are processing a GET request, etc., getParameter/getParameterMap only needs to get the parameters from the query string, so it makes sense that Jetty wouldn't read the body in those cases.
I am creating a Web Service that will handle incoming request properly (I knew, it is a description) I found some sample code which present SOAP WS and looks like:
#SoapAction("some fine url")
#ResponsePayload
public CertResponse getCert(#RequestPayload Cert param)
{...}
It takes Cert object from request and manages it properly. I want to do it in the REST approach and I changed this class to look like:
#RequestMapping(value="getCert", method = RequestMethod.POST)
#ResponseBody
public CertResponse getCert(#RequestBody Cert param)
{...}
But I have no idea how or even if it is possible to write a client that can send object through HTTP Post.
Can anyone give me a hint how can i send object Cert? Or if i have to stay with #SoapAction what should I do to make it work? I guess removing #Controller is not enough.
In SOAP approach, there is a well defined way to convert each class object to SOAP formatted XML. Thus, there is no effort.
If you will use RESTful approach, you have to describe how your Cert or CertResponse objects will be written to/read from the response/request.
Basically you have three options:
Use JSON or XML or plain String. Convert your Web service descriptor so that the request and response are one of those (JSON, XML, String). Then your getCert method should convert the request to Cert object, prepare your response as CertResponse object and convert it to an appropriate response type.
Leave your getCert method as is. But you need to specify "how Cert objects are read from request" and "how CertResponse objects are written to response" You need to define classes that extend interfaces MessageBodyReader and MessageBodyWriter. In these classes a similar conversion logic should be implemented that converts your objects to/from JSON or XML or String.
In any of these two options you need to implement two things : A method that converts JSON/XML/String to Cert, a method that converts CertResponse object to JSON/XML/String.
You can do a text based implementation, which parses/constructs the request/response by text processing and uses String class only. Or you can use some library such as JSON library with JSONObject class, or Java SAX or DOM based XML libraries that come with the Java bundle.
Check out for application frameworks such as Spring. They might provide ways to automatically convert your objects to JSON or XML, reducing the programming effort necessary.
Spring allows you to pass JSON objects from the client as a request parameters, it will convert them into your objects automatically. This discussion have some examples.
SOAP services are not really compatible with REST semantics. And it's not clear what SOAP framework do you use. Typically most SOAP frameworks offer you one way or another to generate a SOAP client code for you WSDL. You can check cxf.apache.org.
For REST services use something like Jersey or Spring MVC
is their a neat way to pass a model to jsp, render the jsp and return the html as string using Spring. The html is then used in an e-mail that is fired off programmitcally, I do not want to use freemarker, but maybe I should ?
The url being requested is part of the same app.
I want one of my service layer classes to be able to call a view and use the html as a String.
You can call requestDispatcher.include(request, response) method.
You will need to implement the request and response objects. The request object will provide all information to the dispatcher which page should be rendered, the response object you will pass to the call will then capture the result to a string (using e.g. a StringBuilder).
See e.g. this tutorial for more info.
I'm guessing a servlet filter will do the trick? Not really a Spring solution, but easy enough to do.
Also this answer seems relevant, although it is DWR that you may not necessarily want to use in this instance.
You can use Velocity to create an email template:
String text = VelocityEngineUtils.mergeTemplateIntoString(
velocityEngine, "emailTemplate.vm", model);
There is a complete chapter in the Spring reference docs of how Spring can be used to send emails of various types.
How, if possible, do I get the raw XML request/response that is invoked/retrieved by Axis in my application?
I'm using WSDL2Java that is included with Axis to generate the Java stubs.
EDIT:
What I currently have is an app that uses Axis to handle the remote API calls.
One of the requirement is to 'store' all the XML request/response from these calls in the session so that it will be available in the JSP (for debugging purposes). How can I achieve this?
I tried writing a custom handler that extends BasicHandler but in that handler, I still can't get the HttpServletRequest/HttpServletResponse pair from the MessageContext
After a while searching its as simple as this:
//After your _call.invoke(...);
//Request
String request = _call.getMessageContext().getRequestMessage().getSOAPPart().getEnvelope().getBody().toString();
//Response
String response = _call.getMessageContext().getResponseMessage().getSOAPPart().getEnvelope().getBody().toString();
where _call is org.apache.axis.client.Call
Then you can save it in a file where you want...
Why don't you write a server side soap handler, get hold of MessageContext and I believe there is a way to get hold of the payload from there. If you want to pass it to downstream then put it in thread local. See e.g. of handler here
I end up using the solution described in this question
Basically, I use it to get a hold of the HttpServletRequest and from there I set the proper item in the session.