This has now come to a point where I cannot take it anymore! i have seen a lot of people have had the same problem as this one but their solution do not work for me.
I am trying to call a REST service from my Android application. I am still new to Android BTW.
The calling code looks like this:
String httpResult = "";
HttpClient httpClient = new DefaulthttpClient();
HttpContext httpContext = new BasicHttpContext();
String url = myURL;
HttpGet httpGet = new HttpGet(myURL);
HttpResponse response = httpClient.execute(httpGet, httpContext);
//receive response in input stream
InputStream is = response.getEntity().getContent();
//convert the stream into a string
if(is != null){
//call method that will convert stream to string
httpResult = cString(is);
}else{
httpResult = "Error";
}
When I debug the code, I see that throws an exception when the compiler hits the "HttpClient httpClient = new DefaultHttpClient()" line of code and shows "No Source Found" screen.
"No Source Found"occurred when you debug a class without the source file.
You should just use F6 to step over when debugging.
Related
I am trying to implement the MOT history API https://dvsa.github.io/mot-history-api-documentation/ and they give an example using CURL which works with the supplied api key successfully when using an online CURL tool.
I am trying to implement this in Android and realise I have to use something like HttpPost rather than CURL, this is my code:
//Tried with full URL and by adding the registration as a header.
//HttpPost httpPost = new HttpPost("https://beta.check-mot.service.gov.uk/trade/vehicles/mot-tests?registration=" + reg_selected);
HttpPost httpPost = new HttpPost("https://beta.check-mot.service.gov.uk/trade/vehicles/mot-tests");
httpPost.addHeader("Content-Type", "application/json");
httpPost.addHeader("Accept", "application/json+v6");
httpPost.addHeader("x-api-key", "abcdefgh123456");
httpPost.addHeader("registration", reg_selected);
StringEntity entity = new StringEntity(jsonObj.toString(), HTTP.UTF_8);
httpPost.setEntity(entity);
HttpClient client = new DefaultHttpClient();
try {
HttpResponse response = client.execute(httpPost);
if (response.getStatusLine().getStatusCode() == 200) {
InputStream inputStream = response.getEntity().getContent();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String readLine = bufferedReader.readLine();
String jsonStr = readLine;
JSONObject myJsonObj = new JSONObject(jsonStr);
}else if (response.getStatusLine().getStatusCode() == 400){
//Bad Request Invalid data in the request. Check your URL and parameters
error_text = "Bad Request";
}else if (response.getStatusLine().getStatusCode() == 403){
//Unauthorised – The x-api-key is missing or invalid in the header
error_text = "Authentication error"; //<<<< FAILS HERE 403
}
response.getStatusLine().getStatusCode() returns • "403 – Unauthorised – The x-api-key is missing or invalid in the header".
However the x-api-key that I use works correctly with the online CURL test so the actual key is correct but how I am adding it to my android code request must be invalid or similar.
Can anyone throw any light as to the correct way to convert the CURL into Android java so that the server does not return 403?
Thanks
It's easy to do with Jsoup:
// CREATE CONNECTION
Connection conn=Jsoup.connect("URL_GOES_HERE");
// ADD POST/FORM DATA
conn.data("KEY", "VALUE");
// ADD HEADERS HERE
conn.header("KEY", "VALUE");
// SET METHOD AS POST
conn.method(Connection.Method.POST);
// ACCEPT RESPONDING CONTENT TYPE
conn.ignoreContentType(true);
try
{
// GET RESPONSE
String response = conn.execute().body();
// USE RESPONSE HERE
// CREATE JSON OBJECT OR ANYTHING...
} catch(HttpStatusException e)
{
int status = e.getStatusCode();
// HANDLE HTTP ERROR HERE
} catch (IOException e)
{
// HANDLE IO ERRORS HERE
}
Ps: I guess you are confused with Header and Post Data. The key etc (Credentials) must be used as Post Data and Content Type etc as Header.
I am trying to send a two binary file to one of the REST API. But I get 400 bad request response from the end point.
Need to send below key and values to endpoint.
userForm - user.xml
structureForm - structure.xdp
Below is the java code, [UPDATED CODE]
HttpPost request = new HttpPost(url);
File userForm = new File("D:\\Downloads\\user.xml");
LOG.info("length ---->" + userForm.length()); // See valid file size
HttpEntity userFormEntity = MultipartEntityBuilder.create()
.addPart("userForm", new FileBody(userForm))
.build();
File structureFile = new File("D:\\Downloads\\structure.xdp");
LOG.info("length structureFile ---->" + structureFile.length()); // See valid file size
HttpEntity structureEntity = MultipartEntityBuilder.create()
.addPart("structureForm", new FileBody(structureFile))
.build();
if (userFormEntity != null && structureEntity != null) {
request.setEntity(userFormEntity);
request.setEntity(structureEntity);
}
final CloseableHttpClient httpClient = HttpClientBuilder.create().build();
CloseableHttpResponse response = httpClient.execute(request);
Seemed like the key 'userForm' and 'structureForm' are not going properly to end point. Is it correct way to send the key?
It is working when I try to submit through postman as below
I consulted the API documentation and sent it successfully in api explorer-> Envelopes: create. I also got json & request path & token. I used httpclient post in java and received Object moved Object moved to here . Does anyone know what I missed?
`
DocsignDocument docsignDocument = new DocsignDocument();
docsignDocument.setDocumentBase64
docsignDocument.setDocumentId("1");
docsignDocument.setFileExtension("pdf");
docsignDocument.setName("Test.pdf");
list.add(docsignDocument);
Recipients recipients = new Recipients();
Signers signers = new Signers();
signers.setEmail("xxxx");
signers.setName("Qin");
signers.setRecipientId("1");
Signers signers1 = new Signers();
signers1.setEmail("xxx#qq.com");
signers1.setName("OYX");
signers1.setRecipientId("2");
List<Signers> signersList = new ArrayList<>();
signersList.add(signers);
signersList.add(signers1);
recipients.setSigners(signersList);
dataJson.put("documents",list);
dataJson.put("emailSubject","TEST");
dataJson.put("recipients",recipients);
dataJson.put("status","sent");
String data = dataJson.toJSONString();
String results2 = HttpDocusignUtils.httpPostJson("https://account-d.docusign.com/restapi/v2.1/accounts/xxx/envelopes",access_token,data)`
post request:
public static String httpPostJson(String uri, String token, String obj) {
String result = "";
try {
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(uri);
httpPost.addHeader("Content-Type", "application/json"); // 添加请求头
httpPost.addHeader("Authorization","Bearer "+token);
httpPost.addHeader("Accept-Encoding","gzip,deflate,sdch");
httpPost.setEntity(new StringEntity(obj));
System.out.println(httpPost);
HttpResponse response = httpclient.execute(httpPost);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instreams = entity.getContent();
result = convertStreamToString(instreams);
System.out.println(result);
}
} catch (Exception e) {
e.getMessage();
}
return result;
}
https://account-d.docusign.com/restapi/v2.1/accounts/xxx/envelopes is not a valid DocuSign endpoint.
The Account Server (account-d.docusign.com) is used to get a token and make a UserInfo call to determine the correct base URL for a particular account.
Because you're in the Demo environment, your base url will begin with https://demo.docusign.net
Well, one issue is that the the Document model in Java is Document from
import com.docusign.esign.model.Document;
To debug, I suggest using the DocuSign API logging feature. Then update (edit) your question to include the JSON shown in the log.
Were you able to run the code examples for Java? See eg-03-java-auth-code-grant
Also, please tell us (by editing your question) what you are trying to do.
Creates envelopes - Use Base Url in Api Call
https://demo.docusign.net/restapi/v2.1/accounts/
Error Reason is use Wrong url - https://account-d.docusign.com/restapi/v2.1/accounts/
DocuSign Developers Documentation
I have a problem with a WebService on Android. I am getting a 400 error but there is no information on the ErrorStream.
What I am trying to do is a POST request on a WCF Webservice using JSON.
I must add that I have includeExceptionDetailInFaults Enabled on my Service. The last time I got a 400 error, it was because I hadn't defined the RequestProperty. Now I don't get any error in the stream.
Here is the code:
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
// In my last error I had not included these lines. Maybe they are still wrong?
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Accept", "application/json");
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true);
urlConnection.setChunkedStreamingMode(0);
OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(out);
outputStreamWriter.write(jsonObject.toString(), 0, jsonObject.length());
outputStreamWriter.flush();
//outputStreamWriter.close();
int code = urlConnection.getResponseCode();
System.out.println(code);
if(code == 400) {
BufferedInputStream errorStream = new BufferedInputStream(urlConnection.getErrorStream());
InputStreamReader errorStreamReader = new InputStreamReader(errorStream);
BufferedReader bufferedReader = new BufferedReader(errorStreamReader);
StringBuilder builder = new StringBuilder();
String aux = "";
while ((aux = bufferedReader.readLine()) != null) {
builder.append(aux);
}
String output = builder.toString(); // The output is empty.
System.out.print(output);
}
Check Retrofit library from Square it's more easy and thin for GET/POST request and especially for REST. I suggest you to try it. It will make your life easy.
You can use different JSON parsers, error handlers, etc. Very flexible.
POST request definition using retrofit it's simple like this:
An object can be specified for use as an HTTP request body with the #Body annotation.
#POST("/users/new")
void createUser(#Body User user, Callback<User> cb);
Methods can also be declared to send form-encoded and multipart data.
Form-encoded data is sent when #FormUrlEncoded is present on the method. Each key-value pair is annotated with #Field containing the name and the object providing the value.
#FormUrlEncoded
#POST("/user/edit")
User updateUser(#Field("first_name") String first, #Field("last_name") String last);
After you define method inside your Java interface like shown above instantiate it:
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("https://api.soundcloud.com")
.build();
MyInterface service = restAdapter.create(MyInterface.class);
And then you can call your method synchronously or asynchronously (in case you pass Callback instance).
service.myapi(requestBody);
See Retrofit documentation (http://square.github.io/retrofit/javadoc/index.html) and samples on GitHub for more details.
A 400 error might be occuring (and usually occurs in my case) because of incorrect URL or bad JSON format in post. please check those two
Using an HttpPost object will make your job a lot easier in my opinion
HttpPost post = new HttpPost(url);
if(payload != null){
try {
StringEntity entity = new StringEntity(payload,HTTP.UTF_8);
entity.setContentType(contentType);
post.setEntity(entity);
} catch (UnsupportedEncodingException e) {
LOG.d(TAG, "post err url : " + url);
LOG.e(TAG, "post err url" , e);
throw new Exception(1, e);
}
}
HttpResponse response=executeRequest(owner, post);
I'm currently trying to get some data via a 'uri' using the following code in java:
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(uri);
HttpResponse response = client.execute(get);
HttpEntity entity = response.getEntity();
if(entity != null){
InputStream stream = entity.getContent();
callString = stream.toString();
return callString;
}
However this isn't working. Does anyone know what I'm doing wrong here?
You cannot print out the input stream like that... instead, do something like this:-
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet("http://ichart.finance.yahoo.com/table.csv?s=MSFT");
HttpResponse response = client.execute(get);
HttpEntity entity = response.getEntity();
if (entity != null) {
Scanner scanner = new Scanner(entity.getContent());
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
}
The printout looks like this:-
1994-02-02,84.75,85.50,84.00,84.00,40924800,2.09
1994-02-01,85.00,85.75,84.50,85.12,44003200,2.12
1994-01-31,85.25,85.87,84.75,85.12,62566400,2.12
1994-01-28,84.50,85.50,84.25,84.87,41875200,2.11
1994-01-27,84.00,84.75,83.25,84.25,51129600,2.10
1994-01-26,85.00,85.00,84.00,84.25,50489600,2.10
1994-01-25,85.25,85.37,84.00,85.12,70361600,2.12
...
Its a total guess but shouldn't it be:
String uri = "ichart.finance.yahoo.com/table.csv?s=MSFT"
HttpData data = HttpRequest.get(uri);
System.out.println(data.content);
you are trying to download a file and getEntity is used get an object for a type you have specified. IMHO this wont work.
You need to code which will actually read the response stream and read contents out of it...
What are you trying to do ?
To read the resulting entity to a String use EntityUtils.toString(HttpEntity) or EntityUtils.toString(HttpEntity, String) if you know the character set.
If you are getting NetworkOnMainThreadException then that means you are calling client.execute(get); on the main thread which is an exception thrown on Honeycomb and higher. See http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html for details. The solution is to run this in a new thread.