MinMin's Online OJ
1. Project objectives
Similar to Leetcode, a simple title-brushing project is implemented. Users can access the title list page in the browser, click on the title to enter the title details page, and write, compile, run the code here, and return the results to the browser page
2. Functions implemented by the project
1. You can display a list of all titles
2. Click on the title to see the details of the title, the code editing box, and a button to submit a compilation run
3. You can compile and run the submitted code and automatically execute the set test cases to return the test results
3. Technology stack used by the project
-
Development environment:
Win10: Operating System of Computer
IDEA: Java Code Writing Tool
Maven: Used to manage dependent packages and package projects into war packages
Linux: Deploying the environment
-
Technology used:
Servlet: Implement server-related API s
Gson: Java class library provided by Google for mapping between Java objects and JSON data
Front-end page technology: used to display pages and interact with back-end data interfaces
Java multi-process: Use multi-process to control JDK
JDBC:Java Provides an interface to access the database
4. Project development process
4.1 Compile Module
Functions implemented by 4.1.1:
Given a java file, jdk can be compiled and run with code
Details of 4.1.2 implementation
1.CommandandUtil.java
Implement a class that can execute an instruction to combine the compilation and execution of the entire java program
- The.JDK has a Runtime class whose objects allow you to create a subprocess and have it execute a command
//1. Get Runtime Object. Runtime is a singleton pattern Runtime runtime = Runtime.getRuntime();
- Using the exec method of the Runtime object, you can
1) Create a subprocess
2) Procedure replacement
//Create a process to execute specified commands in a separate process Process process = runtime.exec(cmd);
-
.Use redirection: Write the content redirection of the java process we want to actually execute to the specified file, because the parent process was created in IDEA and the process process was created inside the parent process, so after running the output, the console output is the parent process, not what we want to use
-
.Start redirecting:
(1) Obtain the object process to the child process
(2) Use input streams to read messages during process execution;
(3) Output streams write these messages to a dedicated file stdoutFile or stderrFile (Standard Output Redirection or Standard Error Redirection)
(4) Finally, pay attention to the closure of the flow
//5. Redirect for standard errors if (stderrFile != null) { InputStream stderrFrom = process.getErrorStream(); OutputStream stderrTo=new FileOutputStream(stderrFile); int ch2=-1; while ((ch2 = stderrFrom.read()) != -1) { stderrTo.write(ch2); } stderrFrom.close(); stderrTo.close(); }
- You should make sure that the child process executes first, so add a process to wait for waitFor()
// Exit code 0--Execution success, not 0--Failure for exitCode process //The parent process on which process depends can be blocked until the process finishes execution or is forced to abort.Blocked process continued int exitCode = process.waitFor();
2.Question.java Class:
There are two properties to compile the executed content code: code and stdin
//Code content to compile and execute private String code; //Standard input for execution private String stdin;
3.Answer.java Class:
The result of compilation, that is, the data generated during compilation:
//Represent the current error type with error, 0--Success 1--Compile Error 2--Run Error private int error; //Indicates the specific cause of the error, compilation error, run error private String reason; //Standard Output Corresponding to Execution private String stdout; //Contents corresponding to standard errors at execution time private String stderr;
4.Task.java Class:
Describes a complete compilation run and defines some properties as temporary files that are all stored in the tmp directory for easy debugging
(1) Create a temporary file directory tmp, store some temporary files, record the intermediate results for debugging purposes
Include:Solution.java Class\Stdin.txt\Stdout.txt\Stderr.txt\compile_Error.txtCompile the file corresponding to the error (the specific reason for the error)
(2) Write a compiled method, compileAndRun (code to compile), and return the result
1. Compile instructions: javac-encoding utf-8. /tmp/Solution.java-d. /tmp/ Note: -d: Indicates that the compiled byte code file is stored in. /tmp/directory Compiled correctly: then COMPILE_An ERROR file is empty, indicating that the compilation is successful, a non-empty file indicates that a compilation error occurred, and the error will not continue 2. Run instructions: java-classpath. /tmp/Solution Note: The classpath option specifies the load path Run correctly: STDERR is empty, use readFile method in FileUtil to view file contents, parameter is file path
String cmd=String.format("javac -encoding utf8 %s -d %s",CODE,WORK_DIR); CommandUtil.run(cmd, null, COMPILE_ERROR); String compileError = FileUtil.readFile(COMPILE_ERROR); if (!"".equals(compileError)) { System.out.println("Compilation error"); answer.setError(1); answer.setReason(compileError); return answer; }
4.2 Design Tool Class
4.3.1.FileUtil--Class for reading and writing files
public static String readFile(String filePath)//read file public static void writeFile(String filePath, String content)//write file
4.3.2.DBUtil--Database Operation Class
1. Data Source Acquisition
2. Get connected
3. Close the connection
4.3 Title Management Module
Functions implemented by 4.2.1
You can store and retrieve all the information about the title, and add or delete the title.
Details of 4.2.2 implementation
1. Design the database
Design Primary Key id is self-increasing
2. Get data sources
In database operation class DButil.java in
Design using thread-safe version of the singleton mode
private static volatile DataSource dataSource=null; public static DataSource getDataSource(){ if (dataSource==null) { synchronized (DBUtil.class) { if(dataSource==null){ dataSource=new MysqlDataSource(); ((MysqlDataSource)dataSource).setURL(URL); ((MysqlDataSource)dataSource).setUser(USERNAME); ((MysqlDataSource)dataSource).setPassword(PASSWORD); } } } return dataSource; }
3. Establish a database connection
public static Connection getConnection(){ try { //Built-in database connection pool return getDataSource().getConnection(); } catch (SQLException e) { e.printStackTrace(); } return null; }
4. Close database connection
public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet) { try { if(resultSet!=null){ resultSet.close(); } if (statement != null) { statement.close(); } if (connection != null) { connection.close(); } } catch (SQLException e) { e.printStackTrace(); } }
5. Operation of title data
4.4 Front and Back End Interaction
1. Enter the home page to get API s for all topics
2. Click on the title to see the API of the title details
3. Click Submit to execute the compile-run API
4.4.1GSON:
Gson is a Java class library provided by Google for mapping between Java objects and JSON data.You can convert a Json character into a Java object or a Java into a Json string.
1. Introducing gson dependency
</dependencies> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.2</version> </dependency> </dependencies>
2. Create gson objects
private Gson gson=new GsonBuilder().create();
3. Common methods
public String toJson(Objcet obj)//The toJson method, which converts an object to a json string. public T fromJson(String jsonStr,T.class)//fromJson method that converts json strings into Java objects
3. Features:
a, fast and efficient
b. Small and concise code
c. Object-oriented
d. Convenient data transfer and analysis
4.4.1.ProblemServlet
1. Use the doGet method to get a list of titles and return it to the browser
private Gson gson=new GsonBuilder().create(); protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String id = req.getParameter("id"); if (id == null || "".equals(id)) { //1. Without the id parameter, perform the search for all titles} selectAll(resp); } else { //2. Execute the lookup logic for the given topic information with the id parameter selectOne(Integer.parseInt(id), resp); } } private void selectOne(int problemId, HttpServletResponse resp) throws IOException { resp.setContentType("application/json;charset=utf-8"); ProblemDAO problemDAO=new ProblemDAO(); Problem problem = problemDAO.selectOne(problemId); //The test code should not tell front-end users to clean up this content manually at this time problem.setTestCode(""); String jsonString = gson.toJson(problem); resp.getWriter().write(jsonString); } private void selectAll(HttpServletResponse resp) throws IOException { //ContentType -- Describes what type of data is in the body //Common values:html:text/html //Picture: image/png image/jpg //json:application/json //css:text/css //javascript:application/javascript //Character set can also be set here resp.setContentType("application/json;charset=utf-8"); ProblemDAO problemDAO = new ProblemDAO(); List<Problem> problems = problemDAO.selectAll(); //Organize the results into a json structure //[Note] The ordered fields in the problem need to be commented out String jsonString = gson.toJson(problems); resp.getWriter().write(jsonString); }
4.4.2-CompileServlet.java
Get the code in the user compilation box and compile it
(1) static class CompileRequest is a class used to assist in parsing data requests in a body and submitting code
private int id; private String code;
(2) static class CompileResponse {// This class is used to assist in constructing the body data for the final response, parsing
private int ok; private String reason; private String stdout;
doPost(req,resp) 1.Read Requested body All data 2.according to API Conventional format to parse JSON Data, get CompileRequest object 3.By object Id Get user compiled code 4.By object Id Get the code for the test case for this topic 5.Assemble 6.Re-create the assembled new code question Object 7.Pass this object in Task Compile and run in answer 8.Construct the run result as response data and write it back to the client
4.5 Front End Page Design
4.5.1 Implementing Functions
1. Show the first page of the project and the list of titles
2. Show Project Details Page
Details of 4.5.2 implementation
1. Introducing the JQuery function library
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
1.jQuery is a JavaScript function library.Is a lightweight JavaScript library that writes less and does more.
2.jQuery library contains the following functions:
- HTML element selection and operation
- CSS Operation
- AJAX: A technology for exchanging data with a server that updates some pages without overloading all pages.
2. Introducing Vue
Build a progressive framework for the user interface to implement responsive data binding and composite view components through the simplest API s possible.