从零开始搭建一个JavaSSM作业管理系统(四)

从零开始搭建一个JavaSSM作业管理系统系列

从零开始搭建一个JavaSSM作业管理系统(一)
从零开始搭建一个JavaSSM作业管理系统(二)
从零开始搭建一个JavaSSM作业管理系统(三)
从零开始搭建一个JavaSSM作业管理系统(四)

项目下载地址

说明!!!

1.本系列的文章仅展示搭建SSM作业管理系统的大致流程,文章中不会提供该项目的完整代码,如果需要完整代码可以在提供的链接中自行下载

2.本系列只展示作业管理系统一小部分功能实现(登录功能、管理员界面的学生信息管理功能),大部分功能都是信息的增删改查基本操作,重复度较多,大体步骤也都相同,故不做过多展示,请大家见谅

3.博主本人也算是spring框架的初学者,写此系列的目的旨在分享个人在学习SSM过程中的一些经验,如果大家在博客中发现代码或一些解释有误,还望多多指正

前言

在完成底层工作后,下面我们来逐一实现作业管理系统的功能

摘要

本文主要介绍作业管理系统相关功能的实现

  • 登录功能
  • 管理员界面的学生信息管理功能

本文也是该系列的最后一篇

说明

前端我采用了Layui框架
相关代码的使用可以参考Layui官方文档
Layui

登录功能

学生身份
教师身份
管理员身份
登录界面
作业管理系统-学生界面
作业管理系统-教师界面
作业管理系统-管理员界面

1.html

<form class="layui-form zyl_pad_01" action="">
	<div class="layui-col-sm12 layui-col-md12">
		<div class="layui-form-item">
			<input type="text" name="userId" id="userId" lay-verify="required|userId" autocomplete="off" placeholder="账号" class="layui-input">
			<i class="layui-icon layui-icon-username zyl_lofo_icon"></i>
		</div>
	</div>
	<div class="layui-col-sm12 layui-col-md12">
		<div class="layui-form-item">
			<input type="password" name="password" id="password" lay-verify="required|password" autocomplete="off" placeholder="密码" class="layui-input">
			<i class="layui-icon layui-icon-password zyl_lofo_icon"></i>
		</div>
	</div>
	<div class="layui-col-sm12 layui-col-md12">
		<div class="layui-form-item">
			<select name="type" id="type" lay-filter="">
				<option value=""></option>
				<option value="0" selected="">学生</option>
				<option value="1">教师</option>
				<option value="2">管理员</option>
			</select>
			<i class="layui-icon layui-icon-friends zyl_lofo_icon"></i>
		</div>
	</div>
	<div class="layui-col-sm12 layui-col-md12">
		<div class="layui-row">
			<div class="layui-col-xs4 layui-col-sm4 layui-col-md4">
				<div class="layui-form-item">
					<input type="text" name="vercode" id="vercode" lay-verify="required|vercodes" autocomplete="off" placeholder="验证码" class="layui-input" maxlength="4">
					<i class="layui-icon layui-icon-vercode zyl_lofo_icon"></i>
				</div>
			</div>
			<div class="layui-col-xs4 layui-col-sm4 layui-col-md4">
				<div class="zyl_lofo_vercode zylVerCode" onclick="zylVerCode()"></div>
			</div>
		</div>
	</div>
	<div class="layui-col-sm12 layui-col-md12">
		<button class="layui-btn layui-btn-fluid" lay-submit="" lay-filter="login">立即登录</button>
	</div>
</form>

2.js

layui.use(['form'], function(){
	var form = layui.form;
				
	//自定义验证规则
	form.verify({
		userId: function(value){
			if(hasLetter(value) == true || isChina(value) == true){
				return '账号不能含有英文字母或中文';
			}
		}
		,password: [/^[\S]{5,12}$/,'密码必须5到12位,且不能出现空格']
		,vercodes: function(value){
			//获取验证码
			var zylVerCode = $(".zylVerCode").html();
			if(value!=zylVerCode){
				return '验证码错误(区分大小写)';
			}
		}
		,content: function(value){
			layedit.sync(editIndex);
		}
	});
				
				//监听提交
	form.on('submit(login)', function(data){
					//用ajax时需要注意你的url接口、采用哪一种方式type获取,它的使用的哪种数据类型datatype
		$.ajax({
			url:'/home/login',
			type:'get',
			dataType:'json',
			data:data.field,
			beforeSend:function(){
				//弹出的lodinng层
				layer.load(2,{
					shade:[0.5,"#02fff0"]
				});
			},
			success:function(res){
				if (res.redirect) {
					window.location.href = res.url;
				} else {
					layer.msg("无法进入系统,输入的账号或密码错误");
				}
			},
			error:function(){
				//用户输入与接口内容不对应,显示文字
				layer.msg("访问失败")
			},
			complete:function(){
				//关掉loading
				layer.closeAll("loading")
			}
	    })
		return false;//不会跳转到网址栏,只会跳转到你要的界面 一定要写。
	});

});

(1)layui.use() 主要用来导入所需要用到的Layui模块,这里我导入了form,即Layui的表单模块,同时所有js代码也需要写在use()的function里面

如果在js代码里使用form需要定义var form = layui.form

具体详细用法可以参考Layui的官方文档

(2)form.verify() 主要定义表单内元素的验证规则,如果表单内某个标签需要自定义验证规则,需要在该标签内添加lay-verify=“名字”,如

<input type="text" lay-verify="required|name" class="layui-input">

required|name - 添加’required’则设置该标签为必需填写的标签,’|'后的name则相当于验证ID

验证时只需在js代码中编写:

form.verify({
	name:验证的规则
})	

(3)form.on(‘submit(login)’, function(data){}) 为监听表单提交的函数

对应button如下:

<button class="layui-btn layui-btn-fluid" lay-submit="" lay-filter="login">立即登录</button>

在button标签里加入lay-filter即可监听提交

3.Controller层

@Controller
@RequestMapping("/home")
public class HomeManagementController {
    @Autowired
    private StudentService studentService;
    @Autowired
    private TeacherService teacherService;
    @Autowired
    private AdminService adminService;

     //登录信息处理
    @RequestMapping(value = "/login",method = RequestMethod.GET)
    @ResponseBody
    private Map<String, Object> login(HttpServletRequest request){
        Map<String, Object> modelMap = new HashMap<>();

        int type = HttpServletRequestUtil.getInt(request,"type");
        long userId = HttpServletRequestUtil.getLong(request,"userId");
        String inputPassword = HttpServletRequestUtil.getString(request,"password");
        String realPassword;

        if (type == 0){
            Student student = studentService.getStudentById(userId);
            realPassword = student.getPassword();
            if (realPassword.equals(inputPassword)){
                request.getSession().setAttribute("studentId",userId);
                modelMap.put("redirect",true);
                modelMap.put("url","/home/studentIndex?studentId="+student.getStudentId());
            }else {
                modelMap.put("redirect",false);
            }
        }else if (type == 1){
            Teacher teacher = teacherService.getTeacherById(userId);
            realPassword = teacher.getPassword();
            if (realPassword.equals(inputPassword)){
                request.getSession().setAttribute("teacherId",userId);
                modelMap.put("redirect",true);
                modelMap.put("url","/home/teacherIndex?teacherId="+teacher.getTeacherId());
            }else {
                modelMap.put("redirect",false);
            }
        }else if (type == 2){
            Admin admin = adminService.getAdminById(userId);
            realPassword = admin.getPassword();
            if (realPassword.equals(inputPassword)){
                request.getSession().setAttribute("adminId",userId);
                modelMap.put("redirect",true);
                modelMap.put("url","/home/adminIndex?adminName="+admin.getAdminName());
            }else {
                modelMap.put("redirect",false);
            }
        }else {
            modelMap.put("redirect",false);
        }
        return modelMap;
    }
}

Controller层主要接受前端传过来的数据:
type-用户类型
userId-账号
password-密码

前后端处理数据流程如下:
首先根据type判断用户的类型,再根据账号和密码判断该用户的账号和密码是否正确,如果正确,返回相应的url和success(状态为true),前端再根据返回的url跳转的相应界面;如果不正确只返回success(状态为false)

4.演示

此处只演示学生界面的登录
登录界面演示

管理员界面-学生信息管理功能

学生信息管理
增加学生信息
删除学生信息
修改学生信息
查看学生详细列表

增加学生信息

1.html
<form class="layui-form" action="" lay-filter="add-studentInfo">

  <div class="layui-form-item">
    <div class="layui-inline">
      <label class="layui-form-label">学生头像</label>
      <input type="file" name="profileImg">
    </div>
  </div>
  <div class="layui-form-item">
    <div class="layui-inline">
      <label class="layui-form-label">学生号</label>
      <div class="layui-input-inline">
        <input type="text" name="studentId" lay-verify="required|studentId" autocomplete="off" class="layui-input">
      </div>
    </div>
    <div class="layui-inline">
      <label class="layui-form-label">学生姓名</label>
      <div class="layui-input-inline">
        <input type="text" name="studentName" lay-verify="required|studentName" autocomplete="off" class="layui-input">
      </div>
    </div>
  </div>
  <div class="layui-form-item">
    <label class="layui-form-label">性别</label>
    <div class="layui-input-block">
      <input type="radio" name="gender" value="" title="">
      <input type="radio" name="gender" value="" title="">
    </div>
  </div>
  <div class="layui-form-item">
    <label class="layui-form-label">邮箱</label>
    <div class="layui-input-block">
      <input type="text" name="email" lay-verify="email" placeholder="" autocomplete="off" class="layui-input">
    </div>
  </div>
  <div class="layui-form-item layui-form-text">
    <label class="layui-form-label">简介</label>
    <div class="layui-input-block">
      <textarea name="studentDesc" placeholder="请输入内容" class="layui-textarea"></textarea>
    </div>
  </div>
  <div class="layui-form-item">
    <label class="layui-form-label">所属班级</label>
    <div class="layui-input-block">
      <div class="layui-col-md6">
        <select id="clazz">
        </select>
      </div>
    </div>
  </div>

  <div class="layui-form-item layui-layout-admin">
    <div class="layui-input-block">
      <div class="layui-footer" style="left: 0;">
        <button class="layui-btn" lay-submit="" lay-filter="add-student">立即提交</button>
        <button type="reset" class="layui-btn layui-btn-primary">重置</button>
      </div>
    </div>
  </div>
  
</form>
2.js
  layui.use(['index', 'form'], function(){
    var $ = layui.$
    ,layer = layui.layer
    ,form = layui.form;

    form.render(null, 'add-studentInfo');

    /* 自定义验证规则 */
    form.verify({
      studentId: function(value){
        if(hasLetter(value) === true || isChina(value) === true){
          return '学生号不能含有中文';
        }
      }
      ,studentName: function(value){
        if(containsNumber(value) === true){
          return '学生姓名不能含有数字';
        }
      }
    });

    getClazzList();

    // 获取班级列表
    function getClazzList(){
      $.get('/admin/listClazzMap', function(res) {
        if (res.success){
          var tempHtml = '';
          //根据班级列表动态拼接html
          res.clazzList.map(function (item, index) {
            tempHtml += '<option data-id="' + item.clazzId + '">'
                    + item.clazzDesc + '</option>';
          });
          $('#clazz').html(tempHtml);
          form.render('select');
        }
      });
    }

    var student = {};
    
    /* 监听提交 */
    form.on('submit(add-student)', function(data){
      // 获取缩略图文件流
      var studentImg = $('input[name="profileImg"]')[0].files[0];

      student.studentId = $('input[name="studentId"]').val();
      student.studentName = $('input[name="studentName"]').val();
      student.gender = $('input[name="gender"]:checked').val();
      student.email = $('input[name="email"]').val();
      student.studentDesc = $('textarea[name="studentDesc"]').val();
      student.clazz = {
        clazzId : $('#clazz').find('option').not(function () {
          return !this.selected;
        }).data('id')
      };

      var formData = new FormData();
      formData.append('studentImg', studentImg);
      formData.append('studentStr',JSON.stringify(student));

      //用ajax时需要注意你的url接口、采用哪一种方式type获取,它的使用的哪种数据类型datatype
      $.ajax({
        url:'/admin/addStudent',
        type:'post',
        data:formData,
        contentType : false,
        processData : false,
        success:function(res){
          if (res.success){
            layer.msg("添加学生信息成功");
          }else {
            layer.msg("添加学生信息失败" + res.errMsg);
          }
        }
      })
      return false;
    });

  });

form.render(null, ‘add-studentInfo’) 主要对表单所有元素更新渲染,相当于初始化表单

form.render(‘select’) 主要对表单中select标签更新渲染,由于学生表单中select标签为动态插入,Layui中form模块的自动化渲染是会对其失效的,所以需要在动态插入select标签里的元素后再进行一次渲染

有关表单渲染的详细介绍可以参考Layui的官方文档

3.Controller层
@Controller
@RequestMapping("/admin")
public class StudentManagementController {
    @Autowired
    private StudentService studentService;

    //添加学生信息
    //获取前端ajax传递的字符串,解析字符串为相应的student实体,根据解析好的数据添加学生信息
    @RequestMapping(value = "/addStudent",method = RequestMethod.POST)
    @ResponseBody
    private Map<String,Object> addStudent(HttpServletRequest request){
        Map<String,Object> modelMap = new HashMap<>();

        //1.接受并转化相应的参数
        //获取前端传过来的学生信息,并将它转换成实体类;
        //同时获取前端传递过来的文件流,将它接受到studentImg里面去
        String studentStr = HttpServletRequestUtil.getString(request,"studentStr");
        if (studentStr == null){
            modelMap.put("success",false);
            modelMap.put("errMsg","请输入学生信息");
            return modelMap;
        }
        ObjectMapper mapper = new ObjectMapper();
        Student student;
        try {
            student = mapper.readValue(studentStr,Student.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            modelMap.put("success",false);
            modelMap.put("errMsg",e.getMessage());
            return modelMap;
        }
        CommonsMultipartFile studentImg;
        CommonsMultipartResolver commonsMultipartResolver =
                new CommonsMultipartResolver(
                        request.getSession().getServletContext()
                );
        MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
        studentImg = (CommonsMultipartFile) multipartHttpServletRequest.getFile("studentImg");

        //2.添加学生信息
        StudentExecution studentExecution;
        try {
            ImageHolder imageHolder = null;
            if (studentImg != null){
                imageHolder = new ImageHolder(studentImg.getOriginalFilename(),studentImg.getInputStream());
            }
            studentExecution = studentService.addStudent(student,imageHolder);
            if (studentExecution.getState() == StudentStateEnum.SUCCESS.getState()){
                modelMap.put("success",true);
            }else{
                modelMap.put("success",false);
                modelMap.put("errMsg",studentExecution.getStateInfo());
            }
        } catch (IOException e) {
            modelMap.put("success",false);
            modelMap.put("errMsg",e.getMessage());
        }
        return modelMap;
        //3.返回结果
    }
}    
4.演示

添加学生演示

查看学生详细列表

1.html
<table class="layui-hide" id="student-list" lay-filter="student-list"></table>
2.js
layui.use(['table'], function(){
    var table = layui.table

    table.render({
      elem: '#student-list'
      ,id: 'studentTable'
      ,url: '/admin/listStudent'
      ,toolbar: '#operation'
      ,title: '学生信息列表'
      ,cols: [[
         {field:'studentId', title:'学生ID号', width:120, fixed: 'left', unresize: true, sort: true},
         {field:'password', title:'密码', width:150},
         {field:'studentName', title:'学生姓名', width:120, sort: true},
         {field:'gender', title:'性别', width:80},
         {field:'email', title:'邮箱', width:150, templet: function(res){
          return '<em>'+ res.email +'</em>'
        }},
         {field:'studentDesc', title:'简介', width:250},
         {title:'班级ID号', width:120, sort: true, templet: function(data){
             return data.clazz.clazzId;
           }},
         {title:'班级名', width:150, sort: true, templet: function(data){
             return data.clazz.clazzDesc;
           }},
         {title:'创建时间', width:120, templet: function(res){
             return new Date(res.createTime).Format("yyyy-MM-dd");
        }},
         {title:'最近一次更新时间', width:160, templet: function(res){
             if (res.lastEditTime != null){
               return new Date(res.lastEditTime).Format("yyyy-MM-dd");
             }else {
               return "暂未更新";
             }
         }},
         {fixed: 'right', title:'操作', toolbar: '#operation', width:150}
      ]]
      ,page: true
    });

});

(1)elem对应于html中id为student-list的table标签

(2)url是将要访问的接口

(3)cols,与controller层返回的集合相关联,里面的field值对应着集合里面相同名字的字段,如果需要更改controller层返回的某一个字段的格式,需要用到templet

示例如下:

{field:'email', title:'邮箱', width:150, templet: function(res){
          return '<em>'+ res.email +'</em>'
}}

此处代码是将后端传递过来的字段email通过templet读取,并用html的标签将字段值包裹起来

最终显示如下,这是其中一行的数据:

最终显示
可以看到,表格中邮箱那一列下面的值是斜体的,可见templet生效了

(4)toolbar控件-工具条

示例如下:

{fixed: 'right', title:'操作', toolbar: '#operation', width:150}
<script type="text/html" id="operation">
    <a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
    <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
</script>

通过定义的id为operation的组件,Layui的table便能显示出工具条
显示出工具条

3.Controller层
@Controller
@RequestMapping("/admin")
public class StudentManagementController {
    @Autowired
    private StudentService studentService;

    //列出所有学生列表-返回为Layui类型
    @RequestMapping(value = "/listStudent",method = RequestMethod.GET)
    @ResponseBody
    public Layui listStudent(){
        //查询显示列表数据
        List<Student> studentList = studentService.getStudentList();
        return Layui.data(studentList.size(),studentList);
    }
}  
4.Layui工具类

Layui的table有规定的数据格式,所以需要定义一个Layui工具类封装查询到的列表数据

public class Layui  extends HashMap<String, Object> {

    public static Layui data(Integer count, List<?> data){
        Layui r = new Layui();
        r.put("code", 0);
        r.put("msg", "");
        r.put("count", count);
        r.put("data", data);
        return r;
    }
}

返回数据格式如下:
返回数据格式

5.演示

列表演示

删除、修改学生信息

1.html
<table class="layui-hide" id="student-list" lay-filter="student-list"></table>
             
<script type="text/html" id="operation">
    <a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
    <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
</script>
2.js

(1)表单监听,通过工具条控件中lay-event的值来进行情况判断

//监听行工具事件
table.on('tool(student-list)', function(obj){
    var data = obj.data;
    if(obj.event === 'del'){
      layer.confirm('确定要删除吗', function(index){
        delStudentById(data.studentId);
        layer.close(index);
      });
    } else if(obj.event === 'edit'){
      layer.open({
        //layer提供了5种层类型。可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)
        type: 1,
        title: "修改学生信息",
        area: ['600px', '400px'],
        content: $("#popUpdateStudent")//引用的弹出层的页面层的方式加载修改界面表单
    });
      //动态向表传递赋值可以参看文章进行修改界面的更新前数据的显示,当然也是异步请求的要数据的修改数据的获取
      setFormValue(obj,data);
    }
});

(2)修改界面表单

<!--这里是弹出层的表单信息-->
<!--style是在本页隐藏,只有点击编辑才会弹出-->
  <div class="layui-row" id="popUpdateStudent" style="display:none;">
    <div class="layui-col-md10">
      <form class="layui-form layui-from-pane" action="" style="margin-top:20px" lay-filter="modify-student">
        <div class="layui-form-item">
          <div class="layui-inline">
            <label class="layui-form-label">学生头像</label>
            <input type="file" name="profileImg">
          </div>
        </div>
        <div class="layui-form-item">
          <div class="layui-inline">
            <label class="layui-form-label">学生号</label>
            <div class="layui-input-inline">
              <input type="text" name="studentId" class="layui-input" readonly>
            </div>
          </div>
          <div class="layui-inline">
            <label class="layui-form-label">学生姓名</label>
            <div class="layui-input-inline">
              <input type="text" name="studentName" lay-verify="required|studentName" class="layui-input">
            </div>
          </div>
        </div>
        <div class="layui-form-item">
          <label class="layui-form-label">性别</label>
          <div class="layui-input-block">
            <input type="radio" name="gender" value="" title="">
            <input type="radio" name="gender" value="" title="">
          </div>
        </div>
        <div class="layui-form-item">
          <label class="layui-form-label">邮箱</label>
          <div class="layui-input-block">
            <input type="text" name="email" lay-verify="email" class="layui-input">
          </div>
        </div>
        <div class="layui-form-item layui-form-text">
          <label class="layui-form-label">简介</label>
          <div class="layui-input-block">
            <textarea name="studentDesc" placeholder="请输入内容" class="layui-textarea"></textarea>
          </div>
        </div>
        <div class="layui-form-item">
          <label class="layui-form-label">所属班级</label>
          <div class="layui-input-block">
            <div class="layui-col-md6">
              <select id="clazz">
              </select>
            </div>
          </div>
        </div>

        <div class="layui-form-item layui-layout-admin">
          <div class="layui-input-block">
            <div class="layui-footer" style="left: 0;">
              <button class="layui-btn" lay-submit="" lay-filter="edit-student">立即提交</button>
            </div>
          </div>
        </div>
      </form>
    </div>
  </div>
3.Controller层
@Controller
@RequestMapping("/admin")
public class StudentManagementController {
    @Autowired
    private StudentService studentService;

    //修改学生信息
    //获取前端ajax传递的字符串,解析字符串为相应的student实体,根据解析好的数据修改学生信息
    @RequestMapping(value = "/modifyStudent",method = RequestMethod.POST)
    @ResponseBody
    public Map<String,Object> modifyTeacher(HttpServletRequest request) throws IOException {
        Map<String, Object> modelMap = new HashMap<>();
        // 接收前端参数的变量的初始化
        ObjectMapper mapper = new ObjectMapper();
        Student student;

        // 若请求中存在文件流,则取出相关的文件
        CommonsMultipartFile studentImg = null;
        CommonsMultipartResolver commonsMultipartResolver =
                new CommonsMultipartResolver(
                        request.getSession().getServletContext()
                );
        if (commonsMultipartResolver.isMultipart(request)){
            MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
            studentImg = (CommonsMultipartFile) multipartHttpServletRequest.getFile("studentImg");
        }

        try {
            String studentStr = HttpServletRequestUtil.getString(request, "studentStr");
            // 尝试获取前端传过来的表单string流并将其转换成Student实体类
            student = mapper.readValue(studentStr, Student.class);
        } catch (Exception e) {
            modelMap.put("success", false);
            modelMap.put("errMsg", e.toString());
            return modelMap;
        }
        try {
            ImageHolder imageHolder = null;
            // 开始进行学生信息变更操作
            if (studentImg != null){
                imageHolder = new ImageHolder(studentImg.getOriginalFilename(),studentImg.getInputStream());
            }
            StudentExecution studentExecution = studentService.modifyStudent(student, imageHolder);
            if (studentExecution.getState() == StudentStateEnum.SUCCESS.getState()) {
                modelMap.put("success", true);
            } else {
                modelMap.put("success", false);
                modelMap.put("errMsg", studentExecution.getStateInfo());
            }
        } catch (RuntimeException e) {
            modelMap.put("success", false);
            modelMap.put("errMsg", e.toString());
            return modelMap;
        }
        return modelMap;
    }

    //删除学生信息
    //根据前端路由路径中传递的studentId值删除指定学生信息
    @RequestMapping(value = "/deleteStudent",method = RequestMethod.GET)
    @ResponseBody
    public Map<String,Object> deleteStudent(@RequestParam("studentId") Long studentId){
        Map<String,Object> modelMap = new HashMap<>();
        studentService.deleteStudent(studentId);
        modelMap.put("success",true);
        return modelMap;
    }
}
4.演示

演示一
演示二

结语

本系列虽然结束了,但是作业管理系统要实现的功能还有很多,其实系统的各种功能都涉及信息的增删改查功能,大体实现方法均可以仿照我实现学生信息管理的流程来设计

我个人而言,对于每个功能的设计流程如下:

dao层
service层
controller层
前端界面

每设计完一个层级的功能后,便对该层进行测试

  • 对dao层和service层进行UT测试即可(UT测试的流程我已经在前面展示过了)
  • 对controller层的测试一般与前端相关联,比较简单的方法是将数据以map形式返回到前端,在浏览器的网址直接输入对应的路由

关于作业管理系统,还有很多复杂的功能,例如文件上传、文件下载、图像处理等等,这些我并没有在该系列里展示出来。就我个人理解,这些功能都是在基本功能上的扩展,如果理解了SSM框架增删改查四种基本操作实现方法的话,相信其他功能的实现方法自然很好理解

最后也再次说明一下,我也是spring框架的初学者,写这个系列的目的也是希望像我一样初学SSM框架的人有所帮助吧,通过这个系列向大家展示搭建SSM框架的整个流程

关于这个系列的所有代码和解释如果大家发现哪里有错误的话,欢迎指正

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值