#java #exception-handling #try-catch #try-with-resources
#java #исключение #попытка-перехват #попытка с ресурсами
Вопрос:
Я хочу реализовать код для обработки запросов POST с использованием попытки с ресурсами.
Ниже приведен мой код:
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();
}
У меня есть следующие проблемы с кодом:
- Как ввести условные операторы в try с ресурсами для вышеупомянутого сценария?
- Есть ли способ передать соединение в попытке с ресурсами? (Это может быть сделано с использованием вложенных блоков try-catch, поскольку URL и HttpConnection не могут быть автоматически закрыты, что само по себе не является совместимым решением)
- Является ли использование try с ресурсами для решения вышеуказанной проблемы лучшим подходом?
Ответ №1:
Попробуйте это.
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()
это лямбда-выражение, которое выполняется con.disconnect()
на конечном этапе инструкции try.
Комментарии:
1. Это нормально для большинства моих запросов. Но является ли использование вложенной попытки хорошим подходом? Я имею в виду, что мой код отлично работает с try-catch-finally. В чем преимущество такого подхода?
2. @Chinmayjain Если вы / кто-то скопируете код, он будет отображаться как один монолитный блок.
3. Преимущество заключается в надежности. Любое закрытие может вызвать исключение IOException. Вы также можете переместить код в частные методы (например, writeQuery и readResponse), чтобы он выглядел лучше 😉
Ответ №2:
1. Вы также можете использовать условные операторы внутри try
инструкции with resources. К сожалению, вы должны определить новую переменную для этого блока и не можете использовать предопределенную переменную. (переменная in
в вашем коде)
try (BufferedReader in = (responseCode >= 400 ? new BufferedReader(new InputStreamReader(con.getErrorStream())) : new BufferedReader(new InputStreamReader(con.getInputStream())))) {
// your code for getting string data
}
2: Я не уверен, что HttpUrlConnection
это AutoCloseable
так, поэтому было бы неплохо вызвать disconnect()
самостоятельно. Я открыт для любого предложения по этому вопросу.
3: try
with resources определенно поможет вам в управлении ресурсами. Но если вы уверены, что правильно освобождаете ресурсы после использования, тогда ваш код в порядке.