文章目录
- ${参数}表示来自后台
- 参数表示要去向后台
RESTful风格概述
-
RESTful可理解为架构的一组规范,约束条件和原则
-
REST:表述性状态转移(理解为资源在客户端和服务端间传递),此处表述为资源的表述
-
有被引用的必要的东西称为资源,如文本,图片,服务
-
URI可唯一识别资源
-
状态转移:资源在客户端处改变(客户端会修改资源,和服务器保存的资源不同),从而进入后续(另一种)的状态
-
RESTful架构统一客户端访问资源接口——》从而让不同系统之间相互访问资源,可使用同样接口——》便于实现资源共享
-
一言以蔽之:不同类型资源使用相同接口进行访问
-
客户端按照这种约束(统一的接口)与不同资源对接——》有利于不同系统间实现资源共享
风格实例
- 传参形式不同于以往:
- 以前:URL +?+参数名=参数值
- 现在:URL+/+直接写参数值,不需要参数名=参数值了(如被修改的对象,上图的id或course位置)
功能演示
- index页面(显示全部课程信息)
- add界面:添加课程信息的界面
- edit界面:编辑课程信息的界面,会显示课程初始信息(所以会查询的存在,即get请求)
- 增加:初始add界面,点击提交(触发post请求),完成添加——》然后重定向index界面
- 查询:直接index界面(默认浏览器访问为get请求)
- 修改:点击index界面的编辑(触发get请求)——》后台会查询当前信息,并展示在edit界面,修改后点击提交(触发put请求)——》跳转index界面
- 删除:点击index界面的删除(触发delete请求)——》删除完成,然后跳转index界面
RESTful与HTTP
-
对应增删改查
-
SpringMVC默认可以处理post和get请求,对于delete或put请求特殊处理
-
将post请求转换为delete或put请求——》添加HTTPmethod过滤器+JSP页面添加form表单的隐藏域
-
过滤器(web.xml文件中)如下:
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- 导入依赖 SpringMVC+Jackson+JSTL
- 创建实体类(Course)和DAO操作类(CourseDAO类,添加注解@Repository,该类的Map对象模拟数据库)
- 创建Controller类(注解@Controller+依赖注入)
- JSP页面,web.xml和springmvc.xml(开启注解扫描+视图解析器+消息转换器)
@Autowired private CourseDAO courseDAO;
Controller类概述
@Controller
public class CourseController {
@Autowired //依赖注入
private CourseDAO courseDAO; //DAO工具类
/**
* 添加课程
*/
@PostMapping(value = "/add")
public String add(Course course){ //前台数据封装为course对象
courseDAO.add(course);
return "redirect:/getAll"; //发送重定向请求,重新加载页面,进入getAll方法
}
/**
* 查询全部课程
* @return
*/
@GetMapping(value = "/getAll")
public ModelAndView getAll(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("index");
modelAndView.addObject("courses",courseDAO.getAll());
return modelAndView;
}
/**
* 通过id查询课程
*/
@GetMapping(value = "/getById/{id}")
public ModelAndView getById(@PathVariable(value = "id") int id){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("edit");
modelAndView.addObject("course",courseDAO.getById(id));
return modelAndView;
}
/**修改课程
*
*/
@PutMapping(value = "/update")
public String update(Course course){
courseDAO.update(course);
return "redirect:/getAll";
}
/**
* 删除课程
*/
@DeleteMapping(value = "/delete/{id}")
public String delete(@PathVariable(value = "id") int id){
courseDAO.deleteById(id);
return "redirect:/getAll"; //发送重定向请求,重新加载页面,进入getAll方法
}
}
index.jsp
- 先查询全部课程,然后显示全部课程信息
- 关注隐藏域和请求方法的设置
/**
* 查询全部课程
* @return
*/
@GetMapping(value = "/getAll")
public ModelAndView getAll(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("index");
modelAndView.addObject("courses",courseDAO.getAll());
return modelAndView;
}
<c:forEach items="${courses}" var="course">
//写法同第二章的注解,遍历取出一个个对象,为course,然后利用EL表达式
<tr>
<td><input type='checkbox' class='check_item'/></td>
<td>${course.id}</td>
<td>${course.name}</td>
<td>${course.price}</td>
<td>
<form action="${pageContext.request.contextPath}/getById/${course.id}" method="get">
//关注编辑表单设置,请求方法为get
<button class="btn btn-primary btn-sm edit_btn" type="submit">
<span class="glyphicon glyphicon-pencil">编辑</span>
</button>
</form>
</td>
<td>
<form action="${pageContext.request.contextPath}/delete/${course.id}" method="post">
//将删除方法应该为delete,但伪装为post请求
<button class="btn btn-danger btn-sm delete_btn" type="submit">
<input type="hidden" name="_method" value="DELETE"/>
//关注删除表单设置,加入了隐藏域,hidden可知
<span class="glyphicon glyphicon-trash">删除</span>
</button>
</form>
</td>
</tr>
</c:forEach>
Post请求
/**
* 添加课程
*/
@PostMapping(value = "/add")
public String add(Course course){ //前台数据封装为course对象
courseDAO.add(course);
return "redirect:/getAll"; //发送重定向请求,进入getAll方法
}
JSP页面
- add.jsp
<form class="form-horizontal" role="form" action="${pageContext.request.contextPath}/add" method="post"> //获取工程的contextPath
<div class="form-group">
<label class="col-sm-1 control-label">课程编号</label>
<div class="col-sm-3">
<input type="text" class="form-control" name="id" placeholder="请输入课程编号">
</div>
</div>
- 不用RequestMapping来进行根据请求类型的跳转,改用PostMapping表示post请求才能进入该方法
Get请求和put请求
-
index.jsp中点击编辑(get请求,因为下一步是查询现在课程信息,显示在edit页面)——》进入edit页面——》修改,然后submit(put请求,但要伪装为post请求)后修改成功——》跳转到index.jsp
-
查询课程的业务方法,将id作为前台参数传入——》要想将URL的ID赋值给业务方法的形参ID——》使用注解PathVariable
/**
* 通过id查询课程
*/
@GetMapping(value = "/getById/{id}")
public ModelAndView getById(@PathVariable(value = "id") int id){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("edit"); //edit页面
modelAndView.addObject("course",courseDAO.getById(id));
return modelAndView;
}
/**修改课程
*
*/
@PutMapping(value = "/update")
public String update(Course course){
courseDAO.update(course);
return "redirect:/getAll";
}
- 前台需要将ID作为参数传到后台——》利用EL表达式
<form action="${pageContext.request.contextPath}/getById/${course.id}" method="get">
<button class="btn btn-primary btn-sm edit_btn" type="submit">
<span class="glyphicon glyphicon-pencil">编辑</span>
</button>
</form>
JSP页面
- index.jsp页面(get请求,具体内容见上文)
- edit.jsp页面(put请求)
<form class="form-horizontal" role="form" action="${pageContext.request.contextPath}/update" method="post"> //method为post方法
<div class="form-group">
<label class="col-sm-1 control-label">课程编号</label>
<div class="col-sm-3">
<input type="text" value="${course.id}" name="id" readonly="readonly" class="form-control"> //只读,不能修改
</div>
</div>
<div class="form-group">
<label class="col-sm-1 control-label">课程名称</label>
<div class="col-sm-3">
<input type="text" value="${course.name}" name="name" class="form-control">
</div>
</div>
<div class="form-group">
<label class="col-sm-1 control-label">课程价格</label>
<div class="col-sm-3">
<input type="text" value="${course.price}" name="price" class="form-control">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-1 col-sm-3">
<input type="hidden" name="_method" value="PUT"/>
//method为put方法,不能直接用,hidden伪装为post方法(见上面的注释)
<button type="submit" class="btn btn-default">提交</button>
</div>
</div>
</form>
Delete请求
/**
* 删除课程
*/
@DeleteMapping(value = "/delete/{id}")
public String delete(@PathVariable(value = "id") int id){
courseDAO.deleteById(id); //删除课程
return "redirect:/getAll"; //删除完后,重定向,显示全部课程信息
}
JSP页面
- 完整的index.jsp见上文,下方为截取,将delete请求伪装(转换)为post请求
<form action="${pageContext.request.contextPath}/delete/${course.id}" method="post">
<button class="btn btn-danger btn-sm delete_btn" type="submit">
<input type="hidden" name="_method" value="DELETE"/> //隐藏域
<span class="glyphicon glyphicon-trash">删除</span>
</button>
</form>