URL encode Text with line breaks in java - java

So I have an ArrayList of String objects that I want to send in a Http POST request using the Apache Http Client.
What I am doing now is concatenating the List objects to a new String each followed by a System.getProperty("line.separator") for a linebreak.
However I get a bad response from the server, telling my the URL is malformed.
Thanks in advance for your help!
ArrayList<String> episodeList
String episodesAsString = "";
for(String s : episodeList)
episodesAsString = episodesAsString.concat(s + NL);
URI uri = new URI(
"https",
"my.domain.com",
"/path/add?this=123456&application=myApp&event=myEvent&description=" + episodesAsString,
null);
HttpClient client = new DefaultHttpClient();
HttpPost request = new HttpPost(uri);
HttpResponse response = client.execute(request);

It seems by NL you mean new line character. Instead after concatinating all the strings and using \n instead of NL, use URLEncoder to encode the string. Also check if the URL is being passed badly in debug.

In your case you are not sending POST data. The problem might be with bad URL.
Try this:
String strUrl = "http://localhost:7001/RESTFUL_Tutorial/rest/hello/test1/test naveen kumar/test pwd";
URL url = new URL(strUrl);
// for getting URI
URI urlinfo = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
// for getting URL
url = urlinfo.toURL();
For more better use URLEncoder
place your url.. :)

I think the URI is the problem. Even though I think you can construct a proper URL using it, you are missing the '//' before the hostname. I your example, I believe the request would be going to:
https:my.domain.com/path/addthis=123456&application=myApp&event=myEvent&description=XXX
This is based on the 5min I just spent reading the JavaDoc of the URI class. You could probably test this by putting a Proxy or sniffer on and seeing what the payload of the headers look like.

Related

Creating a URL Using Java - What's the Best Practice?

I have an application that is calling a rest service. I need to pass it a URL and right now I'm creating the URL by concatenating a string.
I'm doing it this way:
String urlBase = "http:/api/controller/";
String apiMethod = "buy";
String url = urlBase + apiMethod;
The above is fake obviously, but the point is I'm using simple string concats.
Is this the best practice? I'm relatively new to Java. Should I be building a URL object instead?
Thanks
if you have a base path which needs some additional string to be added to it you have 2 options:
First is, using String.format():
String baseUrl = "http:/api/controller/%s"; // note the %s at the end
String apiMethod = "buy";
String url = String.format(baseUrl, apiMethod);
Or using String.replace():
String baseUrl = "http:/api/controller/{apiMethod}";
String apiMethod = "buy";
String url = baseUrl.replace("\\{apiMethod}", apiMethod);
The nice thing about both answers is, that the string that needs to be inserted, doesn't have to be at the end.
If you are using jersey-client. The following would be the best practice to access the subresources without making the code ugly
Resource: /someApp
Sub-Resource: /someApp/getData
Client client = ClientBuilder.newClient();
WebTarget webTarget = client.target("https://localhost:7777/someApp/").path("getData");
Response response = webTarget.request().header("key", "value").get();
If you are using plain Java, it's better to use dedicated class for URL building which throws exception if provided data are invalid in semantic way.
It has various constructors, you can read about it here.
Example
URL url = new URL(
"http",
"stackoverflow.com",
"/questions/50989746/creating-a-url-using-java-whats-the-best-practive"
);
System.out.println(url);

URL wont open file:\C filepath in Java

I need to open a filename using a URL(java.net.URL) as below:
file:/C:/RAdev/Basic/src/test/resources/xml Data/test
dir/app-config-seed-data.xml
I've the following java code to read
fileURL = new File(filePath).toURI().toURL();
is = fileURL.openStream();
Since windows can access file:\, even URL should be able to open the same.
Workaround used for now:
public static final String FILE_URL_PREFIX = "file:";
if (filePath.contains(FILE_URL_PREFIX)) {
filePath = filePath.replaceAll("file:/", "");
System.out.println("Modified filepath - " + filePath);
}
fileURL = new File(filePath).toURI().toURL();
is = fileURL.openStream();
Is the above workaround needed, please let me know if there is another way to reap the benefits of URL accessing. I'm new to URL/URI in java, help is really appreciated.
Thanks.
file:/C:/ is not a valid file url. Try starting your URLs with file://C:/.
Additionally, the File(String) constructor does not take a URL, it takes a local file path. If you have a URL as a string that you want to parse, use the URL(String) constructor:
URL fileURL = new URL("file://C:/RAdev/Basic/src/test/resources/xml Data/test dir/app-config-seed-data.xml");
is = fileURL.openStream();
Adding the below implementation on top of Darth Android suggestion worked:
URL url = new URL(filePath);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(),
url.getPort(), url.getPath(), url.getQuery(),
url.getRef());
URL fileURL = uri.toURL();
InputStream is = fileURL.openStream();

Why passing a string to URI throws exception?

I have a code like this :
String previousUrl = "http://localhost:8080/abc.html?xyz=hbkbkj|kjbjkbkj kjbkj";
URL url = new URL(previousUrl);
URI uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), url.getRef());
Now this code works perfectly. And i get the desired URI.
But if I pass the previousUrl to URI constructor then it throws exception. I want to know the reason.
String previousUrl = "http://localhost:8080/abc.html?xyz=hbkbkj|kjbjkbkj kjbkj";
URI uri = new URI(previousUrl);
Thanks.
It already tells you the reason! There's an invalid character in the url:
java.net.URISyntaxException: Illegal character in query at index 41: http://localhost:8080/abc.html?xyz=hbkbkj|kjbjkbkj kjbkj
So the character | can't be processed! Therefore you'll have to create an URL before passing the information to the URI constructor (like you already did successfully)
You could also try to replace all the characters that can't be processed with their % equivalent:
new URI(previousUrl.replaceAll(" ", "%20").replaceAll("\\|", "%7C"));
But you'll have to add more of these replacements every time you meet a new caracter that can't be processed!

Java - how to encode URL path for non Latin characters

Currently there is final URL url = new URL(urlString); but I run into server not supporting non-ASCII in path.
Using Java (Android) I need to encode URL from
http://acmeserver.com/download/agc/fcms/儿子去哪儿/儿子去哪儿.png
to
http://acmeserver.com/download/agc/fcms/%E5%84%BF%E5%AD%90%E5%8E%BB%E5%93%AA%E5%84%BF/%E5%84%BF%E5%AD%90%E5%8E%BB%E5%93%AA%E5%84%BF.png
just like browsers do.
I checked URLEncoder.encode(s, "UTF-8"); but it also encodes / slashes
http%3A%2F%2acmeserver.com%2Fdownload%2Fagc%2Ffcms%2F%E5%84%BF%E5%AD%90%E5%8E%BB%E5%93%AA%E5%84%BF%2F%E5%84%BF%E5%AD%90%E5%8E%BB%E5%93%AA%E5%84%BF.png
Is there way to do it simply without parsing string that the method gets?
from http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars
B.2.1 Non-ASCII characters in URI attribute values Although URIs do
not contain non-ASCII values (see [URI], section 2.1) authors
sometimes specify them in attribute values expecting URIs (i.e.,
defined with %URI; in the DTD). For instance, the following href value
is illegal:
...
We recommend that user agents adopt the following convention for
handling non-ASCII characters in such cases:
Represent each character in UTF-8 (see [RFC2279]) as one or more
bytes.
Escape these bytes with the URI escaping mechanism (i.e., by
converting each byte to %HH, where HH is the hexadecimal notation of
the byte value).
You should just encode the special characters and the parse them together. If you tried to encode the entire URI then you'd run into problems.
Stick with:
String query = URLEncoder.encode("apples oranges", "utf-8");
String url = "http://stackoverflow.com/search?q=" + query;
Check out this great guide on URL encoding.
That being said, a little bit of searching suggests that there may be other ways to do what you want:
Give this a try:
String urlStr = "http://abc.dev.domain.com/0007AC/ads/800x480 15sec h.264.mp4";
URL url = new URL(urlStr);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();
(You will need to have those spaces encoded so you can use it for a request.)
This takes advantage of a couple features available to you in Android
classes. First, the URL class can break a url into its proper
components so there is no need for you to do any string search/replace
work. Secondly, this approach takes advantage of the URI class
feature of properly escaping components when you construct a URI via
components rather than from a single string.
The beauty of this approach is that you can take any valid url string
and have it work without needing any special knowledge of it yourself.
final URL url = new URL( new URI(urlString).toASCIIString() );
worked for me.
I did it as below, which is cumbersome
//was: final URL url = new URL(urlString);
String asciiString;
try {
asciiString = new URL(urlString).toURI().toASCIIString();
} catch (URISyntaxException e1) {
Log.e(TAG, "Error new URL(urlString).toURI().toASCIIString() " + urlString + " : " + e1);
return null;
}
Log.v(TAG, urlString+" -> "+ asciiString );
final URL url = new URL(asciiString);
url is later used in
connection = (HttpURLConnection) url.openConnection();

How to use java.net.URI

I've tried to use java.net.URI to manipulate query strings but I failed to even on very simple task like getting the query string from one url and placing it in another.
Do you know how to make this code below work
URI sample = new URI("test?param1=x%3D1");
URI uri2 = new URI(
"http",
"domain",
"/a-path",
sample.getRawQuery(),
sample.getFragment());
Call to uri2.toASCIIString() should return: http://domain/a-path?param1=x%3D1
but it returns: http://domain/a-path?param1=x%253D1 (double encoding)
if I use getQuery() instead of getRawQuery() the query string is not encoded at all and the url looks like this: http://domain/a-path?param1=x=1
The problem is that the second constructor will encode the query and fragment using URL encoding. But = is a legal URI character, so it will not encode that for you; and % is not a legal URI character, so it will encode it. That's exactly the opposite of what you want, in this case.
So, you can't use the second constructor. Use the first one, by concatenating the parts of the string together yourself.
Could you wrap the call to getQuery() with a call to java.net.URLEncoder.encode(String)?
URI sample = new URI("test?param1=x%3D1");
URI uri2 = new URI(
"http",
"domain",
"/a-path",
URLEncoder.encode(sample.getQuery(), "UTF-8"),
sample.getFragment());

Categories