I am trying to build a multipart HttpRequest using Java 11 as below. I am also trying to pass username
and password and later i might need a file also in the same request. However i keep getting 415 or 400 bad request errors.
The code is below.
import java.io.IOException;
import java.math.BigInteger;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
public class Client{
private HttpClient httpClient;
private HttpResponse httpResponse;
private String Response;
private Map<Object, Object> urlParameters;
public Client(String URL) {
httpClient=BuildClient(URL);
urlParameters= new HashMap<>();
urlParameters.put("username","xxxx");
urlParameters.put("password","xxxx");
try {
PostRequest(httpClient,URL,urlParameters);
} catch (IOException e) {
System.out.println("Client Error");
e.printStackTrace();
}
}
public HttpClient BuildClient(String URL) {
return HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(10))
.build();
}
//This is the code for request build
public HttpResponse PostRequest(HttpClient httpClient, String url, Map<Object, Object> params) throws IOException {
String boundary = new BigInteger(256, new Random()).toString();
HttpRequest request = HttpRequest.newBuilder()
//.POST(HttpRequest.BodyPublishers.fromPublisher(subscriber -> ))
.POST(HttpRequest.BodyPublishers.noBody())
.POST(HttpRequest.BodyPublishers.ofString("{\"username\":\"XXXXX\"}{\"password\":\"XXXX\"}"))
//.POST(HttpRequest.BodyPublishers.ofFile(Path.of("")))
.uri(URI.create("http://example.com/request/add"))
.setHeader("User-Agent", "firefox")
.setHeader("Content-Type", "multipart/form-data")
.build();
HttpResponse<String> response = null;
try {
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(request.headers());
// print status code
System.out.println(response.statusCode());
// print response body
System.out.println(response.body());
return response;
}
public HttpRequest.BodyPublisher FormatData(Map<Object, Object> data) {
var builder = new StringBuilder();
for (Map.Entry<Object, Object> entry : data.entrySet()) {
if(builder.length()>0)
{
builder.append("&");
}
builder.append(URLEncoder.encode(entry.getKey().toString(), StandardCharsets.UTF_8));
builder.append("=");
builder.append(URLEncoder.encode(entry.getValue().toString(), StandardCharsets.UTF_8));
}
return HttpRequest.BodyPublishers.ofString(builder.toString());
//return null;
}
}
I was wandering if can be done without add some library as maven dependency such as apache HTTP client.
Related
I have an encoding issue downloading a Chinese RSS url http://finance.qq.com/stock/ggjj/rss_ggjj.xml
import java.io.IOException;
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 Test {
public static void main(String[] args) {
CloseableHttpResponse response = null;
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
String url = "http://finance.qq.com/stock/ggjj/rss_ggjj.xml";
response = httpclient.execute(new HttpGet(url));
System.out.println(EntityUtils.toString(response.getEntity(), "UTF-8"));
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The output contains bad encoded characters:
... �ㄨ����搴�锛�涓��ㄤ�娉煎��������姘� ...
I have the request below, if occurs an error at the service I'd like to save in a database the request serialized to send again in other moment.
URI uri = fromUri(config.getUri()).path("/myservice").build();
Client client = ClientProducer.get();
response = client
.target(uri)
.request()
.headers(obterCabecalhos())
.accept(MediaType.APPLICATION_JSON)
.post(Entity.json(myEntity));
if (response.getStatus() != OK.getStatusCode()) {
throw new TSEIntegracaoException();
// Here I'd like to serialize the request and save in a database
}
I do not think that is possible. How about creating a class that encapsulate your request data (uri, headers, payload) and serializing the instance of that class instead.
An example:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.URI;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.xml.bind.DatatypeConverter;
public class DemoClient {
public static void main(String[] args) throws Exception {
Client client = ClientBuilder.newClient();
URI uri = URI.create("http://localhost:8000");
Map<String, List<Object>> headers = new HashMap<>();
headers.put(HttpHeaders.ACCEPT, Arrays.asList((Object) MediaType.APPLICATION_JSON));
PostRequestData requestData = new PostRequestData(uri, headers, new String("hello world"));
Response response = requestData.post(client);
if (response.getStatus() != Status.ACCEPTED.getStatusCode()) {
// let's serialise it into binary
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteStream);
objectOutputStream.writeObject(requestData);
// save bytestream or print it?
String bin = DatatypeConverter.printHexBinary(byteStream.toByteArray());
System.out.println(bin);
// let's replay the request
byte[] newBytes = DatatypeConverter.parseHexBinary(bin);
ObjectInputStream oin = new ObjectInputStream(new ByteArrayInputStream(newBytes));
PostRequestData newRequestdata = (PostRequestData) oin.readObject();
Response newResponse = newRequestdata.post(client);
if (newResponse.getStatus() != Status.ACCEPTED.getStatusCode()) {
System.out.println("give up!");
}
}
}
static class PostRequestData implements Serializable {
private static final long serialVersionUID = -5786067257552259115L;
final URI uri;
final Map<String, List<Object>> headers;
final Serializable entity;
public PostRequestData(URI uri, Map<String, List<Object>> headers, Serializable entity) {
this.uri = uri;
this.headers = headers;
this.entity = entity;
}
public Response post(Client client) {
MultivaluedHashMap<String, Object> multimap = new MultivaluedHashMap<String, Object>();
headers.forEach((k,v) -> multimap.put(k, v));
return client.target(uri)
.request()
.headers(multimap)
.post(Entity.text(entity));
}
}
}
I want to execute the below command through Java code. This is to create connection to my Appdynamics Contoller
curl --user user#customer1:password 'http://192.168.1.11:9090/controller/rest/applications?output=JSON'
The java code that I have written for this is
import java.io.IOException;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class Test {
private static HttpClient client;
public static void main(String[] args) {
CloseableHttpResponse response = null;
CloseableHttpClient httpclient = null;
try {
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope("192.168.1.11", 9090), new UsernamePasswordCredentials(
"user", "password"));
httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
HttpPost httpget = new HttpPost("http://192.168.1.11:9090/controller/rest/applications?output=JSON");
System.out.println("Executing request " + httpget.getRequestLine());
response = httpclient.execute(httpget);
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
System.out.println(EntityUtils.toString(response.getEntity()));
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
httpclient.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
I keep on getting below error
HTTP/1.1 401 Unauthorized
Error report HTTP Status 401 - type Status reportmessagedescriptionThis request requires HTTP authentication ().
Can anyone please help.
I am trying to write a JSON over an HTTP over a public URL(For security reason as of now I cant share the link for testing, hence assume that writing code for localhost:127.0.0.1:8083/msg)
I want to achieve this, detailed statement is described here: http://pastebin.com/42XYr23a
To achieve this I have written rough draft using Simple Json program, Kindly suggest to parse the URL and fulfill required goals.
java.io.IOException;
import org.apache.http.HttpResponse;
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.apache.http.util.EntityUtils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
public class JsonSimple {
public static void main(String[] args) {
}
public HttpResponse http(String url, String body) {
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
HttpPost request = new HttpPost(url);
StringEntity params = new StringEntity(body);
request.addHeader("content-type", "application/json");
request.setEntity(params);
HttpResponse result = httpClient.execute(request);
String json = EntityUtils.toString(result.getEntity(), "UTF-8");
try {
JSONParser parser = new JSONParser();
Object resultObject = parser.parse(json);
if (resultObject instanceof JSONArray) {
JSONArray array=(JSONArray)resultObject;
for (Object object : array) {
JSONObject obj =(JSONObject)object;
System.out.println(obj.get("example"));
System.out.println(obj.get("fr"));
}
}else if (resultObject instanceof JSONObject) {
JSONObject obj =(JSONObject)resultObject;
System.out.println(obj.get("example"));
System.out.println(obj.get("fr"));
}
} catch (Exception e) {
// TODO: handle exception
}
} catch (IOException ex) {
}
return null;
}}
Kindly suggest solutions
What will be the url for creating an entity say myEntity through a rest url? myEntity has two parameter name and description. Here is how rest controller looks like:
#POST
#Path("/create")
#Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
#Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response createJobType(MyEntity myEntity) {}
If it looks ok then how would myEntity parameters will passed through request url?
It's test class:
#Test
public void testShouldCreateMyEntity() {
MyEntity entity = new MyEntity();
entity.setName("Sample Name");
entity.setDescription("Sample Description);
String url = buildRequestURL("/create/"+entity).toUrl(); // Confused :(
}
Not sure if I should pass entity with URL. If not then how the entity would be passed?
There are many ways of testing your endpoint, and these tests might vary according to your needs.
For example, if authentication is required, or if HTTPS is required.
But supposing you don't need authentication and HTTPS is not used, you can test your endpoint with this code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.CloseableHttpResponse;
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.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import com.google.gson.Gson;
public class RestClientTest {
/**
* #param args
*/
public static void main(String[] args) {
CloseableHttpClient httpClient = null;
HttpPost httpPost = null;
CloseableHttpResponse response = null;
try {
httpClient = HttpClients.createDefault();
httpPost = new HttpPost("http://localaddressportetc.../create"); // <-- I suggest you change this to "entity" since this is what is being created by the POST
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("content-type", "application/json"));
MyEntity entity = new MyEntity();
entity.setName("Sample Name");
entity.setDescription("Sample Description");
Gson gson = new Gson();
String entityJSON = gson.toJson(entity);
StringEntity input = new StringEntity(entityJSON);
input.setContentType("application/json");
httpPost.setEntity(input);
for (NameValuePair h : nvps)
{
httpPost.addHeader(h.getName(), h.getValue());
}
response = httpClient.execute(httpPost);
if (response.getStatusLine().getStatusCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatusLine().getStatusCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(response.getEntity().getContent())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try{
response.close();
httpClient.close();
}catch(Exception ex) {
ex.printStackTrace();
}
}
}
}