Java 在線考試云平臺的實現(xiàn)
更新時間:2021年11月23日 09:09:03 作者:qq_1334611189
讀萬卷書不如行萬里路,只學(xué)書上的理論是遠遠不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+vue+springboot+mysql+maven實現(xiàn)一個前端vue后臺java微服務(wù)的在線考試系統(tǒng),大家可以在過程中查缺補漏,提升水平
考試流程:
- 用戶前臺注冊成為學(xué)生
- 管理員后臺添加老師,系統(tǒng)將該用戶角色上升為老師
- 老師登錄,添加考試,添加題目,發(fā)布考試
- 考生登錄前臺參加考試,交卷
- 老師后臺批改試卷,查看成績
- 考試查看成績
練習(xí)流程:
- 考生登錄前臺參加練習(xí),練習(xí)完自動判分,記錄錯題
- 考生查看成績,查看錯題






用戶登錄操作業(yè)務(wù):
@RestController
@Api(tags = "User APIs")
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/register")
@ApiOperation("注冊")
ResultVO<User> register(@RequestBody RegisterDTO registerDTO) {
ResultVO<User> resultVO;
// 注冊信息的完善,還有唯一性校驗沒(用戶名、郵箱和手機號)已經(jīng)在user表中通過unique來設(shè)置了
User user = userService.register(registerDTO);
if (user != null) {
// 注冊成功
resultVO = new ResultVO<>(ResultEnum.REGISTER_SUCCESS.getCode(), ResultEnum.REGISTER_SUCCESS.getMessage(), user);
} else {
resultVO = new ResultVO<>(ResultEnum.REGISTER_FAILED.getCode(), ResultEnum.REGISTER_FAILED.getMessage(), null);
}
return resultVO;
}
@PostMapping("/login")
@ApiOperation("根據(jù)用戶名或郵箱登錄,登錄成功返回token")
ResultVO<String> login(@RequestBody LoginQo loginQo) { // 這里不用手機號是因為手機號和用戶名難以進行格式區(qū)分,而用戶名和
// 用戶登錄
ResultVO<String> resultVO;
String token = userService.login(loginQo);
if (token != null) {
// 登錄成功
resultVO = new ResultVO<>(ResultEnum.LOGIN_SUCCESS.getCode(), ResultEnum.LOGIN_SUCCESS.getMessage(), token);
} else {
// 登錄失敗
resultVO = new ResultVO<>(ResultEnum.LOGIN_FAILED.getCode(), ResultEnum.LOGIN_FAILED.getMessage(), null);
}
return resultVO;
}
@GetMapping("/user-info")
@ApiOperation("獲取用戶信息")
ResultVO<UserVo> getUserInfo(HttpServletRequest request) {
String userId = (String) request.getAttribute("user_id");
UserVo userVo = userService.getUserInfo(userId);
return new ResultVO<>(ResultEnum.GET_INFO_SUCCESS.getCode(), ResultEnum.GET_INFO_SUCCESS.getMessage(), userVo);
}
@GetMapping("/info")
@ApiOperation("獲取用戶的詳細信息,包括個人信息頁面和操作權(quán)限")
ResultVO<UserInfoVo> getInfo(HttpServletRequest request) {
System.out.println("進入/user/info的獲取用戶信息的接口");
String userId = (String) request.getAttribute("user_id");
UserInfoVo userInfoVo = userService.getInfo(userId);
return new ResultVO<>(ResultEnum.GET_INFO_SUCCESS.getCode(), ResultEnum.GET_INFO_SUCCESS.getMessage(), userInfoVo);
}
@GetMapping("/test")
@ApiOperation("測試接口")
String test(HttpServletRequest request) {
// 下面這兩個屬性都是登錄攔截器從token中解析地,當(dāng)用戶名不對或者token過期時是走不到接口內(nèi)的
String userId = (String) request.getAttribute("user_id");
String username = (String) request.getAttribute("username");
System.out.println("用戶id:" + userId);
System.out.println("用戶名:" + username);
return "用戶id:" + userId + "\n用戶名:" + username;
}
}
問題信息業(yè)務(wù)操作:
@RestController
@Api(tags = "Exam APIs")
@RequestMapping("/exam")
public class ExamController {
@Autowired
private ExamService examService;
@GetMapping("/question/all")
@ApiOperation("獲取所有問題的列表")
ResultVO<List<QuestionVo>> getQuestionAll() {
ResultVO<List<QuestionVo>> resultVO;
try {
List<QuestionVo> questionAll = examService.getQuestionAll();
resultVO = new ResultVO<>(0, "獲取全部問題列表成功", questionAll);
} catch (Exception e) {
e.printStackTrace();
resultVO = new ResultVO<>(-1, "獲取全部問題列表失敗", null);
}
return resultVO;
}
@PostMapping("/question/update")
@ApiOperation("更新問題")
ResultVO<QuestionVo> questionUpdate(@RequestBody QuestionVo questionVo) {
// 完成問題的更新
System.out.println(questionVo);
try {
QuestionVo questionVoResult = examService.updateQuestion(questionVo);
return new ResultVO<>(0, "更新問題成功", questionVoResult);
} catch (Exception e) {
e.printStackTrace();
return new ResultVO<>(-1, "更新問題失敗", null);
}
}
@PostMapping("/question/create")
@ApiOperation("創(chuàng)建問題")
ResultVO<String> questionCreate(@RequestBody QuestionCreateSimplifyVo questionCreateSimplifyVo, HttpServletRequest request) {
QuestionCreateVo questionCreateVo = new QuestionCreateVo();
// 把能拷貝過來的屬性都拷貝過來
BeanUtils.copyProperties(questionCreateSimplifyVo, questionCreateVo);
// 設(shè)置創(chuàng)建者信息
String userId = (String) request.getAttribute("user_id");
questionCreateVo.setQuestionCreatorId(userId);
System.out.println(questionCreateVo);
try {
examService.questionCreate(questionCreateVo);
return new ResultVO<>(0, "問題創(chuàng)建成功", null);
} catch (Exception e) {
e.printStackTrace();
return new ResultVO<>(-1, "創(chuàng)建問題失敗", null);
}
}
@GetMapping("/question/selection")
@ApiOperation("獲取問題分類的相關(guān)選項")
ResultVO<QuestionSelectionVo> getSelections() {
QuestionSelectionVo questionSelectionVo = examService.getSelections();
if (questionSelectionVo != null) {
return new ResultVO<>(0, "獲取問題分類選項成功", questionSelectionVo);
} else {
return new ResultVO<>(-1, "獲取問題分類選項失敗", null);
}
}
@GetMapping("/question/detail/{id}")
@ApiOperation("根據(jù)問題的id獲取問題的詳細信息")
ResultVO<QuestionDetailVo> getQuestionDetail(@PathVariable String id) {
// 根據(jù)問題id獲取問題的詳細信息
System.out.println(id);
ResultVO<QuestionDetailVo> resultVO;
try {
QuestionDetailVo questionDetailVo = examService.getQuestionDetail(id);
resultVO = new ResultVO<>(0, "獲取問題詳情成功", questionDetailVo);
} catch (Exception e) {
e.printStackTrace();
resultVO = new ResultVO<>(-1, "獲取問題詳情失敗", null);
}
return resultVO;
}
@GetMapping("/all")
@ApiOperation("獲取全部考試的列表")
ResultVO<List<ExamVo>> getExamAll() {
// 需要拼接前端需要的考試列表對象
ResultVO<List<ExamVo>> resultVO;
try {
List<ExamVo> examVos = examService.getExamAll();
resultVO = new ResultVO<>(0, "獲取全部考試的列表成功", examVos);
} catch (Exception e) {
e.printStackTrace();
resultVO = new ResultVO<>(-1, "獲取全部考試的列表失敗", null);
}
return resultVO;
}
@GetMapping("/question/type/list")
@ApiOperation("獲取問題列表,按照單選、多選和判斷題分類返回")
ResultVO<ExamQuestionTypeVo> getExamQuestionTypeList() {
// 獲取問題的分類列表
ResultVO<ExamQuestionTypeVo> resultVO;
try {
ExamQuestionTypeVo examQuestionTypeVo = examService.getExamQuestionType();
resultVO = new ResultVO<>(0, "獲取問題列表成功", examQuestionTypeVo);
} catch (Exception e) {
e.printStackTrace();
resultVO = new ResultVO<>(-1, "獲取問題列表失敗", null);
}
return resultVO;
}
@PostMapping("/create")
@ApiOperation("創(chuàng)建考試")
ResultVO<Exam> createExam(@RequestBody ExamCreateVo examCreateVo, HttpServletRequest request) {
// 從前端傳參數(shù)過來,在這里完成考試的入庫
ResultVO<Exam> resultVO;
String userId = (String) request.getAttribute("user_id");
try {
Exam exam = examService.create(examCreateVo, userId);
resultVO = new ResultVO<>(0, "創(chuàng)建考試成功", exam);
} catch (Exception e) {
e.printStackTrace();
resultVO = new ResultVO<>(-1, "創(chuàng)建考試失敗", null);
}
return resultVO;
}
@PostMapping("/update")
@ApiOperation("更新考試")
ResultVO<Exam> updateExam(@RequestBody ExamVo examVo, HttpServletRequest request) {
// 從前端傳參數(shù)過來,在這里完成考試的入庫
ResultVO<Exam> resultVO;
String userId = (String) request.getAttribute("user_id");
try {
Exam exam = examService.update(examVo, userId);
resultVO = new ResultVO<>(0, "更新考試成功", exam);
} catch (Exception e) {
e.printStackTrace();
resultVO = new ResultVO<>(-1, "更新考試失敗", null);
}
return resultVO;
}
@GetMapping("/card/list")
@ApiOperation("獲取考試列表,適配前端卡片列表")
ResultVO<List<ExamCardVo>> getExamCardList() {
// 獲取考試列表卡片
ResultVO<List<ExamCardVo>> resultVO;
try {
List<ExamCardVo> examCardVoList = examService.getExamCardList();
resultVO = new ResultVO<>(0, "獲取考試列表卡片成功", examCardVoList);
} catch (Exception e) {
e.printStackTrace();
resultVO = new ResultVO<>(-1, "獲取考試列表卡片失敗", null);
}
return resultVO;
}
@GetMapping("/detail/{id}")
@ApiOperation("根據(jù)考試的id,獲取考試詳情")
ResultVO<ExamDetailVo> getExamDetail(@PathVariable String id) {
// 根據(jù)id獲取考試詳情
ResultVO<ExamDetailVo> resultVO;
try {
ExamDetailVo examDetail = examService.getExamDetail(id);
resultVO = new ResultVO<>(0, "獲取考試詳情成功", examDetail);
} catch (Exception e) {
resultVO = new ResultVO<>(-1, "獲取考試詳情失敗", null);
}
return resultVO;
}
@PostMapping("/finish/{examId}")
@ApiOperation("根據(jù)用戶提交的答案對指定id的考試判分")
ResultVO<ExamRecord> finishExam(@PathVariable String examId, @RequestBody HashMap<String, List<String>> answersMap, HttpServletRequest request) {
ResultVO<ExamRecord> resultVO;
try {
// 攔截器里設(shè)置上的用戶id
String userId = (String) request.getAttribute("user_id");
// 下面根據(jù)用戶提交的信息進行判分,返回用戶的得分情況
ExamRecord examRecord = examService.judge(userId, examId, answersMap);
resultVO = new ResultVO<>(0, "考卷提交成功", examRecord);
} catch (Exception e) {
e.printStackTrace();
resultVO = new ResultVO<>(-1, "考卷提交失敗", null);
}
return resultVO;
}
@GetMapping("/record/list")
@ApiOperation("獲取當(dāng)前用戶的考試記錄")
ResultVO<List<ExamRecordVo>> getExamRecordList(HttpServletRequest request) {
ResultVO<List<ExamRecordVo>> resultVO;
try {
// 攔截器里設(shè)置上的用戶id
String userId = (String) request.getAttribute("user_id");
// 下面根據(jù)用戶賬號拿到他(她所有的考試信息),注意要用VO封裝下
List<ExamRecordVo> examRecordVoList = examService.getExamRecordList(userId);
resultVO = new ResultVO<>(0, "獲取考試記錄成功", examRecordVoList);
} catch (Exception e) {
e.printStackTrace();
resultVO = new ResultVO<>(-1, "獲取考試記錄失敗", null);
}
return resultVO;
}
@GetMapping("/record/detail/{recordId}")
@ApiOperation("根據(jù)考試記錄id獲取考試記錄詳情")
ResultVO<RecordDetailVo> getExamRecordDetail(@PathVariable String recordId) {
ResultVO<RecordDetailVo> resultVO;
try {
RecordDetailVo recordDetailVo = examService.getRecordDetail(recordId);
resultVO = new ResultVO<>(0, "獲取考試記錄詳情成功", recordDetailVo);
} catch (Exception e) {
e.printStackTrace();
resultVO = new ResultVO<>(-1, "獲取考試記錄詳情失敗", null);
}
return resultVO;
}
}
文件上傳業(yè)務(wù)控制器:
/***********************************************************
* @note : 文件上傳下載的接口,由于Swagger的問題導(dǎo)致在SwaggerUI
* 里測試不成功,實際上前端是完全沒有問題的
* * 為了支持Ajax請求和響應(yīng),最簡單的解決方案返回一個ResponseEntity。
* * 以下示例演示了上傳文件的三種可能方式:
* * 1. 單文件上傳 - `MultipartFile`
* * 2. 多文件上傳 - `MultipartFile []`
* * 3. 將文件上傳到模型 - `@ModelAttribute`
@RestController
@Api(tags = "Upload And Download APIs")
@RequestMapping("/file")
@Slf4j
public class UploadDownloadController {
// @Autowired
// AITestConfig aiTestConfig;
//
// @PostMapping("/upload/single")
// @ApiOperation("單文件上傳")
// public String uploadFile(@RequestParam("file") MultipartFile uploadfile) {
// return FileTransUtil.uploadFile(uploadfile, "/root/" + File.separator + uploadfile.getOriginalFilename());
// }
@ApiOperation("單文件上傳,支持同時傳入?yún)?shù)")
@PostMapping("/api/upload/singleAndparas")
public String uploadFileSingle(@RequestParam("dir") String dir, @RequestParam("file") MultipartFile uploadfile) {
return FileTransUtil.uploadFile(uploadfile, dir);
}
@ApiOperation("單文件上傳,支持同時傳入?yún)?shù),Model")
@PostMapping("/upload/single/model")
public String singleUploadFileModel(@ModelAttribute("model") UploadModel2 model) {
return FileTransUtil.uploadFile(model.getFile(), model.getDir());
}
@ApiOperation("多文件上傳,支持同時傳入?yún)?shù)")
@PostMapping("upload/multiAndparas")
public String uploadFileMulti(@RequestParam("dir") String dir, @RequestParam("files") MultipartFile[] uploadfiles) {
return FileTransUtil.uploadFiles(uploadfiles, dir);
}
@ApiOperation("多文件上傳,支持同時傳入?yún)?shù)")
@PostMapping(value = "/upload/multi/model")
public String multiUploadFileModel(@ModelAttribute(("model")) UploadModel model) {
return FileTransUtil.uploadFiles(model.getFiles(), model.getDir());
}
@ApiOperation("Get下載文件")
@GetMapping(value = "/download/get")
public ResponseEntity<InputStreamResource> downloadFileGet(@RequestParam String filePath) throws IOException {
return FileTransUtil.downloadFile(filePath);
}
@ApiOperation("Post下載文件")
@PostMapping(value = "/download/post")
public ResponseEntity<InputStreamResource> downloadFilePost(@RequestBody DownloadQo downloadQo) throws IOException {
return FileTransUtil.downloadFile(downloadQo.getPath());
}
}
到此這篇關(guān)于Java 在線考試云平臺的實現(xiàn)的文章就介紹到這了,更多相關(guān)Java 考試平臺內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:
- Java項目實戰(zhàn)之在線考試系統(tǒng)的實現(xiàn)(系統(tǒng)介紹)
- Java?實戰(zhàn)項目之學(xué)生信息管理系統(tǒng)的實現(xiàn)流程
- Java 實現(xiàn)完整功能的學(xué)生管理系統(tǒng)實例
- java基于jdbc實現(xiàn)簡單學(xué)生管理系統(tǒng)
- Java實現(xiàn)學(xué)生管理系統(tǒng)詳解
- 利用Java寫一個學(xué)生管理系統(tǒng)
- Java實現(xiàn)簡單學(xué)生信息管理系統(tǒng)
- 基于JavaSwing+mysql開發(fā)一個學(xué)生社團管理系統(tǒng)設(shè)計和實現(xiàn)
- java實現(xiàn)學(xué)生成績檔案管理系統(tǒng)
相關(guān)文章
Java Scanner的使用和hasNextXXX()的用法說明
這篇文章主要介紹了Java Scanner的使用和hasNextXXX()的用法說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10
SpringBoot如何配置MySQL和Oracl雙數(shù)據(jù)源(Mybatis)
這篇文章主要介紹了SpringBoot如何配置MySQL和Oracl雙數(shù)據(jù)源(Mybatis)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03
IDEA 配合 Dockerfile 部署 SpringBoot 工程的注意事項
這篇文章主要介紹了IDEA 配合 Dockerfile 部署 SpringBoot 工程,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-09-09
Spring Boot Actuator未授權(quán)訪問漏洞的問題解決
Spring Boot Actuator 端點的未授權(quán)訪問漏洞是一個安全性問題,可能會導(dǎo)致未經(jīng)授權(quán)的用戶訪問敏感的應(yīng)用程序信息,本文就來介紹一下解決方法,感興趣的可以了解一下2023-09-09
Java之maven打完jar包之后將jar包放到指定位置匯總
這篇文章主要介紹了Java之maven打完jar包之后將jar包放到指定位置匯總,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04

