In Grails web application, I am trying to post minutiae (finger print) byte array from applet to server using rest API.
This what i tried so for
private String post(String purl,String customerId, byte[] regMin1,byte[] regMin2) throws Exception {
StringBuilder parameters = new StringBuilder();
parameters.append("customerId=");
parameters.append(customerId);
parameters.append("®Min1=");
parameters.append(URLEncoder.encode(new String(regMin1),"UTF-8"));
parameters.append("®Min2=");
parameters.append(URLEncoder.encode(new String(regMin2),"UTF-8"));
URL url = new URL(purl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length",Integer.toString(parameters.toString().getBytes().length));
DataOutputStream wr = new DataOutputStream(connection.getOutputStream ());
wr.writeBytes(parameters.toString());
wr.flush();
wr.close();
BufferedReader in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
StringBuilder builder = new StringBuilder();
String aux = "";
while ((aux = in.readLine()) != null) {
builder.append(aux);
}
in.close();
connection.disconnect();
return builder.toString();
}
I can post regMin1, regMin2 successfully but fingerprint verification always failing. I doubt, am i posting correctly.
This looks like a very bad idea to me:
parameters.append(URLEncoder.encode(new String(regMin1),"UTF-8"));
...
parameters.append(URLEncoder.encode(new String(regMin2),"UTF-8"));
If regMin1
and regMin2
aren't actually UTF-8 text (and my guess is that they're not) you'll almost certainly be losing data here.
Don't treat arbitrary binary data as if it's encoded text.
Instead, convert regMin1
and regMin2
to base64 - that way you'll end up with ASCII characters which you can then decode on the server to definitely get the original binary data. You can use a URL-safe version of base64 to avoid having to worry about further encoding the result.
There's a good public domain base64 library you can use for this if you don't have anything else to hand. So for example:
parameters.append("®Min1=")
.append(Base64.encodeBytes(regMin1, Base64.URL_SAFE))
.append("®Min2=")
.append(Base64.encodeBytes(regMin2, Base64.URL_SAFE));
Note that you'd want to decode with the URL_SAFE
option as well - don't just try to decode it as "normal" base64 data.
(You might still want to convert this to a POST request, and you'd definitely have an easier time if you could use a better HTTP library, but they're slightly separate concerns.)
See more on this question at Stackoverflow