중복 코드가 많은 두 가지 방법이 있지만 고유 한 비트가 전체적으로 발생하는 클래스가 있습니다. 내 연구에서 "Execute around method"패턴을 수행해야한다고 생각하지만, 복제 할 수없는 코드를 사용하는 것처럼 보이는 리소스를 찾을 수 없습니다.고유 한 부분이 루프/try-catch 내에있을 때 코드 중복 방지
나는 아래에 붙여 넣은 두 가지 방법 인 apiPost와 apiGet을 가지고 있습니다.
/**
* Class that handles authorising the connection and handles posting and getting data
*
* @version %I%, %G%
* @since 1.0
*/
public class CallHandler {
private static PropertyLoader props = PropertyLoader.getInstance();
final static int MAX = props.getPropertyAsInteger(props.MAX_REQUESTS);
private final Logger log = LoggerFactory.getLogger(CallHandler.class);
private final static String POST = "POST";
private final static String GET = "GET";
/**
* Makes a POST call to the API URL provided and returns the JSON response as a string
* http://stackoverflow.com/questions/15570656/how-to-send-request-payload-to-rest-api-in-java
*
* @param urlString the API URL to send the data to, as a string
* @param payload the serialised JSON payload string
* @return and value returned as a JSON string, ready to be deserialised
*/
public String apiPost(String urlString, String payload) {
boolean keepGoing = true;
int tries = 0;
String line;
StringBuilder jsonString = new StringBuilder();
log.debug("Making API Call: {}", urlString);
while (keepGoing && tries < MAX) {
tries++;
try {
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// UNIQUE CODE START
prepareConnection(connection, POST);
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
writer.write(payload);
writer.close();
// UNIQUE CODE END
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = br.readLine()) != null) {
jsonString.append(line);
}
br.close();
connection.disconnect();
keepGoing = false;
} catch (Exception e) {
log.warn("Try #{}. Error posting: {}", tries, e.getMessage());
log.warn("Pausing for 1 second then trying again...");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException f) {
log.warn("Sleeping has been interrupted: {}", f.getMessage());
}
}
}
return jsonString.toString();
}
/**
* Makes a GET call to the API URL provided and returns the JSON response as a string
* http://stackoverflow.com/questions/2793150/using-java-net-urlconnection-to-fire-and-handle-http-requests
*
* @param urlString the API URL to request the data from, as a string
* @return the json response as a string, ready to be deserialised
*/
public String apiGet(String urlString) {
boolean keepGoing = true;
int tries = 0;
String line;
StringBuilder jsonString = new StringBuilder();
log.debug("Making API Call: {}", urlString);
while (keepGoing && tries < MAX) {
tries++;
try {
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// UNIQUE CODE START
prepareConnection(connection, GET);
connection.connect();
// UNIQUE CODE END
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = br.readLine()) != null) {
jsonString.append(line);
}
br.close();
connection.disconnect();
keepGoing = false;
} catch (Exception e) {
log.warn("Try #{}. Error getting from API: {}", tries, e.getMessage());
log.warn("Pausing for 1 second then trying again...");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException f) {
log.warn("Sleeping has been interrupted: {}", f.getMessage());
}
}
}
return jsonString.toString();
}
/**
* Prepares the HTTP Url connection depending on whether this is a POST or GET call
*
* @param connection the connection to prepare
* @param method whether the call is a POST or GET call
*/
private void prepareConnection(HttpURLConnection connection, String method) {
String charset = "UTF-8";
try {
connection.setRequestMethod(method);
if (method.equals(GET)) {
connection.setRequestProperty("Accept-Charset", charset);
} else if (method.equals(POST)) {
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json; charset=" + charset);
}
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("Authorization", "Bearer " + apiKey);
} catch (Exception e) {
log.error("Error preparing HTTP URL connection: {}", e.getMessage());
throw new RuntimeException(e.getMessage());
}
}
나는 여기에 코드 중복을 절약하기 위해 "실행 방법의 주위에"패턴을 사용할 수 : 고유 섹션의 시작 및 종료 어디 보여주는 의견이 방법의 고유 한 부분을 감싸거야? 그렇다면 누군가이 코드를 사용하도록이 코드를 리팩터링하는 방법을 알아낼 수 있습니다. 이것이 잘못된 길이라면 누군가가 현명한 대안을 제시 할 수 있을까요?
감사에 대한 : 혹시
java 8
과 람다를 사용할 수없는 경우, 당신은 익명의 클래스를 생성 항상을 전환 할 수 있습니다 회신 @Andremoniy 나는 그것을 이해하기 시작하고 있다고 생각한다. (비록 나는 Lambda에 대해 약간의 독서를해야한다.) 어쨌든 람다 없이는 Google App Engine 용으로 개발 중이며 Java 8을 지원하지 않는다고 생각합니다. S – SBmore@SBmore 제 편집을보고 익명 클래스를 사용할 수 있습니다 – Andremoniy
감사합니다. 너무 많은 @Areremoniy, 이것은 크게 도움이되었고 나는 많은 것을 배웠다. – SBmore