门户网站建设公司哪家好,如何统计网站访问量,设计一个网站的首页步骤,网页游戏网址知乎Java在线OJ项目#xff08;三#xff09;、前后端交互API模块 1. 客户端向服务器请求所有题目 或者 单个题目前端获取所有题目获取一个题目 后端 2. 后端读取前端提交的代码#xff0c;进行编译运行#xff0c;返回结果前端提交代码后端处理 1. 客户端向服务器请求所有题目… Java在线OJ项目三、前后端交互API模块 1. 客户端向服务器请求所有题目 或者 单个题目前端获取所有题目获取一个题目 后端 2. 后端读取前端提交的代码进行编译运行返回结果前端提交代码后端处理 1. 客户端向服务器请求所有题目 或者 单个题目
前端通过problem的URL地址访问如果没有其它参数则是查询所有题目如果有id参数就是查询具体题目 后端返回题目的具体详情
前端
获取所有题目 script// 在页面加载的时候, 尝试从服务器获取题目列表. 通过 ajax 的方式来进行获取function getProblems() {// 1. 先通过 ajax 从服务器获取到题目列表. $.ajax({url: problem,type: GET,success: function(data, status) {// data 是响应的 body, status 是响应的状态码// 2. 把得到的响应数据给构造成 HTML 片段makeProblemTable(data);}})}// 通过这个函数来把数据转换成 HTML 页面片段function makeProblemTable(data) {let problemTable document.querySelector(#problemTable);for (let problem of data) {let tr document.createElement(tr);let tdId document.createElement(td);tdId.innerHTML problem.id;tr.appendChild(tdId);let tdTitle document.createElement(td);let a document.createElement(a);a.innerHTML problem.title;a.href problemDetail.html?id problem.id;a.target _blank;tdTitle.appendChild(a);tr.appendChild(tdTitle);let tdLevel document.createElement(td);tdLevel.innerHTML problem.level;tr.appendChild(tdLevel);problemTable.appendChild(tr);}}getProblems();/script获取一个题目
script// 通过 ajax 从服务器获取到题目的详情function getProblem() {// 1. 通过 ajax 给服务器发送一个请求$.ajax({url: problem location.search,type: GET,success: function (data, status) {makeProblemDetail(data);}})}function makeProblemDetail(problem) {// 1. 获取到 problemDesc, 把题目详情填写进去let problemDesc document.querySelector(#problemDesc);let h3 document.createElement(h3);h3.innerHTML problem.id . problem.title _ problem.levelproblemDesc.appendChild(h3);let pre document.createElement(pre);let p document.createElement(p);p.innerHTML problem.description;pre.appendChild(p);problemDesc.appendChild(pre);// 2. 把代码的模板填写到编辑框中. // let codeEditor document.querySelector(#codeEditor);// codeEditor.innerHTML problem.templateCode;editor.setValue(problem.templateCode)
/script后端
package api;import com.fasterxml.jackson.databind.ObjectMapper;
import dao.Problem;
import dao.ProblemDAO;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;WebServlet(/problem)
public class ProblemServlet extends HttpServlet {//ObjectMapper类(com.fasterxml.jackson.databind.ObjectMapper)是Jackson的主要类它可以帮助我们快速的进行各个类型和Json类型的相互转换。private ObjectMapper objectMapper new ObjectMapper();Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//设置返回的状态码 200表示成功resp.setStatus(200);//返回的数据类型resp.setContentType(application/json;charsetutf8);ProblemDAO problemDAO new ProblemDAO();// 尝试获取 id 参数. 如果能获取到, 说明是获取题目详情; 如果不能获取到, 说明是获取题目列表.String idString req.getParameter(id);if (idString null || .equals(idString)) {// 没有获取到 id 字段. 查询题目列表ListProblem problems problemDAO.selectAll();String respString objectMapper.writeValueAsString(problems);resp.getWriter().write(respString);} else {// 获取到了题目 id. 查询题目详情Problem problem problemDAO.selectOne(Integer.parseInt(idString));String respString objectMapper.writeValueAsString(problem);resp.getWriter().write(respString);}}
}2. 后端读取前端提交的代码进行编译运行返回结果 前端提交代码
script// 3. 给提交按钮注册一个点击事件let submitButton document.querySelector(#submitButton);submitButton.onclick function () {// 点击这个按钮, 就要进行提交. (把编辑框的内容给提交到服务器上)let body {id: problem.id,// code: codeEditor.value,code: editor.getValue(),};$.ajax({type: POST,url: compile,data: JSON.stringify(body),success: function (data, status) {let problemResult document.querySelector(#problemResult);if (data.error 0) {// 编译运行没有问题, 把 stdout 显示到页面中problemResult.innerHTML data.stdout;} else {// 编译运行没有问题, 把 reason 显示到页面中problemResult.innerHTML data.reason;}}});}}/script后端处理
package api;import com.fasterxml.jackson.databind.ObjectMapper;
import common.CodeInValidException;
import common.ProblemNotFoundException;
import compile.Answer;
import compile.Question;
import compile.Task;
import dao.Problem;
import dao.ProblemDAO;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;WebServlet(/compile)
public class CompileServlet extends HttpServlet {static class CompileRequest {public int id;public String code;}static class CompileResponse {// 约定 error 为 0 表示编译运行 ok, error 为 1 表示编译出错, error 为 2 表示运行异常(用户提交的代码异常了), 3 表示其他错误public int error;public String reason;public String stdout;}private ObjectMapper objectMapper new ObjectMapper();// {
// id: 2,
// code: class Solution {\n public int[] twoSum(int[] nums, int target) {\n int[] a {0, 1};\n return a;\n }\n}
// }Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 临时加一下这个代码, 来获取到 SmartTomcat 的工作目录System.out.println(用户的当前工作目录: System.getProperty(user.dir));CompileRequest compileRequest null;CompileResponse compileResponse new CompileResponse();try {resp.setStatus(200);resp.setContentType(application/json;charsetutf8);// 1. 先读取请求的正文. 别按照 JSON 格式进行解析String body readBody(req);compileRequest objectMapper.readValue(body, CompileRequest.class);// 2. 根据 id 从数据库中查找到题目的详情 得到测试用例代码ProblemDAO problemDAO new ProblemDAO();Problem problem problemDAO.selectOne(compileRequest.id);if (problem null) {// 为了统一处理错误, 在这个地方抛出一个异常.throw new ProblemNotFoundException();}// testCode 是测试用例的代码String testCode problem.getTestCode();// requestCode 是用户提交的代码String requestCode compileRequest.code;// 3. 把用户提交的代码和测试用例代码, 给拼接成一个完整的代码.String finalCode mergeCode(requestCode, testCode);if (finalCode null) {throw new CodeInValidException();}// System.out.println(finalCode);// 4. 创建一个 Task 实例, 调用里面的 compileAndRun 来进行编译运行.Task task new Task();Question question new Question();question.setCode(finalCode);Answer answer task.compileAndRun(question);// 5. 根据 Task 运行的结果, 包装成一个 HTTP 响应compileResponse.error answer.getError();compileResponse.reason answer.getReason();compileResponse.stdout answer.getStdout();} catch (ProblemNotFoundException e) {// 处理题目没有找到的异常compileResponse.error 3;compileResponse.reason 没有找到指定的题目! id compileRequest.id;} catch (CodeInValidException e) {compileResponse.error 3;compileResponse.reason 提交的代码不符合要求!;} finally {String respString objectMapper.writeValueAsString(compileResponse);resp.getWriter().write(respString);}}private static String mergeCode(String requestCode, String testCode) {// 1. 查找 requestCode 中的最后一个 }int pos requestCode.lastIndexOf(});if (pos -1) {// 说明提交的代码完全没有 } , 显然是非法的代码.return null;}// 2. 根据这个位置进行字符串截取String subStr requestCode.substring(0, pos);// 3. 进行拼接return subStr testCode \n};}private static String readBody(HttpServletRequest req) throws UnsupportedEncodingException {// 1. 先根据 请求头 里面的 ContentLength 获取到 body 的长度(单位是字节)int contentLength req.getContentLength();// 2. 按照这个长度准备好一个 byte[] .byte[] buffer new byte[contentLength];// 3. 通过 req 里面的 getInputStream 方法, 获取到 body 的流对象.try (InputStream inputStream req.getInputStream()) {// 4. 基于这个流对象, 读取内容, 然后把内容放到 byte[] 数组中即可.inputStream.read(buffer);} catch (IOException e) {e.printStackTrace();}// 5. 把这个 byte[] 的内容构造成一个 Stringreturn new String(buffer, UTF8);}
}