i'm trying to use a website from my java application as i'd do through my browser; it's the first time i'm trying something like this and i'm afraid i'm missing something.
I'm using apache httpcore libraries to do the http requests with the post method, with wireshark i've seen the parameters in the post request and i've added them to the request i do with java; the same for the headers.
If i sniff the request made with java i can't capture the http post request, but only the tcp traffic.
This is how i do the request:
HttpPost httpPost = new HttpPost("http://xxx.xxx");
httpPost.setHeader("Host", "xxx.xxx:xxxx");
.
.
.
HttpParams params = new BasicHttpParams();
params.setParameter("aaaa", "bbbb");
.
.
.
HttpResponse response = httpclient.execute(httpPost);
Am i missing something?
I should check something else?
Thank you very much for the help!
You have to supply a body with your post request, which you do so by calling the .setEntity(HttpEntity) method on your HttpPost.
private void sendToPostProxy(HttpServletRequest request,
HttpServletResponse response) throws IOException {
//the url to forward too
String url = "http://127.0.0.1:"+proxyPort+request.getRequestURI()
+(request.getQueryString()==null?"":"?"+request.getQueryString());
HttpPost get = new HttpPost(url);
//I am streaming requests straight through, but there are many Entity types you can use
get.setEntity(new InputStreamEntity(request.getInputStream(), request.getContentLength()));
sendToProxy(request, response, get);
}
private void sendToProxy(HttpServletRequest request,
HttpServletResponse response,HttpRequestBase get) throws IOException {
DefaultHttpClient client = new DefaultHttpClient();
Enumeration headers = request.getHeaderNames();
//copy headers
while(headers.hasMoreElements()){
String next = String.valueOf(headers.nextElement());
String header = request.getHeader(next);
if (!get.containsHeader(next)&&!"Content-Length".equalsIgnoreCase(next))
get.addHeader(next, header);
}
try{
//perform post
HttpResponse proxied = client.execute(get);
//set client headers
for (Header h : proxied.getAllHeaders()){
response.setHeader(h.getName(), h.getValue());
}
//stream to client
HttpEntity body = proxied.getEntity();
body.writeTo(response.getOutputStream());
response.setStatus(HttpServletResponse.SC_OK);
}catch(Exception e){
e.printStackTrace();
get.abort();
}
}
Related
I want to do the same functionality in the HttpPost, using servlets that is, instead of creating the request using HttpPost, I want to use another request coming from a servlet and change body before forwarding it to the URL "www.url.com/cgi-bin", how can I change the body content of a request ?
public void call() throws ClientProtocolException, IOException, InterruptedException {
String url = "www.url.com/cgi-bin"
HttpClient httpclient = new DefaultHttpClient();
httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpPost httppost = new HttpPost(url);
String data = "body data";
InputStream stream = new ByteArrayInputStream(data.getBytes("UTF-8"));
InputStreamEntity reqEntity = new InputStreamEntity(stream, -1);
reqEntity.setChunked(true);
httppost.setEntity(reqEntity);
httppost.addHeader("charset", "utf-8");
httppost.setHeader("Content-Type", "text/xml");
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
httpclient.getConnectionManager().shutdown();
}
I want it to be like...
#WebServlet("/myServlet/*")
public class MyHandler extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response) {
// add data to request here ...
// forward request to the URL ...
}
}
Unfortunately it is not possible, using servlet api's, for a servlet to generate a new post request with body content.
I need to translate this for example :
curl -X PUT -u ident:pass -H "Content-Type : application/json" --data-binary #G:\jonJob.json "http://localhost:8080/jobs/"
(this works).
in java with httpClient. I have try a lot of things but nothing work..
Someone could help me please ?
What I've tried :
public class PostFile {
#SuppressWarnings("deprecation")
public static void main(String[] args) throws Exception {
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("ident", "pass");
provider.setCredentials(AuthScope.ANY, credentials);
HttpClient httpClient = HttpClientBuilder.create().setDefaultCredentialsProvider(provider).build();
HttpPut httppost = new HttpPut("http://localhost:8080/jobs/");
File file = new File("G:/jsonJob.json");
HttpEntity httpEntity = MultipartEntityBuilder.create().addBinaryBody("file", file, ContentType.create("application/json"), file.getName()).build();
httppost.setEntity(httpEntity);
System.out.println("executing request " + httppost.getRequestLine());
HttpResponse response = httpClient.execute(httppost);
HttpEntity resEntity = response.getEntity();
System.out.println(response.getStatusLine());
if (resEntity != null) {
System.out.println(EntityUtils.toString(resEntity));
}
if (resEntity != null) {
resEntity.consumeContent();
}
httpClient.getConnectionManager().shutdown();
}
}
Result : "HTTP/1.1 415 Not supported type" (unsupported media type)
for your http req headers -H you have java runnable imple with interceptor:
public void run() {
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(YourConnectionMgr.getInstance())
.addInterceptorLast(new HttpRequestInterceptor() {
public void process(
final HttpRequest request,
final HttpContext context) throws HttpException, IOException {
if (request.getRequestLine().getMethod() == "POST"){
request.addHeader("Content-Type", "application/json") ;
see examples here to figure out 'connectionManager'
for simple auth, add this
to map in memory and POST a file see answer here
Note, you will eventually want some kind of async http client for java , you can google for that. The apache examples like in the link provided are mostly blocking network calls AFAIK
With in my java code, I need to send a http post request to a specific URL with 3 headers:
URL: http://localhost/something
Referer: http://localhost/something
Authorization: Basic (with a username and password)
Content-type: application/json
This returns a response with a JSON "key":"value" pair in it that I then need to parse somehow to store the key/value (Alan/72) in a MAP. The response is (when using SOAPUI or Postman Rest):
{
"analyzedNames": [
{
"alternate": false
}
],
"nameResults": [
{
"alternate": false,
"givenName": "John",
"nameCategory": "PERSONAL",
"originalGivenName": "",
"originalSurname": "",
"score": 72,
"scriptType": "NOSCRIPT",
}
]
}
I can do this using SOAPUI or Postman Rest but how can I do this within Java as I'm getting an error:
****DEBUG main org.apache.http.impl.conn.DefaultClientConnection - Receiving response: HTTP/1.1 500 Internal Server Error****
My code is:
public class NameSearch {
/**
* #param args
* #throws IOException
* #throws ClientProtocolException
*/
public static void main(String[] args) throws ClientProtocolException, IOException {
// TODO Auto-generated method stub
DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
StringWriter writer = new StringWriter();
//Define a postRequest request
HttpPost postRequest = new HttpPost("http://127.0.0.1:1400/dispatcher/api/rest/search");
//Set the content-type header
postRequest.addHeader("content-type", "application/json");
postRequest.addHeader("Authorization", "Basic ZW5zYWRtaW46ZW5zYWRtaW4=");
try {
//Set the request post body
StringEntity userEntity = new StringEntity(writer.getBuffer().toString());
postRequest.setEntity(userEntity);
//Send the request; return the response in HttpResponse object if any
HttpResponse response = defaultHttpClient.execute(postRequest);
//verify if any error code first
int statusCode = response.getStatusLine().getStatusCode();
}
finally
{
//Important: Close the connect
defaultHttpClient.getConnectionManager().shutdown();
}
}
}
Any help (with some sample code including which libraries to import) will be most appreciated.
THANKS
Yes, you can do it with java
You need apache HTTP client library http://hc.apache.org/ and commons-io
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://localhost/something");
post.setHeader("Referer", "http://localhost/something");
post.setHeader("Authorization", "Basic (with a username and password)");
post.setHeader("Content-type", "application/json");
// if you need any parameters
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
urlParameters.add(new BasicNameValuePair("paramName", "paramValue"));
post.setEntity(new UrlEncodedFormEntity(urlParameters));
HttpResponse response = client.execute(post);
HttpEntity entity = response.getEntity();
Header encodingHeader = entity.getContentEncoding();
// you need to know the encoding to parse correctly
Charset encoding = encodingHeader == null ? StandardCharsets.UTF_8 :
Charsets.toCharset(encodingHeader.getValue());
// use org.apache.http.util.EntityUtils to read json as string
String json = EntityUtils.toString(entity, StandardCharsets.UTF_8);
JSONObject o = new JSONObject(json);
I recommend http-request built on Apache HTTP API.
HttpRequest<String> httpRequest = HttpRequestBuilder.createPost(yourUri
new TypeReference<Map<String, List<Map<String, Object>>>>{})
.basicAuth(userName, password)
.addContentType(ContentType.APPLICATION_JSON)
.build();
public void send(){
ResponseHandler<String> responseHandler = httpRequest.executeWithBody(yourJsonData);
int statusCode = responseHandler.getStatusCode();
Map<String, List<Map<String, Object>>> response = responseHandler.get(); // Before calling the get () method, make sure the response is present: responseHandler.hasContent()
System.out.println(response.get("nameResults").get(0).get("givenName")); //John
}
I highly recommend reading the documentation before use.
Note: You can create your custom type instead of Map to parse response. See my answer here.
I have used the following code in my client:
HttpPost post = new HttpPost(url);
post.setEntity(new ByteArrayEntity(myString.getBytes("UTF8")));
HttpResponse response = this.execute(post);
I would now like to access the string on the server end. The handle method looks as follows:
public void handle(String target, Request baseRequest, HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException { ... }
The request only lets me access the content length and type but not the content itself. Any pointers?
I'm using java as a pl and the built in classes from javax.servlet.
You've set the string as the sole HTTP request body instead of as a request parameter for some reason. So, to get it, you need to read the whole HTTP request body. This is in the servlet available by
InputStream input = request.getInputStream();
// Read it into a String the usual way (using UTF-8).
Note that this would return an empty stream when it's already been read beforehand, e.g. by calling getParameter() beforehand on the very same request which would implicitly parse the POST request body for that.
The more sane approach would be to send it as a normal URL encoded request parameter as follows (exactly like as those HTML forms by default do)
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("myString", myString));
post.setEntity(new UrlEncodedFormEntity(params));
so that you can in the servlet just do
String myString = request.getParameter("myString");
// ...
I have a secure site that needs to display images coming from external non-https URLs on certain pages. I want to create a servlet that is used only as a proxy to pass the image data to the pages. One way is to use Apache's HttpClient to download the image data and then use IOUtils.copy to copy the data to the servlet's response.
Is there a simpler way?
UPDATE: The reason for this is to avoid browser warnings.
This is what I ended up using:
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
try {
String url = request.getParameter("url");
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
InputStream inputStream = httpEntity.getContent();
response.setContentType("image/jpeg");
IOUtils.copy(inputStream, response.getOutputStream());
} catch (Exception e) {
AppLogger.log(e);
}
}
If anyone has a better way to accomplish this, please post it.
If I understand well, you don't need anything like that, just return the references to the images or audio, or anything else in your HTML response and the browser will take care of make request to the server that contains each of the resources, if they're reachable, they will be displayed on the client.