- build.gradle
// webflux
implementation 'org.springframework.boot:spring-boot-starter-webflux'
- WebClient 사용할 class
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import reactor.core.publisher.Mono;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
@Slf4j
@Component
public class CitationItemProcessor implements ItemProcessor<Paper, Paper> {
private final WebClient webClient;
@Value("${scopus.api-key}")
private String openAiToken;
@Autowired
public CitationItemProcessor(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder.build();
}
@Override
public Paper process(Paper paper) {
try {
log.info(" ************ Processing paper with DOI: {} ************ ", paper.getDoi());
String doi = paper.getDoi();
String url = "<https://api.elsevier.com/content/abstract/doi/>" + doi;
Mono<String> responseMono = webClient.get()
.uri(url)
.header("X-ELS-APIKey", openAiToken)
.retrieve()
.bodyToMono(String.class);
String response = responseMono.block();
if (response != null) {
if (response.contains("RESOURCE_NOT_FOUND")) {
// scopus에 등록된 논문이 아닐 경우,
return paper;
} else if (response.contains("<citedby-count>")) {
// 정상 응답 받은 경우,
int total = parseCitationFromResponse(response);
log.info(" ************ Response received citedby-count: {} ************ ", total);
if (total > 0) {
paper.updateCitation(total);
}
} else {
// 응답이 예상치 못한 형태일 경우,
log.error(" ************ Unexpected response: {} ************ ", response);
}
}
} catch (Exception e) {
// try 블록 내에서 예외가 발생한 경우,
log.error(" ************ An error occurred while processing the paper: ", e);
}
return paper;
}
private int parseCitationFromResponse(String response) throws Exception {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(response)));
NodeList nodeList = doc.getElementsByTagName("citedby-count");
if (nodeList.getLength() > 0) {
String citedByCount = nodeList.item(0).getTextContent();
return Integer.parseInt(citedByCount);
} else {
log.warn(" ************ No 'citedby-count' tag found in the XML response. ************ ");
return 0;
}
} catch (Exception e) {
log.error(" ************ Error while parsing XML response: ", e);
return 0;
}
}
}