Illegal argument exception: Host name may not be null - illegalargumentexception

Illegal Argument exception: Host name may not be null
I am getting this error at last line
HttpResponse httpResponse = httpClient.execute(get)
I tried all possible solutions like encoding url if contains space etc.. and variables like name and phone all these are from my calling class
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
String time = sdf.format(cal.getTime());
String value="Dish:"+cr.getString(1)+"Quantity:"+cr.getInt(2)+"Price"+cr.getString(3).trim()+"TotalPrice:"+Integer.parseInt(cr.getString(3))*cr.getInt(2)+"Address:"+address+"CustomerName:"+name+"RestaurantName:"+cr.getString(4).trim();
url = "http:twowaits.in/orderapp.php?name="+name.trim()+"&no="+phone.trim()+"&add="+URLEncoder.encode(address, "UTF-8")+"&rest="+URLEncoder.encode(cr.getString(4),"UTF-8")+"&cost="+cr.getString(3).trim()+"&value="+URLEncoder.encode(value, "UTF-8")+"&dishname="+cr.getString(1).trim()+"&qty="+cr.getInt(2)+"&time="+time;
HttpGet get = new HttpGet(url);
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse httpResponse = httpClient.execute(get);

You forgot the // after http:.
url = "http://twowaits.in/......
The stacktrace says it all; your URL does not contain a hostname (a domain name or IP). That means you either didn't supply one, or you made a formatting error somewhere so the URL couldn't be parsed properly. In this case, you did supply a domain name, it's just that the URL isn't formatted properly.
Note that the Apache HttpClient that you are using is deprecated and Google recommends you switch to something else, e.g. URLConnection. Square's OKHttp is also a great alternative.
Also, you might want to try and make your code more readable. Using a builder pattern for your URI would probably help a lot. See URIBuilder or you could just use a StringBuilder.

Related

Spring-test cannot set #RequestPart. It always send it as null

I cannot test Controller by using mockMvc in spring-test. I want to know right way to test API with #RequestPart.
The method to test is this.
#RequestMapping(value = "/", method = RequestMethod.POST)
public ResponseEntity<Object> replaceFile(
#RequestPart("files") Map<String, Object> files,
#RequestPart("fileKey") String fileKey)
And to test I build a mock request like below.
MockMultipartFile blob = new MockMultipartFile("files", files.getBytes());
MockMultipartFile key = new MockMultipartFile("fileKey", fileKey.getBytes());
mockMvc.perform(fileUpload("/")
.file(blob)
.file(key))
.andDo(print())
.andExpect(status().isOk());
As you can see, I used fileUpload. But in past time, I tried to use post with content or requestAttr because all of them didn't work.
I think current code is the closest to answer among I tried, but can't get closer anymore.
The weird thing is, the real in-use API is almost same with them.
In client side, user sent a new FormData() object to request and server can get data properly.
The server side code is below.
#RequestMapping(value = "/api/{variable}", method = RequestMethod.POST)
public ResponseEntity<Object> apiMethod(
#PathVariable int variable,
#RequestPart("dto1") DTO1 dto1,
#RequestPart("dto2") DTO2 dto2,
#RequestPart("file") Map<String, Object> file)
"file" part consists of "file name" key and its blob value encoded base64.
For example, {"hello.txt": "SGVsbG8gd29ybGQh"}
What I want to know - Right way to test API with #RequestPart
What I tried
method - fileUpload / data - file, content, requestAttr but they send null.
method - post / data - file, content, requestAttr but they throw MultipartException.
Restriction - Cannot use multipart because the system is using a low version of Spring.
Thanks!
Thanks to #borino who commented to my question, I got the clue of problem.
It is certain to use fileUpload for testing API with #RequestPart arguments.
In that case, it caused from content type.
I declared MockMultipartFile without contentType.
MockMultipartFile blob = new MockMultipartFile("files", files.getBytes());
MockMultipartFile key = new MockMultipartFile("fileKey", fileKey.getBytes());
But the arguments of API have a type, Map<String,Object> and String each.
As #borino said to me, I changed constructor of MockMultipartFile to make sure contentType, and it works!
MockMultipartFile blob = new MockMultipartFile("files", "", "application/json", files.getBytes());
MockMultipartFile key = new MockMultipartFile("fileKey", "", "application/json", fileKey.getBytes());
Just add contentType when you have a problem like me. Thanks!

How to stop ASP .NET from JSONifying JSON

I am currently trying to wrap an internal API and make it external. To do so, I am trying to relay the JSON responses from the internal API and send that exact response when someone makes a get request. Instead, ASP .NET is JSONifying that son and adding extra back slashes as escape characters (when in fact those slashes are really escape slashes put in by the internal api).
How can i get it so asp does not jsonify the string
You can write your json data directly to response and set right content headers.
public HttpResponseMessage GetData()
{
var json = "\"value\": \"da\\ta\"";
var resp = Request.CreateResponse(HttpStatusCode.OK);
resp.Content = new StringContent(json);
resp.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
resp.Content.Headers.ContentEncoding = //your json encoding, you can get it from response inner API
return resp;
}

How can I catch a pound sign(#) from URL with multiple values in ASHX files

This is my ASHX File where I am catching multiple parameters from request URL using httpcontext, and it is working properly but when I am including a Hash(#) value in Text parameter through the URL. It is not taking the value of FLOW which is another parameter(next to Text parameter).
So it is working for:
http://localhost:10326/ussd.ashx?user=MSL&pass=MSL663055&tid=65506&msisdn=8801520101525&text=***3333**&flow=begin&momt=mo
And it is not working for:
http://localhost:10326/ussd.ashx?user=MSL&pass=MSL663055&tid=65506&msisdn=8801520101525&text=***3333#**&flow=begin&momt=mo
My ASHX files:
public void ProcessRequest(HttpContext context)
{
HttpRequest httpRequest = context.Request;
string user = httpRequest.QueryString["user"].ToString();
string pass = httpRequest.QueryString["pass"].ToString();
string tid = httpRequest.QueryString["tid"].ToString();
string msisdn = httpRequest.QueryString["msisdn"].ToString();
string text = httpRequest.QueryString["text"].ToString();
flow = httpRequest.QueryString["flow"].ToString();
HttpContext.Current.Session["user"] = user;
HttpContext.Current.Session["pass"] = pass;
HttpContext.Current.Session["tid"] = tid;
HttpContext.Current.Session["msisdn"] = msisdn;
HttpContext.Current.Session["text"] = text;
HttpContext.Current.Session["flow"] = flow;
You need to URI encode your parameter values before they are added to the URL. This way the server will not get confused by unsafe characters such as '#' which has its own meaning when included as part of a URL. See RFC 3986 Section 2.
See Encode URL in JavaScript as an example of how to encode the sent data using JavaScript. Whatever is sending the data in the URL will need to do the encoding. There is not much you can do once the request has reached the server. Without knowing how your URL is being created, I can't offer much more.
In short: the problem is with your client code not your ASHX file.

Get string from current URL

I am writing an asp.net MVC Application. I have the application send a request to FreeAgent and if the request is successful a code is returned in the redirect of the URL.
For example this is a copy of a successful URL.
{
http://localhost:3425/FreeAgent/Home?code=144B2ymEKw3JfB9EDPIqCGeWKYLb9IKc-ABI6SZ0o&state=
}
They have added the ?code=144B2ymEKw3JfB9EDPIqCGeWKYLb9IKc-ABI6SZ0o&state= to my URL
I need the bit after the ?code= and before &state=
I can use this to get the URL
string code = Request.Url.AbsoluteUri;
but I need help extracting the code from this
edit:
The code will be different each time it is run
You can use the System.Uri and System.Web.HttpUtility classes
string uri = "http://localhost:3425/FreeAgent/Home?code=144B2ymEKw3JfB9EDPIqCGeWKYLb9IKc-ABI6SZ0o&state=";
string queryString = new System.Uri(uri).Query;
var queryDictionary = System.Web.HttpUtility.ParseQueryString(queryString);
Then the value of the code query parameter will be available in queryDictionary["code"]

Find application root URL without using ~

I need to construct the URL of a page in a String, to send it an email (as part of an email verification system). If i use the ~ symbol to denote the app root, it is taken literally.
The app will be deployed on a server on three different sites (on different ports) and each site can be accessed via 2 different URLs (one for LAn and one for internet).
So hardcoding the URL is out of question. I want to construct the url to verify.aspx in my application
Please help
You need this:
HttpContext.Current.Request.ApplicationPath
It's equivalent to "~" in a URL.
http://msdn.microsoft.com/en-us/library/system.web.httprequest.applicationpath.aspx
Unfortunately none of the methods listed generated the full url starting from http://---.
So i had to extract these from request.url. Something like this
Uri url=HttpContext.Current.Request.Url;
StringBuilder urlString = new StringBuilder();
urlString.Append(url.Scheme);
urlString.Append("://");
urlString.Append(url.Authority);
urlString.Append("/MyDesiredPath");
Can someone spot any potential problems with this?
Try:
HttpRequest req = HttpContext.Current.Request;
string url = req.Url.GetComponents(UriComponents.SchemeAndServer, UriFormat.SafeUnescaped)
+ ((req.ApplicationPath.Length > 1) ? req.ApplicationPath : "");
You need to put the URL as part of your web application's configuration. The web application does not know how it can be reached from the outside world.
E.g. consider a scenario where there's multiple proxies and load balancers in front of your web server... how would the web server know anything but its own IP?
So, you need to configure each instance of your web application by adding the base URL e.g. as an app setting in its web.config.
You can use HttpRequest.RawURL (docs here)property and base your URL on that, but if you are behind any kind of redirection, the RawURL may not reflect the actual URL of your application.
I ended up with this. I take the request url, and use the position of Request.ApplicationRoot to discover the left part of the uri. Should work with applications hosted in a virtual directory "/example" or in the root "/".
private string GetFullUrl(string relativeUrl)
{
if (string.IsNullOrWhiteSpace(relativeUrl))
throw new ArgumentNullException("relativeUrl");
if (!relativeUrl.StartsWith("/"))
throw new ArgumentException("url should start with /", "relativeUrl");
string current = Request.Url.ToString();
string applicationPath = Request.ApplicationPath;
int applicationPathIndex = current.IndexOf(applicationPath, 10, StringComparison.InvariantCultureIgnoreCase);
// should not be possible
if (applicationPathIndex == -1) throw new InvalidOperationException("Unable to derive root path");
string basePath = current.Substring(0, applicationPathIndex);
string fullRoot = string.Concat(
basePath,
(applicationPath == "/") ? string.Empty : applicationPath,
relativeUrl);
return fullRoot;
}
This has always worked for me:
string root = Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, "");

Resources