I'm trying to connect to my server by HTTP and obtain a JSON object, but it seems that I can't do it.
Here's my code:
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class Conector {
public static void main(String[] args) throws Exception {
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
HttpGet httpGet = new HttpGet("https://falseweb/select_all.php");
CloseableHttpResponse response1 = httpclient.execute(httpGet);
try {
System.out.println(response1.getStatusLine());
HttpEntity entity1 = response1.getEntity();
System.out.println(entity1.getContentEncoding());
EntityUtils.consume(entity1);
} finally {
response1.close();
}
} finally {
httpclient.close();
}
}
}
But instead of the JSON I get a printed null. I already tried the php file and it works, returning a json. Any idea what I'm doing wrong?.
The connection works because i got this message :
HTTP/1.1 200 OK
You seem to be logging out the content encoding as opposed to the actual content of the response which is probably why you aren't having any JSON joy.
Give the following a go (using Apache Commons IOUtils) :
System.out.println(IOUtils.toString(entity1.getContent(), "UTF8"));
If you can't use IOUtils then you can use any method of converting the InputStream into a String. More on that here.
Related
When making a post request to my backend, I get the following error. I can't really find a fix online and am very new to Java.
Here is the error:
Caused by: java.lang.ClassNotFoundException: org.apache.http.concurrent.Cancellable
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
... 59 more
Code
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.http.HttpHeaders;
import java.util.ArrayList;
import java.util.List;
public class APIBridge {
private final CloseableHttpClient httpClient = HttpClients.createDefault();
public String url = "http://localhost:9004/index.php";
public static void Register(String username, String password) throws UnsupportedEncodingException {
String url = "http://localhost:9004/index.php";
HttpPost post = new HttpPost(url);
// Add request parameter, form parameters
List<NameValuePair> urlParameters = new ArrayList<>();
urlParameters.add(new BasicNameValuePair("username", username));
urlParameters.add(new BasicNameValuePair("password", password));
urlParameters.add(new BasicNameValuePair("Register", "true"));
post.setEntity(new UrlEncodedFormEntity(urlParameters));
try (CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = httpClient.execute(post)) {
System.out.println(EntityUtils.toString(response.getEntity()));
} catch (ClientProtocolException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void close() throws IOException {
httpClient.close();
}
private void sendGet() throws Exception {
HttpGet request = new HttpGet("https://www.google.com/search?q=mkyong");
// Add request headers
request.addHeader("custom-key", "mkyong");
//request.addHeader(, "Googlebot");
try (CloseableHttpResponse response = httpClient.execute(request)) {
// Get HttpResponse Status
System.out.println(response.getStatusLine().toString());
HttpEntity entity = response.getEntity();
Header headers = entity.getContentType();
System.out.println(headers);
if (entity != null) {
// Return it as a String
String result = EntityUtils.toString(entity);
System.out.println(result);
}
}
}
IMO, it is easier to use the HTTP client in the JDK, so I have provided an answer demonstrating this alternate approach.
The Apache HTTP libraries were never targeted at somebody who is "new to Java". If you use them, make sure you use the correct versions of all the libraries and matching documentation as the library has gone through multiple incompatible API changes over years of library upgrades.
From your question, your module-info.java may be wrong or may need to be deleted. But your issue could also be caused by an environment setup or dependency version issue.
Basically, the class isn’t on the class or module path. Or it is on a path, but it is not accessible. The reason for that is not discernable from your question.
Example JavaFXApp using JDK HTTP Client
Makes a post request, gets the result as text and places the text in a TextArea.
module-info.java
module com.example.httpapp {
requires javafx.controls;
requires java.net.http;
exports com.example.httpapp;
}
src/main/java/com/example/httpapp/HttpApp.java
package com.example.httpapp;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class HttpApp extends Application {
#Override
public void start(Stage stage) throws IOException, URISyntaxException, InterruptedException {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("http://jsonplaceholder.typicode.com/posts"))
.POST(HttpRequest.BodyPublishers.ofString("Sample Post Request"))
.build();
HttpResponse<String> response = client.send(
request,
HttpResponse.BodyHandlers.ofString()
);
String responseBody = response.body();
TextArea textArea = new TextArea(responseBody);
textArea.setStyle("-fx-font-family: monospace;");
stage.setScene(new Scene(textArea));
stage.show();
}
public static void main(String[] args) {
launch();
}
}
Authentication
Outside of a local test app, you should not send unencrypted authentication data over a network connection as you have in your question code.
If you also need authentication, it is best to communicate over HTTPS. Then you can securely use basic or digest authentication, or HTTPS mutual authentication, or encode the authentication information in the post body.
Examples for basic authentication using the Java HTTP client are at:
Baeldung: Java HttpClient Basic Authentication
I'm trying to post a file to a rest API and the code I'm using gives an "Early EOF" error. I've looked around and most of what I'm seeing seems to suggest that the data send doesn't match the expected size of what is being sent.
How do I fix this?
Code is shown below:
(based on How can I make a multipart/form-data POST request using Java?)
import java.io.File;
import java.io.FileInputStream;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import lombok.extern.slf4j.Slf4j;
#Slf4j
public class HttpFileUpload {
public static void main(String[] args) throws Exception {
log.info("Starting...");
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost uploadFile = new HttpPost("https://url-to-rest-api/api/2.0/dbfs/put");
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody("path", "/FileStore/my-dir/myfilename.txt", ContentType.TEXT_PLAIN);
String token = "my-security-token";
// This attaches the file to the POST:
File f = new File("C:\\path-to\\my-file.txt");
builder.addBinaryBody(
"file",
new FileInputStream(f),
ContentType.APPLICATION_OCTET_STREAM,
f.getName());
HttpEntity multipart = builder.build();
uploadFile.addHeader("Authorization", "Bearer " + token);
uploadFile.setEntity(multipart);
log.info("Starting upload");
CloseableHttpResponse response = httpClient.execute(uploadFile);
log.info("Done with upload");
HttpEntity responseEntity = response.getEntity();
log.info("Got response");
log.info("Done.");
}
}
This turned out to be a timeout issue. The api I was writing to timed out the request and generated the EOF exception. The api had another call that allowed the file to be uploaded in segments so I modified my solution to use this call instead of trying to upload the entire file in one call.
I am trying to use some code that I got from a website that has sports data served publically via an API (http://developer.fantasydata.com).
The site provide some sample JAVA code to make the http request. For some reason the setEntity method for the declared request (request) is showing a "cannot find symbol error.
package epl.fixtures.test.app;
import java.net.URI;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class EPLFixturesTestApp {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
HttpClient httpclient = HttpClients.createDefault();
try
{
URIBuilder builder = new URIBuilder("https://api.fantasydata.net/soccer/v2/json/CompetitionDetails/EPL");
URI uri = builder.build();
HttpGet request = new HttpGet(uri);
request.setHeader("Ocp-Apim-Subscription-Key", "****************");
// Request body
StringEntity reqEntity = new StringEntity("{body}");
request.setEntity(reqEntity);
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null)
{
System.out.println(EntityUtils.toString(entity));
}
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
}
The line causing the issue is the request.setEntity(reqEntity); line
Can anyone explain this to me please? I have all the relevant jar files from apache added to the project libraries directory.
Thanks
HttpGet does not have a setEntity method.
This makes sense, since the request body has no meaning in GET requests.
Only classes implementing HttpEntityEnclosingRequest have this method.
I don't know why the documentation uses it, but it seems to work when omitting those two lines (which look meaningless anyway). Code:
URIBuilder builder = new URIBuilder("https://api.fantasydata.net/soccer/v2/json/CompetitionDetails/EPL");
URI uri = builder.build();
HttpGet request = new HttpGet(uri);
request.setHeader("Ocp-Apim-Subscription-Key", "****************");
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null)
{
System.out.println(EntityUtils.toString(entity));
}
I am passing a JOSN object from Java to PHP. I am using jdk 1.8 ang WAMP server.
Below is the Java code.
import java.io.IOException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.json.simple.JSONObject;
/**
*
* #author PReeeT Dash
*/
public class FromJava
{
public static void main(String[] args) throws IOException
{
JSONObject json = new JSONObject();
json.put("someKey", "someValue");
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
try
{
HttpPost request = new HttpPost("http://localhost/PGP/JSONReq/tophp.php");
StringEntity params = new StringEntity(json.toString());
request.addHeader("content-type", "application/json");
request.setEntity(params);
httpClient.execute(request);
// handle response here...
} catch (Exception ex)
{
System.out.println("Error: Cannot Estabilish Connection");
}
finally
{
httpClient.close();
}
}
}
PHP script:
$data = json_decode(file_get_contents("php://input"));
echo($data);
When I run the PHP file it always shows an Empty page. Can anyone please help me understand why is it not working.
When I run the following PHP code it always executes the else condition.
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$data = json_decode(file_get_contents("php://input"));
echo($data);
}
else
{
echo "XXXXXX";
}
I do not think this will work.
A PHP script is not "listening" as would a WebService. However, upon receiving the request, the script processes it and try to "print" the result in HTML, not Java.
Fetch the response body your org.apache.http.client instance receives and e.g. send it to System.out
CloseableHttpResponse response = httpClient.execute(request);
IOUtils.copy(response.getEntity().getContent(), System.out);
For IOUtils use import org.apache.commons.io.IOUtils;
In case you're using maven the dependency is
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
You will most likely get the output
Catchable fatal error<: Object of class stdClass could not be converted to string
because echo($data) doesn't work. json_decode(...) returns a stdClass.
Try
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
// json_decode(..., true) will return an array instead of a stdClass
$data = json_decode(file_get_contents("php://input"), true);
var_export($data);
}
else
{
var_export($_SERVER['REQUEST_METHOD']);
}
instead.
There is a json file on my websites floder.
Here is the content:
{
"IsUpdateForcibly": "false",
"Version": "1.0",
"ReleaseNote": "OHOHOHOHOHO",
"DownloadLink": "http://192.168.1.37:11604/APK/FrauleinProject.apk"
}
If I use the browser to see,like http://localhost:11604/Content/CheckVersion.json, the result is same as thefile's content.
While I use the Java code. the response content is a little bit different.
?{
"IsUpdateForcibly": "false",
"Version": "1.0",
"ReleaseNote": "OHOHOHOHOHO",
"DownloadLink": "http://192.168.1.37:11604/APK/FrauleinProject.apk"
}
Why there is a question mark in the front of the string?
Here is is my httpclient code.
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import sun.misc.IOUtils;
import sun.net.www.http.HttpClient;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.WinHttpClients;
import org.apache.http.util.EntityUtils;
public class DesUtil {
public static void main(String[] args) throws Exception {
CloseableHttpClient httpclient = WinHttpClients.createDefault();
// There is no need to provide user credentials
// HttpClient will attempt to access current user security context through
// Windows platform specific methods via JNI.
try {
HttpGet httpget = new HttpGet("http://localhost:11604/Content/CheckVersion.json");
System.out.println("Executing request " + httpget.getRequestLine());
CloseableHttpResponse response = httpclient.execute(httpget);
try {
System.out.println("----------------------------------------");
ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
#Override
public String handleResponse(
final HttpResponse response) throws ClientProtocolException, IOException {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 && status < 300) {
HttpEntity entity = response.getEntity();
return entity != null ? EntityUtils.toString(entity) : null;
} else {
throw new ClientProtocolException("Unexpected response status: " + status);
}
}
};
String json= new String(httpclient.execute(httpget, responseHandler).getBytes("ISO-8859-1"),"UTF-8");
PrintWriter out = new PrintWriter("filename.txt");
out.println(json);
out.close();
System.out.println(json);
JSONObject obj = JSONObject.fromObject(json);
System.out.println(obj==null);
Sb newSB= (Sb)JSONObject.toBean(obj,Sb.class);
System.out.println(newSB==null);
System.out.println(newSB.IsUpdateForcibly);
System.out.println(newSB.Version);
System.out.println(newSB.ReleaseNote);
System.out.println(newSB.DownloadLink);
}
catch(Exception ex){
System.out.println(ex.getMessage());
}
finally {
response.close();
}
}
catch(Exception ex){
System.out.println(ex.getMessage());
}
finally {
httpclient.close();
}
System.out.println("end");
}
}
I had a similar problem. I solved it by adding "UTF-8"
String str= EntityUtils.toString(entity2);
to
String str= EntityUtils.toString(entity2,"UTF-8");
demo:
private static void sendPost() throws ClientProtocolException, IOException
{
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("http://127.0.0.1:8911/crr");
ArrayList<NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("crawlId", "123"));
nvps.add(new BasicNameValuePair("transType", "0"));
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
CloseableHttpResponse response2 = httpClient.execute(httpPost);
try {
System.out.println(response2.getStatusLine());
HttpEntity entity2 = response2.getEntity();
String str= EntityUtils.toString(entity2,"UTF-8");
System.out.println(str);
} finally {
response2.close();
}
}
This probably stems from a Unicode BOM character, a zero-width space in Unicode that is used in UTF-8, UTF-16LE, UTF-16BE at the beginning of a file to mark it as Unicode: \uFEFF. It is redundant, unneeded, and - as seen here - causes several problems.
It was replaced with a question mark, as the character encoding of the saved text could not represent the BOM character.
As #zhizhi mentioned, better safe the JSON as UTF-8. Still better is to remove the BOM.
PrintWriter out = new PrintWriter("filename.txt", "UTF-8");
json = json.replaceFirst("^\uFEFF", "");
Mind that removing the BOM poses a UTF-8 recognition problem for Notepad.