I wrote a method that gets JSON, converts an object to java and writes JSON to a file.But writing to the file just does not work. Tell me what could be the reason?
public class ApiUtils {
public static HttpClient client = HttpClient.newHttpClient();
public static void getRequest(String url, String path) {
PostDTO postDTO = new PostDTO();
String pathJSONFile = "src/main/resources/Post.json";
List<PostPojo> postPojos = null;
HttpRequest request = HttpRequest.newBuilder()
.GET()
.header("accept", "application/json")
.uri(URI.create(url + path))
.build();
try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
ObjectMapper objectMapper = new ObjectMapper();
postPojos = objectMapper.readValue(response.body(), new TypeReference<List<PostPojo>>() {
});
objectMapper.writeValue(Paths.get("allPost.json").toFile(), response.body());
postDTO.setStatus(response.statusCode());
postDTO.setPosts(postPojos);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(postDTO);
}
}
File allPost.json located in the folder resources.
You're writing the wrong object I think - your code sample says
objectMapper.writeValue(Paths.get("allPost.json").toFile(), response.body());
which is trying to write the InputStream of response.body(). I presume you meant to try and write out postPojos via
objectMapper.writeValue(Paths.get("allPost.json").toFile(), postPojos);
instead.
Related
I'm using an asynchronous request (because synchronous doesn't work correctly with this API), the OkHttp3 library. Inside the request, I get a response in the form of JSON. I need to somehow pass values from Json to a class variable. I decided to try it this way, but it doesn't work.
public String sessionId = null;
...
public QRcodeReader() throws Exception {
this.sessionId = null;
}
... // between this code I have 1 function, which reg my number.
// in this func I need to confirm my phone by code in SMS.
public void SmsCode(String Code) // String get from another class
{
SmsJson smsJson = new SmsJson("*phoneNumber*", "*secret_key*", "*os*", Code);
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
RequestBody body = RequestBody.create(
MediaType.parse("application/json"), gson.toJson(smsJson));
Request request = new Request.Builder()
.url("https://irkkt-mobile.nalog.ru:8888/v2/auth/phone/verify")
.addHeader("Host", HOST)
.addHeader("Accept", ACCEPT)
.addHeader("Device-OS", DEVICE_OS)
.addHeader("Device-ID", DEVICE_ID)
.addHeader("clientVersion", CLIENT_VERSION)
.addHeader("Accept-Language", ACCEPT_LANGUAGE)
.addHeader("User-Agent", USER_AGENT)
.post(body)
.build();
httpClient.newCall(request).enqueue(new Callback() {
#Override
public void onResponse(#NonNull Call call, #NonNull Response response) throws IOException {
try (Response responseBody = httpClient.newCall(request).execute()) {
if (!responseBody.isSuccessful())
throw new IOException("Unexpected code " + responseBody);
// Here I try to transfer data from request to class variable. Not Work.
SetSessionId(Objects.requireNonNull(responseBody.body()).string());
System.out.println(Objects.requireNonNull(responseBody.body()).string());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
});
}
void SetSessionId(String sessionId){
this.sessionId = sessionId;
}
I need to use SessionID further along here:
public String GetTicketID(String QR){
TicketID ticketID = new TicketID(QR);
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
RequestBody body = RequestBody.create(
MediaType.parse("application/json"), gson.toJson(ticketID));
Request request = new Request.Builder()
.url("https://irkkt-mobile.nalog.ru:8888/v2/ticket")
.addHeader("Host", HOST)
.addHeader("Accept", ACCEPT)
.addHeader("Device-OS", DEVICE_OS)
.addHeader("Device-ID", DEVICE_ID)
.addHeader("clientVersion", CLIENT_VERSION)
.addHeader("Accept-Language", ACCEPT_LANGUAGE)
.addHeader("User-Agent", USER_AGENT)
.addHeader("sessionId", sessionId) // Here I get NULL and exception!
.post(body)
.build();
httpClient.newCall(request).enqueue(new Callback() {
#Override
public void onResponse(Call call, Response response) throws IOException {
try (Response responseBody = httpClient.newCall(request).execute()) {
if (!responseBody.isSuccessful())
throw new IOException("Unexpected code " + responseBody);
System.out.println(Objects.requireNonNull(responseBody.body()).string());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
});
return ""; // Here I need to transfer id to another variable, not did it yet.
}
The problem is that SessionID = Null and the request does not work.
I think I'm doing something wrong, but I can't figure out what. May be it is because async request..
Good day. I've defined a 2 URI's for a http call. The first one works great, the code is a complete copy beside some arguments. The second one throws a Exception . I'll list the code below.
public class WeatherAPI {
private static String apiKey = "asdasd";
private HttpResponse<String> response;
private URI uri;
private HttpRequest getRequest(URI newUri) {
return HttpRequest.newBuilder()
.uri(newUri)
.build();
}
private HttpClient getClient() {
return HttpClient.newBuilder().build();
}
private String getResponse(URI uri) {
var client = getClient();
var request = getRequest(uri);
try {
response = client.send(request, HttpResponse.BodyHandlers.ofString());
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return response.body();
}
public JSONObject getCityData(String lat, String lon) {
String url = "api.openweathermap.org/data/2.5/weather"; // System.out.println(uri);
try {
uri = new URIBuilder(URI.create(url))
.addParameter("lat", lat)
.addParameter("lon", lon)
.addParameter("appid", apiKey)
.build();
System.out.println(uri);
} catch (URISyntaxException e) {
e.printStackTrace();
}
var body = getResponse(uri);
System.out.println(body);
return null;
}
}
Throws
Exception in thread "main" java.lang.IllegalArgumentException: URI
with undefined scheme
It seems that the URL is missing the protocol-Prefix like http:// or https:// .. try
http://api.openweathermap.org/data/2.5/weather
or
https://api.openweathermap.org/data/2.5/weather
as URL. This should work.
I'm trying to make a request and get the json response to a json string but every time i execute this it gives me an exception. Please help me.
public String login(String json) throws IOException {
OkHttpClient client = new OkHttpClient();
Gson gson = new Gson();
Agent agent = gson.fromJson(json, Agent.class);
json = gson.toJson(agent, Agent.class);
String url = "http://laravel-zona-azul.herokuapp.com/api/v1/login";
Request.Builder builder = new Request.Builder();
builder.url(url);
MediaType mediaType =
MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(mediaType, json);
builder.post(body)
.addHeader("login", agent.login)
.addHeader("cache-control", agent.password);
Log.d("MYAPP", "Body: " + body);
Request request = builder.build();
try{
Response response = client.newCall(request).execute();
return response.body().string();
}
catch (IOException e){
e.printStackTrace();
}
return "";
}
Use this it's working fine for me.
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (response != null)
try {
response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
}
});
Instead of Using this
try{
Response response = client.newCall(request).execute();
return response.body().string();
}
catch (IOException e){
e.printStackTrace();
}
How to download and read a text file using Retrofit or even better Rx Retrofit ?
Below is a sample how it was done before retrofit time.
really would be how to convert the code below in Retrofit
Sample:
try {
// Create a URL for the desired page
URL url = new URL("ksite.com/thefile.txt");
// Read all the text returned by the server
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String str;
while ((str = in.readLine()) != null) {
// str is one line of text; readLine() strips the newline character(s)
}
in.close();
} catch (MalformedURLException e) {
} catch (IOException e) {
}
I really Appreciate your help. Thanks
Edit:
There is a #Streaming annotation since version Retrofit 1.6 that can be used for delivering a raw InputStream. Can be used for downloading a file.
IMO Retrofit is not the best tool for downloading a file (unless the file contains JSON).
Using Retrofit (version 2) means you are using OkHttp under the hood. OkHttp is the better tool for downloading a file.
An asynchronous get with OkHttp looks like this:
private final OkHttpClient client = new OkHttpClient();
public void run() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
client.newCall(request).enqueue(new Callback() {
#Override public void onFailure(Request request, IOException throwable) {
throwable.printStackTrace();
}
#Override public void onResponse(Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
Headers responseHeaders = response.headers();
for (int i = 0; i < responseHeaders.size(); i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}
System.out.println(response.body().string());
}
});
}
More in the recipes section on Github.
Also from the wiki:
The string() method on response body is convenient and efficient for
small documents. But if the response body is large (greater than 1
MiB), avoid string() because it will load the entire document into
memory. In that case, prefer to process the body as a stream.
Edit:
Using RxJava
public interface Api {
#Streaming
#GET("path to file")
Observable<ResponseBody> getFile();
}
api.getFile()
.flatMap(responseBody -> {
try {
return Observable.just(responseBody.string());
} catch (IOException e) {
return Observable.error(e);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(System.out::println);
Again you should probably not use responseBody.string() for bigger files.
I try to issue a POST request with ClientResource, I'm able to retrieve the response STATUS, I also want to get the response body when I get an exception.
Here is my code:
public static Pair<Status, JSONObject> post(String url, JSONObject body) {
ClientResource clientResource = new ClientResource(url);
try {
Representation response = clientResource.post(new JsonRepresentation(body), MediaType.APPLICATION_JSON);
String responseBody = response.getText();
Status responseStatus = clientResource.getStatus();
return new ImmutablePair<>(responseStatus, new JSONObject(responseBody));
} catch (ResourceException e) {
logger.error("failed to issue a POST request. responseStatus=" + clientResource.getStatus().toString(), e);
//TODO - how do I get here the body of the response???
} catch (IOException |JSONException e) {
throw e;
} finally {
clientResource.release();
}
}
Here is the code that my server resource returns in case of failure
getResponse().setStatus(Status.CLIENT_ERROR_FORBIDDEN);
JsonRepresentation response = new JsonRepresentation( (new JSONObject()).
put("result", "failed to execute") );
return response;
I try to catch the "result" with no success
In fact, the getResponseEntity method returns the content of the response. It corresponds to a representation. You can wrap it by a JsonRepresentation class if you expect some JSON content:
try {
(...)
} catch(ResourceException ex) {
Representation responseRepresentation
= clientResource.getResponseEntity();
JsonRepresentation jsonRepr
= new JsonRepresentation(responseRepresentation);
JSONObject errors = jsonRepr.getJsonObject();
}
You can notice that Restlet also supports annotated exceptions.
Otherwise I wrote a blog post about this subject: http://restlet.com/blog/2015/12/21/exception-handling-with-restlet-framework/. I think that it could help you.
Thierry