I am writing a Java based Web application, which, in the actual production environment would be front-ended by another application which would set certain HTTP request headers before the request hits my application.
However, in the development environment I do not have the front-ending application, for which I need to create a mock web application that simulates the same behavior. i.e. this mock application should set the request headers and redirect or forward or whatever that I do not know :) to a certain page in my application.
How can I accomplish this?
The following articles may help you:
Adding Header Information to an existing HTTP Request
How to modify request headers in a J2EE web
application.
P.S.
I am sorry I provided only links, that was one of my early answer on SO ))
In case you don't want to modify your code as suggested by #user1979427 you can use a proxy server to modify headers or add headers on the fly.
For example in Apache HTTPD you would add something like below and proxy the
Header add HEADER "HEADERVALUE"
RequestHeader set HEADER "HEADERVALUE"
Refer to HTTPD doc
You should create a AddReqHeaderForFrowardWrapper request wrapper passing the headername and header values. And, override the request header related methods to return your custom header.
You can use Tracer to implement this.
There are frameworks available to support this implementation.
Spring has Sleuth, Zipkin, OpenTracing available.
I find OpenTracing to be easy to use without worrying about dependency conflicts.
Read more about it here: https://opentracing.io/guides/java/
Instead of writing a mock application, I used a browser add-on that allowed me to add custom headers!
For setting header in java, you can use:
request.setHeader(attributeName, attributeValue);
And for redirecting to another page, you can use:
request.sendRedirect(URL);
Related
I have recently been facing issues with http4 and http component with spring.
if i configure proxy details as part of the URL,it works, but if i set them as part of the header information, it does not work even with latest version of 2.15.1,
why these inconsistencies.
Regards
Ram
When using proxy then the http client needs to setup stuff prior to be used. The header information can only control some parts such as the context path / query parameters etc. But not proxy / SSL etc that has to be setup prior.
You can use a "dynamic to" if you want a full dynamic endpoint on the fly. See: http://camel.apache.org/how-to-use-a-dynamic-uri-in-to.html
I would like to call a servlet from another servlet doing two things:
setting the content type to "multipart/form-data"
setting the method to "POST".
This is very easy to do from a form, but I need to do it from another servlet. Any ideas how?
You can use java.net.HttpUrlConnection or maybe Apache HTTP client to send a POST/GET request to the other servlet. You will basically be invoking the other servlet the same way a browser would.
It sounds like request forwarding or include is what you're looking for. What you actually do will depend on what you intend to do with the output of the target servlet. Are you going to display it somehow? Or are you simply discarding it? You may in some cases, need to be a bit more "creative" in how you invoke those methods (e.g., either creating your own request/response instances, or wrapping the current request/response so that state changes are isolated).
Alternatively, to keep things simple you may want to just open a network connection to your target servlet's mapped URL as Jeff suggested.
It sounds like you want to send an HTTP POST with java. I would recommend using apache HttpClient. Check out this question Add parameters to Apache HttpPost
You can also do this with pure java with (HttpUrlConnection)[ http://download.oracle.com/javase/6/docs/api/java/net/HttpURLConnection.html].
I have a class that I want to hook and redirect HTTP requests in.
I also have a loader class already written, but all it does it replace the functions that contain the HTTP requests I want to change.
Is there a way to hook HTTP requests in Java so that I can redirect them all more easily?
Sort of like a proxy-wrapper.
Clarification:
The app sends out a GET or POST request to a URL.
I need the content to remain the same, just change the URL.
DNS redirects won't work, the Host HTTP header needs to be correct for the new server.
PS: This is a Desktop App, not a server script.
A cumbersome but reliable way of doing this would be to make your application use a proxy server, and then write a proxy server which makes the changes you need. The proxy server could be in-process in your application; it wouldn't need to be a separate program.
To use a proxy, set a couple of system properties - http.proxyHost and http.proxyPort. Requests made via HttpURLConnection will then use that proxy (unless they specifically override the default proxy settings). Requests made using some other method like Apache HttpClient will not, i think, be affected, but hopefully, all your requests are using HttpURLConnection.
To implement the proxy, if you're using a Sun JRE, then you should probably use the built-in HTTP server; set up a single handler mapped to the path "/", and this will pick up all requests being sent by your app, and can then determine the right URL to send them to, and make a connection to that URL (with all the right headers too). To make the connection, use URL.openConnection(Proxy.NO_PROXY) to avoid making a request to the proxy and so getting caught in an infinite loop. You'll then need to pump input and output between the two sockets.
The only other way i can think of to do this would be to override HttpURLConnection with a new handler which steers requests to your desired destination; you'd need to find a way to persuade the URL class to use your handler instead of the default one. I don't know how you'd do that in a clean way.
While an older post, this should give some ideas of some kinds of bytecode injects which can be peformed: Java Programming: Bytecode Injection. Another tool is Javassist and you may be able to find some links from the Aspected-oriented programming wiki article (look at the bytecode weavers section).
There are some products which extensively dynamically modify code.
Depending upon what is desired, there may be ... less painful ... methods. If you simply want to 'hook' HTTP requests, another option is just to use a proxy (which could be an external process) and funnel through that. Using a proxy would likely require control over the name resolution used.
you can use servlet filters which intercept the requests, the requests can further be wrapped, redirected, forwarded or completed from here.
http://www.oracle.com/technetwork/java/filters-137243.html
Do you control all of the code? If so, I suggest using Dependency Injection to inject the concrete implementation you want, which would allow you to instead inject a proxy class.
If you can change the source code, just change it and add your extra code on each HTTP request.
If you can't change the source code, but it uses dependency injection, perhaps you can inject something to catch requests.
Otherwise: use aspect-oriented programming and catch to URL class, or whatever you use to do HTTP requests. #AspectJ (http://www.eclipse.org/aspectj/doc/next/adk15notebook/ataspectj.html ) is quite easy and powerful.
I am trying to put some logging to capture the raw http request coming to my application. My Java code is inside a SpringMVC controller. I have access to the "HttpServletRequest" object. But I could not find a way to get the raw http request stream out of it. There is a reader but only reads the post content. What I want is the whole shebang, the url, the headers, the body. Is there an easy way to do this?
Thanks in advance.
No.
The servlet provides no such API, and it would be hard to implement because (basically) you cannot read the same data twice from a Socket. It is not difficult to get header information, but raw headers are impossible to capture within a servlet container. To get the bodies you need to capture them yourself as your application reads/writes the relevant streams.
Your alternatives are:
Write your own server-side implementation of the HTTP protocol. (Probably not right for your application.)
You may be able to get the header information you need with filters, though they don't show the raw requests.
Some servlet containers have request header logging; e.g. with Tomcat there's a beast called the RequestDumperValve that you can configure in your "server.xml" file.
Implement a proxy server that sits between the client and your "real" server.
Packet sniffing.
Which is best depends on what you are really trying to achieve.
FOLLOWUP:
If the "badness" is in the headers, the RequestDumperValve approach is probably the best for debugging. Go to the "$CATALINA_HOME/conf/server.xml" file, search for "RequestDumperValve" and uncomment the element. Then restart Tomcat. You can also do the equivalent in your webapp's "context.xml" file. The dumped requests and responses end up in "logs/catalina.out" by default. Note that this will give a LOT of output, so you don't want to do this in production ... except as a last resort.
If the badness is in the content of a POST or PUT request, you'll need to modify your application to save a copy the content as it reads it from the input stream. I'm not aware of any shortcuts for this.
Also, if you want to leave logging on for long periods, you'll probably need to solve the problem yourself by calling the HttpServletRequest API and logging headers, etc. The RequestDumperValve generates too much output, and dumps ALL requests not just the bad ones.
No, servlets provide no api to get at the raw request - you might need a sniffer like wireshark for that.
You can get at the parsed request headers and uri though:
getHeaderNames()
getRequestURI()
etc.
I managed to read my raw request in my webapplication deployed on Tomcat 5.5
All I had to do is to read HttpServletRequest through my servlet/Spring controller
using request.getInputStream() only.
It must be the first API approach to the request. before any filter or other command start to mass with the request that cause its completely reading by the webserver.
What's the problem with that approach?
Im trying to improve the Java Html Document a little but i'm running into problems with the HttpUrlConntion. One thing is that some servers block a request if the user agent is a Java VM. Another problem is that the HttpUrlConnection does not set the Referrer or Location header field. Since several sites use these fields to verify that the content was accessed from their own site, I'm blocked here as well. As far as I can see the only resolution is to replace the URL handler of the HTTP protocol. Or is there any way to modify the default HTTP Handler?
Open the URL with URL.openConnection. Optionally cast to HttpURLConnection. Call URLConnection.setRequestProperty/addRequestProperty.
The default User-Agent header value is set from the "http.agent" system property. The PlugIn and WebStart allow you to set this property.
If you use Apache HttpClient to manage your programmatic HTTP connectivity you get an extremely useful API which makes creating connections (and optional automatic re-connecting on fail), setting Headers, posts vs gets, handy methods for retrieving the returned content and much much more.
I solved my problem. We can just send the header to application/json and pass the body as a json object. That simply solves the issue.