Directly invoke a servlet without a URL? - java

I had two java web apps with servlets that communicated with each other using absolute URLs. I did this because they wouldn't always be running on the same server and even when they were it still worked fine.
However, I've now changed the code so there is only a single web app and the first app (A) now uses the second app (B) more as a library. So, I'd like to be able to make calls on the second app directly without having to know the full URL.
Ideally, the servlets in B would be pure controllers, but unfortunately they are not and the logic is wrapped up in the request and the response and not easily decoupled.
The only option I've seen is to use a RequestDispatcher. However, when getting a dispatcher using the context:
context.getRequestDispatcher("/servlet/mapping");
To make the call I'd then need to synthesize a request and response object and I don't know how to do this. I've looked into wrappers but they need to start from something yet I don't have a starting point. I could create my own wrapper to handle the query parameters, but again, I don't have a request to start from.
Or is there a simpler solution that I'm missing? Thanks!

Just turn all your request.getParameter() type calls into regular passing of variables to a function. Assuming your servlet writes out text and not binary, turn all your out.prints into concatenations to a string you return at the end of the servlet. Or pass in an outputstream rather than response object, and instead of calling the servlet response.getouputstream use the outputstream passed in. Then you can make your servlet just a regular class that takes some parameters and returns a string or prints to an outputstream that you passed in.

Related

How to create a session cookie in java with path while still having good programming practice of functional programming

I really like functional programming, I like its immutability concepts and also it's no side-effects concepts for functions.
I'm trying to take some of these concepts into java.
Now I have some kind of a servlet which receives a request and if browser did not send a cookie to server then i would like to create a cookie with a certain path to the user.
now inside the servlet i don't want to hold that logic because its common to multiple servlets.
so i extract it into some kind of a cookie manager which will do that:
CookieManager.java.handleCookies(request, response)
Check if browser sent cookie.
If not set cookie with new session cookie value with certain path.
however i don't like it because now the servlet will call the CookieManager.java.handleCookie will have a side effect I would rather it to return some kind of a response and further use it in my servlet wihtout having it effect its parameters that i'm passing into it.
anyone can suggest a solution which would both be elegant, no side effects, and excellent in performance?
thanks
You can make use of servlet filter. It would be well suited for your case. You can map your filter to URL pattern and write your code inside dofilter method. Filters are recommended if you want to have pre and post prcoess of request/response. Since you are doing preprocess for you request it would fit in your case. If is also loosely coupled, because you can remove it, modify it, or add another rule anytime without modifying the core servlet code.
One good solution is to use create a servlet which will act as a parent class for all other servlets.
Now in this servlet put this logic of cookie handling in a common function say handlecookie.
In your get and post APIs of this servlet first call this handleCookie and then service API of servlet (keep this empty)
In al child servlet classes you can only override the service class inherited from the parent class and things should work fine for you
Servlet filters are other solution that you can make use of.

How am I supposed to use Apache XML-RPC's TypeConvertorFactory on the server side?

I am struggling to get Apache XML-RPC to call my TypeConvertorFactory at all. It is calling it on the client side (only return values confirmed to work so far, haven't tested parameters) but the server side isn't calling it at all.
My initialisation code looks like this:
XmlRpcServlet servlet = new XmlRpcServlet();
XmlRpcServerConfigImpl config = new XmlRpcServerConfigImpl();
config.setEnabledForExtensions(true);
servlet.getXmlRpcServletServer().setConfig(config);
servlet.getXmlRpcServletServer().setTypeConverterFactory(
new ServerTypeConvertorFactory());
The API looks like this:
private interface API {
AvailableLicencesResponse availableLicences();
}
AvailableLicencesResponse is just an ordinary boring, albeit deeply nested JavaBean.
At the moment, the server sends this response as Base64 (this works because I called setEnabledForExtensions(true) - but if I don't call that, I get "unexpected end of stream" type errors instead, with no additional error anywhere to tell me why.)
I have set breakpoints inside ServerTypeConvertorFactory and it seems that none of the methods are being called on the server. The same breakpoints show the client calling convert() when the server hands back the result, but the result is already the correct type due to serialisation magic so I don't need to convert it.
Essentially, what I am trying to do is to implement a wire protocol which conforms to standard XML-RPC (and doesn't use huge amounts of Base64 data...) while still having an API which doesn't require a thousand casts and calls to Map.get(). I also want to avoid having to make more calls than necessary, which is why I'm returning a bean instead of having separate methods to get each property of it, which would have worked too.
(Also, if there is a simpler to use API than this one, I'm open for suggestions. It started out being really easy, but that's until you need to customise it. Also, anyone suggesting Axis or other SOAP-based APIs will be shot at dawn.)

Is Passing a Parameter to a method the same as creating an object?

I am learning Servlets and JSP. I am wondering about the "doGet" and other methods that may be overidden. The "doGet" takes 2 params - HTTPServletRequest request, and HTTPServletResponse response. This is my question: The request and response objects are used within the method body but I do not see any object creation e.g. request = new HTTPServletRequest. Are these objects created elsewhere e.g. in the superclass? This is just a Java question really as I often wonder about this with Applets also, i.e. the Graphics g object is passed to the "paint" method but I don't see it's creation anywhere?
GF
In the two examples you gave, servlets and applets, the code is running inside of a container. Tomcat is the container for servlets and that means that the container provides certain functionality. In this case the container will create the request and response objects and pass it to your servlet for you.
If you write a plain Java program that runs by itself, then you are responsible for creating all objects.
Generally, in any programming language, when a method is called with instances of an object (or any parameter for that matter), yes, those objects are created somewhere.
For the most part, you don't have to worry about the where, just that they are when dealing with them inside of your functions.
Getting back to your question though, while there might be certain situations that an object was created through non-traditional means (depending on the technology stack), you can be assured that more often than not, if you have a reference to an object passed to you in a method you wrote, then it was created using traditonal means somewhere in the call stack (or another, if you have multiple threads).
In the case of Java, this would mean that someone called new ... at some point, and made it available to the call site of your method in order to pass it in as a parameter.
It's created by the web server (tomcat, for example), and it calling your servlet with this parameters
The objects are created at the call-site. I.e. whoever calls the method is responsible for creating the objects that he/she passed to the method as parameters (unless he passes already existing objects, of course, but those have previously been created somewhere as well).
all methods in servlets are invoked by servlet container such as tomcat

Remote Servlet Comms

I have two servlets A & B.
On B i intend to have a a method isAvailable() which A will call to check the status. If this method returns true then im going to pass it an object to B.
On doing a bit of reading i'm seeing a couple of options non of which im that familar with. JNDI with remote EJB , RMI or simple HTTP (not sure how youd do the last)
What do you guys think ? Any other options ?
Why not make use of the fact that your infrastructure is already talking HTTP ?
So servlet A can perform an HTTP GET on a particular path to check a status (either sending back an object or checking an HTTP response code - this latter method seems a misuse of status codes, however), and PUT/POST an object if required. I note that you're running across multiple hosts, and this will work in your scenario.
The objects can be serialised using standard Java, or via a representation such as XML - perhaps serialised using XStream).
That would seem to me a pretty straightforward way to leverage off the infrastructure you have.
Are your servlets running in the same application server? If so, you might like to use Spring to inject B into A so that the method can be called directly.
Even if the servlets are running in different containers, you can expose them (using Spring again) as Remote objects and similarly inject B into A (except that this will mean that the Spring container will inject a proxy for the remote object). This has zero footprint in your code (i.e. it's all defined by config files and Spring takes care of everything for you)
It looks like this isAvailable() method in Servlet B accesses some kind of "global" data which is stored in the Servlet. Could you extract this object to a separate Singleton which then is available for both Servlets?
There is one instance of Servlet A on a master host and many of Servlet B each on its own host with its own tomcat instances.
You can use java.net.URLConnection to programmatically fire a HTTP request. You can find here a simple tutorial.
Let A fire a HTTP request to B and have in B a servlet which listens on those requests and returns the response accordingly. This can be a simple response.getWriter().write("ok"); or so. You can even return a XML string and so on. In A you can then read this value from the InputStream of the URLConnection.

How do I separate out query string params from POST data in a java servlet

When you get a doGet or doPost call in a servlet you can use getparameterxxx() to get either the query string or the post data in one easy place.
If the call was a GET, you get data from the url/query string.
If the call was a POST, you get the post data all parsed out for you.
Except as it turns out, if you don't put an 'action' attribute in your form call.
If you specify a fully qualified or partially qualified url for the action param everything works great, if you don't, the browser will call the same url as it did on the previous page submit, and if there happens to be query string data there, you'll get that as well as POST data, and there's no way to tell them apart.
Or is there?
I'm looking through the request object, I see where the post data comes from, I'm just trying to figure out where the GET data comes from, so I can erase the GET data on a post call and erase the post data on a GET call before it parses it out if possible.
Any idea what the safe way to do this is?
And lemme guess: you never tried to not put an action field in a form tag. :-)
You're right, I never tried not to put an action field in a form tag ;-) and I wouldn't, because of exactly what you're talking about. (Also, I think it's not valid HTML)
I don't know of any "clean" way to distinguish between GET and POST parameters, but you can access the raw query string using the getQueryString() method of HttpServletRequest, and you can access the raw POST data using the getInputStream() method of ServletRequest. (I'm looking at the Tomcat API docs specifically here, although I think those are both part of the standard Servlet API) Then you could parse the POST data and GET data separately if you want. They will (or should normally) both be formatted the same way, i.e.
name1=value1&name2=value2&...
though possibly with the ampersands replaced by semicolons (which you can technically do in HTTP/1.1, I didn't know that until recently)
In HTML, action is REQUIRED, so I guess the behavior will vary among clients.
The HttpServletRequest.getParameterxxx() methods don't distinguish between GET and POST parameters. If you really need to distinguish between them, you'll need to parse them manually using getQueryString() for the GET parameters and getInputStream()/getReader() for the POST data.
I would write a ServletFilter and decorate the request object to clean things up a bit (using what Hilton suggested above). This is the classic decorator pattern in an intercepting filter.

Categories

Resources