I want to implement the code for handling POST requests using try with resources.
Following is my code:
public static String sendPostRequestDummy(String url, String queryString) {
log.info("Sending 'POST' request to URL : " + url);
log.info("Data : " + queryString);
BufferedReader in = null;
HttpURLConnection con = null;
StringBuilder response = new StringBuilder();
try{
URL obj = new URL(url);
con = (HttpURLConnection) obj.openConnection();
// add request header
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "Mozilla/5.0");
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
con.setRequestProperty("Content-Type", "application/json");
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(queryString);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
log.info("Response Code : " + responseCode);
if (responseCode >= 400)
in = new BufferedReader(new InputStreamReader(con.getErrorStream()));
else
in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
}catch(Exception e){
log.error(e.getMessage(), e);
log.error("Error during posting request");
}
finally{
closeConnectionNoException(in,con);
}
return response.toString();
}
I have the following concerns for the code:
How to introduce conditional statements in try with resources for the above scenario?
Is there a way to pass on the connection in try with resources? (It can be done using nested try-catch blocks since URL and HTTPConnection is not AutoCloseable, which itself is not a compliant solution)
Is using try with resources for the above problem is a better approach?
Try this.
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
try (AutoCloseable conc = () -> con.disconnect()) {
// add request headers
try (DataOutputStream wr = new DataOutputStream(con.getOutputStream())) {
wr.writeBytes(queryString);
}
int responseCode = con.getResponseCode();
try (InputStream ins = responseCode >= 400 ? con.getErrorStream() : con.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(ins))) {
// receive response
}
}
() -> con.disconnect() is a lambda expression which execute con.disconnect() at finally stage of the try statement.
1: You can use conditional statements inside try with resources statement also. Unfortunately you have to define new variable for this block and cannot use a predefined variable. ( variable in in your code)
try (BufferedReader in = (responseCode >= 400 ? new BufferedReader(new InputStreamReader(con.getErrorStream())) : new BufferedReader(new InputStreamReader(con.getInputStream())))) {
// your code for getting string data
}
2: I'm not sure HttpUrlConnection is AutoCloseable, So it might be a good idea to call the disconnect() yourself. I'm open to any suggestion on this one.
3: try with resources will definitely help you in managing the resources. But if you're confident that you're releasing the resources properly after use, then your code is fine.
Related
I've built java code to use satang "orders/user" api.
But got 405 error.
Please help me.
I've built placeLimitOrder() function.
And used successfully.
Then getUserOrders() function also made with same rult.
But this function got 405 error.
I can't find the reason.
public String getUserOrders (String pair,String limit,String offset,String status,String side)
{
String req="limit="+limit+"&offset="+offset+"&pair="+pair+"&side="+side+"&status="+status;
String operation="orders/user";
String signature=getSignature(req);
URL url = new URL(baseUrl+operation);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setDoOutput( true );
con.setInstanceFollowRedirects( false );
con.setRequestProperty("Authorization", "TDAX-API "+this.key);
con.setRequestProperty("Signature",signature);
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("charset", "utf-8");
con.setRequestProperty("User-Agent", "java client");
con.setUseCaches( false );
JsonObject obj=new JsonObject();
obj.addProperty("limit", limit);
obj.addProperty("offset", offset);
obj.addProperty("pair", pair);
obj.addProperty("side", side);
obj.addProperty("status", status);
String json=obj.toString();
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(json);
wr.flush();
wr.close();
int responseCode=con.getResponseCode();
if(responseCode!=HttpURLConnection.HTTP_OK){
throw new BadResponseException(responseCode);
}
BufferedReader rd = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuilder result = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
result.append(line);
}
rd.close();
return result.toString();
}
Following code working well.
I can't find the reason.
public String placeLimitOrder(String amount,String pair,String price,String side) throws IOException, BadResponseException
{
Long lnonce=new Date().getTime();
String nonce=lnonce.toString();
String req="amount="+amount+"&nonce="+nonce+"&pair="+pair+"&price="+price+"&side="+side+"&type=limit";
String operation="orders/";
String signature=getSignature(req);
URL url = new URL(baseUrl+operation);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setDoOutput( true );
con.setInstanceFollowRedirects( false );
con.setRequestProperty("Authorization", "TDAX-API "+this.key);
con.setRequestProperty("Signature",signature);
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("charset", "utf-8");
con.setRequestProperty("User-Agent", "java client");
con.setUseCaches( false );
JsonObject obj=new JsonObject();
obj.addProperty("amount", amount);
obj.addProperty("nonce", nonce);
obj.addProperty("pair", pair);
obj.addProperty("price", price);
obj.addProperty("side", side);
obj.addProperty("type", "limit");
String json=obj.toString();
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(json);
wr.flush();
wr.close();
int responseCode=con.getResponseCode();
if(responseCode!=HttpURLConnection.HTTP_OK){
throw new BadResponseException(responseCode);
}
BufferedReader rd = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuilder result = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
result.append(line);
}
rd.close();
return result.toString();
}
public String getUserOrders(String pair,String limit,String offset,String status,String side) throws IOException, BadResponseException
{
String req="limit="+limit+"&offset="+offset+"&pair="+pair+"&side="+side+"&status="+status;
String operation="orders/user?"+req;
String signature=getSignature("");
URL url = new URL(baseUrl+operation);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setDoOutput( true );
con.setInstanceFollowRedirects( false );
con.setRequestProperty("Authorization", "TDAX-API "+this.key);
con.setRequestProperty("Signature",signature);
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("charset", "utf-8");
con.setRequestProperty("User-Agent", "java client");
con.setUseCaches( false );
int responseCode=con.getResponseCode();
if(responseCode!=HttpURLConnection.HTTP_OK){
throw new BadResponseException(responseCode);
}
BufferedReader rd = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuilder result = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
result.append(line);
}
rd.close();
return result.toString();
}
So if you are trying to do GET to https://api.tdax.com/api/orders/user
Headers should include:
Signature
Authentication
Query Parameters:
pair
limit
offset
status
side
From your code, it looks like you have put everything to the Signature.
Link to API docs
This is what you should fix:
URL. It should look like:
https://api.tdax.com/api/orders/user?pair=pairValue&limit=limitValue&offset=... add all the parameters and insert values.
Change request method to GET
Double-check your headers (Signature, Authentication).
Error code 405 - "bad request", which means most likely your request URL is bad. After you will fix URL, you should be able to get a different response code like 403/401 which should indicate that something is wrong with signature or authentication. In the best-case scenario, you will get 200 and then try to parse the JSON response.
Also, I don't recommend you to use HttpURLConnection, Generally, it’s NOT recommended to use this class, because the codebase is very old and outdated, it may not supports the new HTTP/2 standard, in fact, it’s really difficult to configure and use this class. Please consider using OkHttp, Apache HttpClient or other libraries.
I have a node.js which waits for post with 2 parameters (name and pass):
app.post('/login.html', function (req, res) {
log.info(req.body);
userName = req.body.name;
pass = req.body.pass;
...
}
I'm trying to send post with the 2 parameters via simple java application, but I can't see that it arrive to the node.js.
what am I missing ?
The java code:
public static void main(String[] args) {
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL("http://83.63.118.111:31011/login.html");
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000);
urlConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
urlConnection.setConnectTimeout(10000);
urlConnection.setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
OutputStream os = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
String str = "name='root'&pass='123456'";
//System.out.print(str);
writer.write(str);
writer.flush();
Thread.sleep(100);
writer.close();
os.close();
}
Your code will close when start send data (send and stop)
You should wait it done.
Add code after writer.flush();
Example get response:
BufferedReader in = new BufferedReader(
new InputStreamReader(urlConnection.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
or just get responseCode:
int responseCode = urlConnection.getResponseCode();
Your program wait send request success or fail.
I think you use Thread.sleep(100); to wait send request, but it stop your Thread (don't send data to server)
Your code have req.body, Express.js don't have it, need use middleware body-parser.
public static String request(String httpUrl, String httpArg) {
BufferedReader reader = null;
String result = "";
StringBuffer sbf = new StringBuffer();
httpUrl = httpUrl + "?" + httpArg;
try {
URL url = new URL(httpUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("apikey", myAPpiKey);
conn.connect();
if (conn.getResponseCode() == 200) {
InputStream is = conn.getInputStream();
reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String strRead = null;
while ((strRead = reader.readLine()) != null) {
sbf.append(strRead);
sbf.append("\r\n");
}
reader.close();
result = sbf.toString();
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
Above code worked well on Android 5.1 and Android 6.0, and it returned correct result that I want. But when I ran these on Android 4.4, using the same params, it returned different result. I have tried several times, and attached debugger to the process. I found that the connection could be built successfully, and the ResponseCode was also 200.
I guess there must be something wrong with the HttpURLConnection params, so that the server returned different result. Did I set the params in a way that could work on Android 5.1 and 6.0 but not on 4.4? Can anybody tell me where did I do wrong?
Try below code:
URL url = new URL(httpUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setChunkedStreamingMode(0);
conn.setDoInput(true);
conn.setRequestMethod("GET");
conn.setRequestProperty("apikey", myAPpiKey);
if (conn.getResponseCode() == 200) {
InputStream is = conn.getInputStream();
.........
}
It works for me. Hope it will work.
I have two raspberry pi´s uploading content to a webpage from the same router, which occasionally makes them block access for each other. To prevent this in java, you would normally use threads and synchronize, wait/notify and all that - but how can you do that, when the applications don´t know about each others excistens? -
My code looks something like that - and works otherwise as expected.
public void sendStrings(String output) {
String url2 = "http://myhomepage.com";
HttpURLConnection connection = null;
try {
URL obj = new URL(url2);
connection = (HttpURLConnection) obj.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.connect();
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
writer.write(output);
writer.flush();
writer.close();
InputStream input = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String otherLine;
int responseCode = connection.getResponseCode();
}
catch (IOException e) {
} finally {
connection.disconnect();
}
}
update : this is a duplicate,
i'm building a Proxy-custom-tag with grails taglib, per default it makes a get-request, now i'm facing the problem, that it should be able to handle Post-requests too,#
and i'm able to check the request-method and conditionally set the openConnection method to post if necessary, but i dont know how to append the post-params to the request.
here 's my code so far
def wordpressContent = { attrs, body ->
def url
def requestMethod = request.getMethod()
def queryString = request.getQueryString()?'&'+request.getQueryString():''
def content
println "method :"+requestMethod
println "params == "+params // <- inside here are the post-parameters
url = grailsApplication.config.wordpress.server.url+attrs.pageName+'?include=true'+queryString
try {
content = url.toURL().openConnection().with { conn ->
if(requestMethod == 'POST'){
println "Its a POST"
conn.setRequestMethod("POST")
conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
// HOW to append the params here ?
}
readTimeout = 6000
if( responseCode != 200 ) {
throw new Exception( 'Not Ok' )
}
conn.content.withReader { r ->
r.text
}
}
}
catch( e ) {
println "exception : "+e
content="<div class='float' style='margin-top:10px;width:850px;background-color:white;border-radius:5px;padding:50px;'>Hier wird gerade gebaut</div>"
}
out << content
}
im very stuck here right now, i found answers saying to use this syntax
Writer wr = new OutputStreamWriter(conn.outputStream)
wr.write(postParams)
wr.flush()
wr.close()
but i dont know how to include that to my existing code,
for any hints thanks in advance
update: my solution was to build up the post-parameter-querystring by iterating over the params object in this pattern "xyz=zyx&abc=cba" and write it to the outputStream like above
// HTTP POST request
private void sendPost() throws Exception {
String url = "https://selfsolve.apple.com/wcResults.do";
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
//add request header
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", USER_AGENT);
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
String urlParameters = "sn=C02G8416DRJM&cn=&locale=&caller=&num=12345";
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + urlParameters);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
//print result
System.out.println(response.toString());
}
you are using grails so you can also use groovy HTTPBuilder like below
http://groovy.codehaus.org/modules/http-builder/doc/