CodeJudgeClient.java 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package cn.seecoder.codejudge.client;
  2. import com.fasterxml.jackson.core.JsonProcessingException;
  3. import com.fasterxml.jackson.core.type.TypeReference;
  4. import com.fasterxml.jackson.databind.ObjectMapper;
  5. import com.fasterxml.jackson.databind.json.JsonMapper;
  6. import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
  7. import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
  8. import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
  9. import okhttp3.*;
  10. import org.slf4j.Logger;
  11. import org.slf4j.LoggerFactory;
  12. import javax.validation.constraints.NotNull;
  13. import java.io.IOException;
  14. import java.util.Objects;
  15. import java.util.Optional;
  16. import java.util.concurrent.TimeUnit;
  17. import java.util.function.Function;
  18. /**
  19. * @author kunduin
  20. */
  21. public class CodeJudgeClient implements CodeJudgeApi {
  22. private final Logger logger = LoggerFactory.getLogger(getClass());
  23. private final OkHttpClient client;
  24. private final ObjectMapper mapper;
  25. private final String CONFIG_HOST;
  26. /**
  27. * 创建client
  28. *
  29. * @param host code judge 地址,示例:{@code "http://codejudge.seec.seecoder.cn"}
  30. */
  31. public CodeJudgeClient(String host) {
  32. this.CONFIG_HOST = host;
  33. client = new OkHttpClient().newBuilder().connectTimeout(60000, TimeUnit.MILLISECONDS).readTimeout(60000,TimeUnit.MILLISECONDS).build();
  34. mapper = JsonMapper.builder()
  35. .addModule(new ParameterNamesModule())
  36. .addModule(new Jdk8Module())
  37. .addModule(new JavaTimeModule())
  38. .build();
  39. }
  40. /**
  41. * 判题接口
  42. *
  43. * @param judgeDTO 判题信息
  44. * @return 判题结果
  45. */
  46. @Override
  47. public JudgeResult judge(@NotNull JudgeDTO judgeDTO) {
  48. HttpUrl httpUrl = createUrlBuilder("/api/judge").build();
  49. Response response = post(httpUrl, writeRequestBody(judgeDTO));
  50. return getResponseBody(response, JudgeResult.class)
  51. .map(judgeResult -> {
  52. if (judgeResult.getMessage() == null) {
  53. return judgeResult;
  54. } else {
  55. throw new CodeJudgeSystemException(judgeResult.getMessage());
  56. }
  57. }).orElseThrow(() -> new CodeJudgeSystemException("UN_WRAP"));
  58. }
  59. private HttpUrl.Builder createUrlBuilder(final String path) {
  60. return Objects.requireNonNull(HttpUrl.parse(CONFIG_HOST + path)).newBuilder();
  61. }
  62. private Response post(HttpUrl httpUrl, RequestBody requestBody) {
  63. return requestWithMethod("POST", httpUrl, requestBody);
  64. }
  65. private Response requestWithMethod(String method, HttpUrl httpUrl, RequestBody requestBody) {
  66. Request request = new Request.Builder().url(httpUrl).method(method, requestBody).build();
  67. try {
  68. return client.newCall(request).execute();
  69. } catch (IOException e) {
  70. logger.error("IOException.", e);
  71. throw new CodeJudgeSystemException("IO_EXCEPTION");
  72. }
  73. }
  74. private <T> Optional<T> getResponseBody(Response response, Class<T> tClass) {
  75. return getResponseBody(
  76. response,
  77. bodyString -> {
  78. try {
  79. return mapper.readValue(bodyString, tClass);
  80. } catch (JsonProcessingException e) {
  81. logger.error("JsonProcessingException.", e);
  82. throw new CodeJudgeSystemException("JsonProcessingException");
  83. }
  84. });
  85. }
  86. private <T> Optional<T> getResponseBody(Response response, TypeReference<T> typeReference) {
  87. return getResponseBody(
  88. response,
  89. bodyString -> {
  90. try {
  91. return mapper.readValue(bodyString, typeReference);
  92. } catch (JsonProcessingException e) {
  93. logger.error("JsonProcessingException.", e);
  94. throw new CodeJudgeSystemException("JsonProcessingException");
  95. }
  96. });
  97. }
  98. private <T> Optional<T> getResponseBody(Response response, Function<String, T> mapType) {
  99. return Optional.ofNullable(response.body())
  100. .map(body -> {
  101. try {
  102. String bodyString = body.string();
  103. return mapType.apply(bodyString);
  104. } catch (IOException e) {
  105. logger.error("IOException.", e);
  106. throw new CodeJudgeSystemException("IOException");
  107. }
  108. });
  109. }
  110. private <T> RequestBody writeRequestBody(T obj) {
  111. if (obj == null) {
  112. return null;
  113. }
  114. try {
  115. return RequestBody.create(CodeJudgeConstants.JSON, mapper.writeValueAsString(obj));
  116. } catch (JsonProcessingException e) {
  117. logger.error("JsonProcessingException.", e);
  118. throw new CodeJudgeSystemException("JsonProcessingException");
  119. }
  120. }
  121. }