I downloaded the android-async-http-1.4.8.jar and put it under the app->libs folder. Then add the following code in the MainActivity.
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.google.com", new AsyncHttpResponseHandler() {
#Override
public void onStart() {
// called before request is started
}
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
// called when response HTTP status is "200 OK"
textViewDailyTip.setText(response.toString());
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
}
#Override
public void onRetry(int retryNo) {
// called when request is retried
}
});
but I got the error.
Error:(50, 9) error: cannot access AsyncHttpClient
bad class file: /Users/user/AndroidStudioProjects/yan.com/Yin/app/libs/android-async-http-1.4.8.jar(com/loopj/android/http/AsyncHttpClient.class)
unable to access file: null
Please remove or make sure it appears in the correct subdirectory of the classpath.
Add dependency in the build.gradle file under app:
dependencies {
compile 'com.loopj.android:android-async-http:1.4.9'
}
taken from: Installation & Basic Usage
If it didn't work, try executing the following command:
gradlew installarchives
It should also work without downloading the jar file.
Another note is that I am using version 1.4.5.
Good luck!
Related
I'm trying to get a response from a simple protected Endpoint in the back end.
I've tested the Endpoint in Postman. I set up GET request with the KEY: Authorization and a VALUE: bearer eyxhsls...(this is the Jwt)
and the response gives me Status: 200 OK and the requested String. So everything works fine in the back end.
Now I want to replicate this process on the Client-side using Retrofit. Based on some research I using an OkHttpClient.Builder to insert the Jwt(String) into the header.
I try different things like simply inserting the Jwt(String) into header value:
Request.Builder newRequest = request.newBuilder().header("Authorization", bearerToken);
This returns a 401 status
I have also added the "Bearer " to the VALUE, just like I did in Postman, but the caller referred me to the onFailure method with the Message:
use jsonreader.setlenient(true) to accept malformed json at line 1 column 1
So I have added a GsonBuilder with setLeniet to the addConverterFactory. the caller again referred me to the onFailure method, but with the Message:
JSON document was not fully consumed.
Plz, let me know if anyone has a better idea, or understands what is going on. But stuck now for a number of days now.
public CoffeeController() {
okhttpBuilder = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
#NonNull
#Override
public okhttp3.Response intercept(#NonNull Chain chain) throws IOException {
Request request = chain.request();
bearerToken = "Bearer " +LoginController.getToken();
bearerToken = LoginController.getToken();
Request.Builder newRequest = request.newBuilder().header("Authorization", bearerToken);
return chain.proceed(newRequest.build());
}
});
gson = new GsonBuilder()
.setLenient()
.create();
retrofit = new Retrofit.Builder()
.baseUrl("http://10.0.2.2:8080/")
.client(okhttpBuilder.build())
//.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
public static void CoffeeRead(Context context, TextView ResponseView) {
try {
CoffeeRepo repo = retrofit.create(CoffeeRepo.class);
Call<String> call = repo.Read();
call.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
message = "Read Coffee: " +"\nToken: " +bearerToken +"\nResponse: " + response.code();
ResponseView.setText(message);
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
#Override
public void onFailure(Call<String> call, Throwable t) {
message = "Failed to read coffee: \n" + t.getMessage();
ResponseView.setText(message);
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
});
} catch (Exception e) {
message = "Caught Exception: \n" + e.getMessage();
ResponseView.setText(message);
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
}
public interface CoffeeRepo {
#Headers({
"Cache-Control: max-age=3600",
"User-Agent: Android"
})
#GET("coffee")
Call<String> Read();
}
After I've added a logger, I found out the response was 200. After some research I found out I needed different ConverterFactory, instead of:
.addConverterFactory(ScalarsConverterFactory.create())
I used
.addConverterFactory(GsonConverterFactory.create(gson));
I want to access data on the openrouteservice API - specifically the distance between two given coordinates on the globe - from my Android application.
I have made requests and gotten viable responses from another API that converts two given addresses into their latlong coordinates using the same style of code this request is trying to execute. It works fine, the coordinates arrive and i can further utilize them no problem.
My problem is that i seem to be accessing the API wrongly because if I Log the URL as seen below and copy it from the Debug window into my browser it sends the request, gets a response and shows it in the browser window.
But my application doesn't recieve a response from the API as the onResponse code bit is never executed and the "Fetch done" Log never appears in the actual Debug Log.
The following is my setup of code, which uses Volley to access HTTP Requests and which works fine for other APIs.
#Override
protected String doInBackground(String... strings) {
Log.d("Run =>","Query 3");
String targetKoordURL = null;
String startKoordURL = null;
try {
startKoordURL = startK.getString("lon").concat(",").concat(startK.getString("lat"));
targetKoordURL = targetK.getString("lon").concat(",").concat(targetK.getString("lat"));
} catch (JSONException e) {
e.printStackTrace();
}
String URLfin = "https://api.openrouteservice.org/v2/directions/driving-car?api_key=5b3ce3597851110001cf624823e587e7a80c4c6ab02af6d394585213&start="+startKoordURL+"&end="+targetKoordURL;
Log.d("Debug =>", URLfin);
JsonObjectRequest req = new JsonObjectRequest(Request.Method.GET, URLfin, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
store = response;
Log.d("Run =>", "Fetch done!");
continueImp();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if(error instanceof TimeoutError || error instanceof NoConnectionError){
sideFetcherHTTPRequestStart replace = new sideFetcherHTTPRequestStart();
replace.execute();
Log.d("VOLLEY_ERROR", "Retrying on Kilometer request");
}
error.printStackTrace();
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Accept", "application/json,application/geo+json,application/gpx+xml,img/png; charset=utf-8");
return params;
}
};
return null;
}
You forget to add the request to request queue, try to do as following:
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
JsonObjectRequest req = new JsonObjectRequest(/*params*/);
//add above request to queue
queue.add(req);
I use Spring Rest Docs in version 1.1.2.RELEASE
The Test
MvcResult result = this.mockMvc.perform(get("/api").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andDo(document("index"))
.andReturn();
The API
#RequestMapping(value = "/api")
public ResponseEntity<String> apiWelcome() {
final HttpHeaders httpHeaders= new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
return new ResponseEntity<String>("{\"api\": \"test1\"}", httpHeaders, HttpStatus.OK);
}
When I run the application I can access "/api" in the browser and get the expected {"api": "test1"} response.
But if I run the test I get the following log entries:
c.i.crawler.testnet.measure.RestDocsTest INFO Started RestDocsTest in 2.96 seconds
o.s.web.servlet.PageNotFound WARN No mapping found for HTTP request with URI [/api] in DispatcherServlet with name '' [main]
and the test fails because of HTTP/1.1 404 Not Found.
What am I doing wrong?
Application start
#SpringBootApplication
#Configuration
#EnableConfigurationProperties
#EnableAutoConfiguration
#ComponentScan(basePackageClasses = { SomeController.class })
public class AppRUN {
public static void main(String[] args) {
SpringApplication.run(AppRUN.class, args);
}
}
My test class was annotated as follows:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes=RestDocsTest.class)
#WebAppConfiguration
Changing the annotations to the following removes the error:
#RunWith(SpringRunner.class)
#SpringBootTest
I have a website using Nancy which is hosted using OWIN.
In my Startup.cs file I define the PassThroughOptions as follows:
public void Configuration(IAppBuilder app)
{
app.UseNancy(o => {
o.PassThroughWhenStatusCodesAre(
HttpStatusCode.NotFound,
HttpStatusCode.InternalServerError
);
o.Bootstrapper = new Bootstrapper();
});
app.UseStageMarker(PipelineStage.MapHandler);
}
I need to pass-through the NotFound requests, so that things like my bundled .less files or miniprofiler-results or static files in the root of my site (robots.txt or sitemap.xml) work.
I also have a custom StatusCodeHandler for the 404 code, which also checks a custom header to distinguish between static files (or .less bundles/miniprofiler) and actual stuff that is not found in my modules' methods.
public void Handle(HttpStatusCode statusCode, NancyContext context)
{
Log.Warn("Not found: " + context.Request.Url);
base.Handle(statusCode, context, "Errors/NotFound");
}
This handler then should actually show the error page.
protected void Handle(HttpStatusCode statusCode, NancyContext context, string view)
{
var response = new Negotiator(context)
.WithModel(GetErrorModel(context))
.WithStatusCode(statusCode)
.WithView(view);
context.Response = responseNegotiator.NegotiateResponse(response, context);
}
But the error page is never shown. The request is processed three times and eventually the default IIS error page is shown (using errorMode="Custom" for httpErrors) or simply a white page (using existingResponse="PassThrough" for httpErrors).
Is there any way to display something so simple as a custom error page when hosting a Nancy website on OWIN?
What you've got there looks good, it looks like you've be using the Hosting Nancy with Owin docs.
Here's what works for me:
The Startup.cs (required for Owin): (We've both coded the configuration function differently, you're just using the extension helper while I'm not. Same result. This is in my App.Web project.)
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseNancy(options =>
{
options.Bootstrapper = new BootStrapper();
options.PerformPassThrough = context => context.Response.StatusCode == HttpStatusCode.NotFound;
});
app.UseStageMarker(PipelineStage.MapHandler);
}
}
404 handler: (As per the docs, doesn't matter where this is in the project, by implementing IStatusCodeHandler it'll be automatically picked up by Nancy This is in my App.WebApi project with other module classes.)
public class StatusCode404Handler : IStatusCodeHandler
{
public bool HandlesStatusCode(HttpStatusCode statusCode, NancyContext context)
{
return statusCode == HttpStatusCode.NotFound;
}
public void Handle(HttpStatusCode statusCode, NancyContext context)
{
var response = new GenericFileResponse("statuspages/404.html", "text/html")
{
StatusCode = statusCode
};
context.Response = response;
}
}
The 'statuspages' folder in my App.Web project:
Check this SO post for a comparison of using GenericFileReponse or ViewRenderer (How to display my 404 page in Nancy?).
I have a ServiceStack Service, and the service generates a .zip file then returns it via:
result = new HttpResult(new FileInfo(zipFileName), asAttachment: false);
followed by (later)
Directory.Delete(dir); // Containing the zipfile
return result
The problem I have is I now want to delete the generated file, but I can't because it's still busy.
with an invalid access violation.
What's the best way to handle this? Is there a way to write the whole contents to the response stream which would free up the directory?
There are a number of different ways to return binary responses which can be seen in the ImageService: e.g. you can:
return byte[], Stream, IStreamWriter from your Service which get written directly to the response
wrap byte[], Stream responses in a HttpResult to also customize the HTTP Response headers
write directly to the base.Response in your service
return a custom a custom result
Here's a custom Result example that implements IStreamWriter which writes the file to the response stream and deletes the parent directory of the containing file in the Dispose() method:
public class ZipFileResult : IDisposable, IStreamWriter, IHasOptions
{
private readonly FileInfo fileInfo;
public ZipFileResult(FileInfo zipInfo, string contentType="application/zip")
{
fileInfo = zipInfo;
Options = new Dictionary<string, string> {
{ HttpHeaders.ContentType, contentType }
};
}
public void WriteTo(Stream responseStream)
{
using (var fs = fileInfo.OpenRead())
{
fs.WriteTo(responseStream);
return;
}
}
public void Dispose()
{
Directory.Delete(fileInfo.DirectoryName);
}
public IDictionary<string, string> Options { get; set; }
}