Creating an android app to receive data in json format from web server
in my app I should have url as string and use it to fetch data like below
private static final String my_url = "http://example.com/folder/showJsonData.php";
jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, my_url ,new Response.Listener<JSONObject>() {
.
.
.
}
as you see my_url is not complicated or encoded so everyone can access it after decompiling apk.
the question is that how can I make it a little more complicated
please explain it with example.
Thanks
URL encoding is done in the same way on android as in Java SE;
try {
String url = "http://www.example.com/?id=123&art=abc";
String encodedurl = URLEncoder.encode(url,"UTF-8");
Log.d("TEST", encodedurl);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Related
I have tried to build a http server to streaming video using HLS. I have process the response like below.
private void handleResponse(HttpExchange exchange, String fileNameValue) {
OutputStream responseStream = exchange.getResponseBody();
File file = new File(fileNameValue);
try {
String encoding = "UTF-8";
String response = FileUtils.readFileToString(file, encoding);
exchange.getResponseHeaders().set("Content-Type", "application/x-mpegURL");
exchange.getResponseHeaders().set("Accept-Ranges", "bytes");
exchange.getResponseHeaders().set("Cache-Control", "max-age=0, no-cache, no-store");
exchange.sendResponseHeaders(200, response.length());
responseStream.write(response.getBytes());
responseStream.flush();
responseStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
But the browsers always download the file instead of playing it. And VLC Media Player doesn't play it too.
I want to get the result like this.
Can you show me the way to do it? Some keywords for researching are also appreciated.
I have figured out that their website using xhr to send request so the file appears in the Network section.
I use hls.js after that and get the same result :)
I want to get Amazon page and product information from their website so I work on a future project. I have no experience with APIs but also saw that I would need to pay in order to use Amazon's. My current plan was to use a WebRequest class which basically takes down the page's raw text and then parse through it to get what I need. It pulls down HTML from all the websites I have tried except amazon. When I try and use it for amazon I get text like this...
??èv~-1?½d!Yä90û?¡òk6??ªó?l}L??A?{í??j?ì??ñF Oü?ª[D ú7W¢!?É?L?]â v??ÇJ???t?ñ?j?^,Y£>O?|?I`OöN??Q?»bÇJPy1·¬Ç??RtâU??Q%vB??^íè|??ª?
Can someone explain to me why this happens? Or even better if you could point me towards a better way of doing this? Any help is appreciated.
This is the class I mentioned...
public class WebRequest {
protected String url;
protected ArrayList<String> pageText;
public WebRequest() {
url = "";
pageText = new ArrayList<String>();
}
public WebRequest(String url) {
this.url = url;
pageText = new ArrayList<String>();
load();
}
public boolean load() {
boolean returnValue = true;
try {
URL thisURL = new URL(url);
BufferedReader reader = new BufferedReader(new InputStreamReader(thisURL.openStream()));
String line;
while ((line = reader.readLine()) != null) {
pageText.add(line);
}
reader.close();
}
catch (Exception e) {
returnValue = false;
System.out.println("peepee");
}
return returnValue;
}
public boolean load(String url) {
this.url = url;
return load();
}
public String toString() {
String returnString = "";
for (String s : pageText) {
returnString += s + "\n";
}
return returnString;
}
}
It could be that the page is returned using a different character encoding than your platform default. If that's the case, you should specify the appropriate encoding, e.g:
new InputStreamReader(thisURL.openStream(), "UTF-8")
But that data doesn't look like character data at all to me. It's too random. It looks like binary data. Are you sure you're not downloading an image by mistake?
If you want to make more sophisticated HTTP requests, there are quite a few Java libraries, e.g. OkHttp and AsyncHttpClient.
But it's worth bearing in mind that Amazon probably doesn't like people scraping its site, and will have built in detection of malicious or unwanted activity. It might be sending you gibberish on purpose to deter you from continuing. You should be careful because some big sites may block your IP temporarily or permanently.
My advice would be to learn how to use the Amazon APIs. They're pretty powerful—and you won't get yourself banned.
Trying to build http://IP:4567/foldername/1234?abc=xyz. I don't know much about it but I wrote below code from searching from google:
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
public class MyUrlConstruct {
public static void main(String a[]){
try {
String protocol = "http";
String host = "IP";
int port = 4567;
String path = "foldername/1234";
URL url = new URL (protocol, host, port, path);
System.out.println(url.toString()+"?");
} catch (MalformedURLException ex) {
ex.printStackTrace();
}
}
}
I am able to build URL http://IP:port/foldername/1234?. I am stuck at query part. Please help me to move forward.
You can just pass raw spec
new URL("http://IP:4567/foldername/1234?abc=xyz");
Or you can take something like org.apache.http.client.utils.URIBuilder and build it in safe manner with proper url encoding
URIBuilder builder = new URIBuilder();
builder.setScheme("http");
builder.setHost("IP");
builder.setPath("/foldername/1234");
builder.addParameter("abc", "xyz");
URL url = builder.build().toURL();
Use OkHttp
There is a very popular library named OkHttp which has been starred 20K times on GitHub. With this library, you can build the url like below:
import okhttp3.HttpUrl;
URL url = new HttpUrl.Builder()
.scheme("http")
.host("example.com")
.port(4567)
.addPathSegments("foldername/1234")
.addQueryParameter("abc", "xyz")
.build().url();
Or you can simply parse an URL:
URL url = HttpUrl.parse("http://example.com:4567/foldername/1234?abc=xyz").url();
In general non-Java terms, a URL is a specialized type of URI. You can use the URI class (which is more modern than the venerable URL class, which has been around since Java 1.0) to create a URI more reliably, and you can convert it to a URL with the toURL method of URI:
String protocol = "http";
String host = "example.com";
int port = 4567;
String path = "/foldername/1234";
String auth = null;
String fragment = null;
URI uri = new URI(protocol, auth, host, port, path, query, fragment);
URL url = uri.toURL();
Note that the path needs to start with a slash.
If you happen to be using Spring already, I have found the org.springframework.web.util.UriComponentsBuilder to be quite nifty. Here is how you would use it in your case.
final URL myUrl = UriComponentsBuilder
.fromHttpUrl("http://IP:4567/foldername/1234?abc=xyz")
.build()
.toUri()
.toURL();
If using Spring Framework:
UriComponentsBuilder.newInstance()
.scheme(scheme)
.host(host)
.path(path)
.build()
.toUri()
.toURL();
A new UriComponentsBuilder class helps to create UriComponents
instances by providing fine-grained control over all aspects of
preparing a URI including construction, expansion from template
variables, and encoding.
Know more:
https://www.baeldung.com/spring-uricomponentsbuilder
JavaDoc:
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/util/UriComponentsBuilder.html
If you use Android, you can use the Uri.Builder API. Example:
val uri = Uri.Builder().scheme("https").authority("s3.amazonaws.com").appendEncodedPath(bucketName).appendEncodedPath(fileName).build()
Docs:
https://developer.android.com/reference/android/net/Uri.Builder
I just started using YouTube API for Java and I'm having a tough time trying to figure out why things don't work since exception/stack trace is no where to be found. What I'm trying to do is to get list of videos uploaded by current user.
GoogleTokenResponse tokenFromExchange = new GoogleTokenResponse();
tokenFromExchange.setAccessToken(accessToken);
GoogleCredential credential = new GoogleCredential.Builder().setJsonFactory(JSON_FACTORY).setTransport(TRANSPORT).build();
credential.setFromTokenResponse(tokenFromExchange);
YouTube.Channels.List channelRequest = youtube.channels().list("contentDetails");
channelRequest.setMine(true);
channelRequest.setFields("items/contentDetails,nextPageToken,pageInfo");
ChannelListResponse channelResult = channelRequest.execute();
I don't see anything wrong with this code and also tried removing multiple things, but still not able to get it to work. Please let me know if you have run into a similar issue. The version of client library I'm using is v3-rev110-1.18.0-rc.
YouTube API has some working code and you can use it.
public static YouTubeService service;
public static String USER_FEED = "http://gdata.youtube.com/feeds/api/users/";
public static String CLIENT_ID = "...";
public static String DEVELOPER_KEY = "...";
public static int getVideoCountOf(String uploader) {
try {
service = new YouTubeService(CLIENT_ID, DEVELOPER_KEY);
String uploader = "UCK-H1e0S8jg-8qoqQ5N8jvw"; // sample user
String feedUrl = USER_FEED + uploader + "/uploads";
VideoFeed videoFeed = service.getFeed(new URL(feedUrl), VideoFeed.class);
return videoFeed.getTotalResults();
} catch (Exception ex) {
Logger.getLogger(YouTubeCore.class.getName()).log(Level.SEVERE, null, ex);
}
return 0;
}
This simple give you the number of videos a user has. You can read through videoFeed using printEntireVideoFeed prepared on their api page.
I have a cloud storage at strato namely hidrive. It uses the webdav protocol. Note that it's based on HTTP. The client application they provide is poor and buggy so I tried various other tools for synchronization but none just worked the way I need it.
I'm therefore trying to implement it in Java using the Sardine project. Is there any code for hard-copying a local source folder to an external cloud folder? I haven't found anything in that direction.
The following code is supposed to upload the file...
Sardine sardine = SardineFactory.begin("username", "password");
InputStream fis = new FileInputStream(new File("some/file/test.txt"));
sardine.put("https://webdav.hidrive.strato.com/users/username/Backup", fis);
... but throws an exception instead:
Exception in thread "main" com.github.sardine.impl.SardineException: Unexpected response (301 Moved Permanently)
at com.github.sardine.impl.handler.ValidatingResponseHandler.validateResponse(ValidatingResponseHandler.java:48)
at com.github.sardine.impl.handler.VoidResponseHandler.handleResponse(VoidResponseHandler.java:34)
at com.github.sardine.impl.handler.VoidResponseHandler.handleResponse(VoidResponseHandler.java:1)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:218)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:160)
at com.github.sardine.impl.SardineImpl.execute(SardineImpl.java:828)
at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:755)
at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:738)
at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:726)
at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:696)
at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:689)
at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:682)
at com.github.sardine.impl.SardineImpl.put(SardineImpl.java:676)
Printing out the folders in that directory works so the connection/ authentication did succeed:
List<DavResource> resources = sardine.list("https://webdav.hidrive.strato.com/users/username/Backup");
for (DavResource res : resources)
{
System.out.println(res);
}
Please either help me fix my code or link me to some file synchronization library that works for my purpose.
Sardine uses (internally) HttpClient. There is similar question here where you can find an answer Httpclient 4, error 302. How to redirect?.
Try converting the InputStream obj into byte array before you call put(). Something like the below,
byte[] fisByte = IOUtils.toByteArray(fis);
sardine.put("https://webdav.hidrive.strato.com/users/username/Backup", fisByte);
It worked for me. Let me know.
I had to extend the "org.apache.http.impl.client.LaxRedirectStrategy" and also the getRedirect() Method of org.apache.http.impl.client.DefaultRedirectStrategy with a treatment of the needed methods: PUT, MKOL, etc. . By default only GET is redirected.
It looks like this:
private static final String[] REDIRECT_METHODS = new String[] { HttpGet.METHOD_NAME, HttpPost.METHOD_NAME, HttpHead.METHOD_NAME, HttpPut.METHOD_NAME, HttpDelete.METHOD_NAME, HttpMkCol.METHOD_NAME };
isRedirectable-Method
for (final String m : REDIRECT_METHODS) {
if (m.equalsIgnoreCase(method)) {
System.out.println("isRedirectable true");
return true;
}
}
return method.equalsIgnoreCase(HttpPropFind.METHOD_NAME);
getRedirect-Method:
final URI uri = getLocationURI(request, response, context);
final String method = request.getRequestLine().getMethod();
if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
return new HttpHead(uri);
} else if (method.equalsIgnoreCase(HttpGet.METHOD_NAME)) {
return new HttpGet(uri);
} else if (method.equalsIgnoreCase(HttpPut.METHOD_NAME)) {
HttpPut httpPut = new HttpPut(uri);
httpPut.setEntity(((HttpEntityEnclosingRequest) request).getEntity());
return httpPut;
} else if (method.equalsIgnoreCase("MKCOL")) {
return new HttpMkCol(uri);
} else if (method.equalsIgnoreCase("DELETE")) {
return new HttpDelete(uri);
} else {
final int status = response.getStatusLine().getStatusCode();
if (status == HttpStatus.SC_TEMPORARY_REDIRECT) {
return RequestBuilder.copy(request).setUri(uri).build();
} else {
return new HttpGet(uri);
}
}
That worked for me.