-
온라인 자바 컴파일러 만들기 (Judge0 API)Project 2024. 7. 19. 09:50
Judge0 - Where code happens.
Robust, scalable, and open-source online code execution system.
judge0.com
온라인 자바 컴파일러를 만들어 보고 싶었다. 찾아 보니 사용자가 입력한 코드를 컴파일해주는 Judge0 API가 이미 있어서 사용해보기로 했다. 위 사이트로 접속하여 다음 단계를 밟으면 API 키를 발급 받을 수 있다. 무료 버전을 사용하면 하루에 50개의 요청만 가능한 것 같다.
1. Get Started
2. Subscribe
3. Start Free Plan
4. API 키 확인
스프링 부트 프로젝트 생성 - build.gradle
plugins { id 'java' id 'org.springframework.boot' version '3.3.1' id 'io.spring.dependency-management' version '1.1.5' } group = 'project' version = '0.0.1-SNAPSHOT' java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-webflux' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' if (isAppleSilicon()) { runtimeOnly("io.netty:netty-resolver-dns-native-macos:4.1.94.Final:osx-aarch_64") } } def isAppleSilicon() { return System.getProperty("os.name") == "Mac OS X" && System.getProperty("os.arch") == "aarch64" } tasks.named('test') { useJUnitPlatform() }
CompilerController
@Controller public class CompilerController { private final WebClient webClient; public CompilerController(WebClient.Builder webClientBuilder, @Value("${apiKey}") String key) { this.webClient = webClientBuilder .baseUrl("https://judge0-ce.p.rapidapi.com") .defaultHeader("x-rapidapi-key", key) .defaultHeader("x-rapidapi-host", "judge0-ce.p.rapidapi.com") .build(); } @GetMapping("/") public String index(Model model) { String defaultCode = """ public class Main { public static void main(String[] args) { System.out.println("Hello, World!"); } } """; model.addAttribute("sourceCode", defaultCode); return "index"; } @PostMapping("/compile") public Mono<ResponseEntity<Map<String, String>>> compileCode(@RequestBody Map<String, String> requestBody) { String sourceCode = requestBody.get("sourceCode"); String encodedSourceCode = Base64.getEncoder().encodeToString(sourceCode.getBytes()); Map<String, String> requestPayload = new HashMap<>(); requestPayload.put("language_id", "62"); // Java requestPayload.put("source_code", encodedSourceCode); requestPayload.put("stdin", ""); return this.webClient.post() .uri("/submissions?base64_encoded=true&wait=false") .contentType(MediaType.APPLICATION_JSON) .bodyValue(requestPayload) .retrieve() .bodyToMono(Map.class) .flatMap(response -> { String token = (String) response.get("token"); return checkResult(token); }) .map(result -> { Map<String, String> responseMap = new HashMap<>(); StringBuilder output = new StringBuilder(); String stdout = (String) result.get("stdout"); String stderr = (String) result.get("stderr"); String compileOutput = (String) result.get("compile_output"); String message = (String) result.get("message"); if (stdout != null) { output.append(new String(Base64.getDecoder().decode(stdout))); } if (stderr != null) { output.append(new String(Base64.getDecoder().decode(stderr))); } if (compileOutput != null) { output.append(new String(Base64.getDecoder().decode(compileOutput))); } if (message != null) { output.append(message); } responseMap.put("output", output.toString()); return ResponseEntity.ok(responseMap); }) .onErrorResume(e -> { Map<String, String> responseMap = new HashMap<>(); responseMap.put("output", "An error occurred: " + e.getMessage()); return Mono.just(ResponseEntity.ok(responseMap)); }); } private Mono<Map> checkResult(String token) { return this.webClient.get() .uri("/submissions/" + token + "?base64_encoded=true") .retrieve() .bodyToMono(Map.class); } }
index.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Online Java Compiler</title> <link rel="icon" href="/icon/duke.ico" type="image/x-icon"> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script> $(document).ready(function() { $("form").on("submit", function(event) { event.preventDefault(); $.ajax({ type: "POST", url: "/compile", contentType: "application/json", data: JSON.stringify({ sourceCode: $("#sourceCode").val() }), success: function(response) { $("#output").text(response.output); }, error: function() { $("#output").text("An error occurred while compiling the code."); } }); }); }); </script> </head> <body> <h1>Online Java Compiler!!</h1> <form> <textarea id="sourceCode" name="sourceCode" rows="20" cols="80" placeholder="Enter your Java code here" th:text="${sourceCode}"></textarea><br/> <button type="submit">Compile</button> </form> <h2>Result:</h2> <pre id="output" th:text="${output}"></pre> </body> </html>
'Project' 카테고리의 다른 글
프로젝트에 JWT 인증/인가 적용하기 (0) 2024.08.30 [팀 프로젝트] LMS 웹 사이트 만들기 (Learn Hub) (1) 2024.08.28 구글 reCAPTCHA v2, v3 사용해보기 🤖 (0) 2024.08.15 [팀 프로젝트] 애니메이션 커뮤니티 웹 사이트 만들기 (Who's Ducking) (0) 2024.07.07 [팀 프로젝트] 헬스장 키오스크 만들기 (JavaGym) (0) 2024.04.29