SpringMVC 之 RESTful 风格的增删改查
1. 视图和视图解析器
- 视图解析器
- 请求处理方法执行完成后,最终返回一个ModelAndView对象,对于返回String,View 或 ModelMap
等类型的处理方法, SpringMVC 也会在内部将它们装配成一个ModelAndView对象; - SpringMVC借助视图解析器(ViewResolver)得到最终的视图对象(View),最终的视图可以是 JSP,
EXCEL,PDF等各种表现形式的视图;
- 请求处理方法执行完成后,最终返回一个ModelAndView对象,对于返回String,View 或 ModelMap
- 视图
- 视图的作用是渲染模型数据,将模型里的数据以某种形式呈现给客户;
- View 接口,位于
org.springframework.web.servlet
包中; - 视图对象由视图解析器负责实例化.由于视图是无状态的,所以它们不会有线程安全的问题;
2. mvc:view-controller
标签
- 作用: 在不需要Controller处理request请求的情况下,直接将设置的View交给相应的视图解析器解析为
视图;
// 在 springDispatcherServlet-servlet.xml 中配置
<mvc:view-controller path="/自定义网址" view-name="View视图页面名称"/>
// 还需要使用 mvc:annotation-driven 标签,否则,在使用 Controller 处理request请求时,访问
// 该页面,会报异常;
<mvc:annotation-driven></mvc:annotation-driven>
3. 自定义视图
3.1 具体实现步骤
- 建立专门的view包:
cn.itcast.springmvc.views
; - 编写一个View接口的实现类;
- 将
BeanNameViewResolver
配置进springmvc配置文件;
// 1. 创建View接口的实现类
@Component
public class HelloView implements View{
public String getContentType(){
return "text/html;charset=UTF-8";
}
public void render(Map<String,?> model, HttpServletRequest request,
HttpServletResponse response) throws Exception{
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("自定义视图显示");
response.getWriter().flush();
response.getWriter().close();
}
}
// 2. springDispatcherServlet-servlet.xml 中配置视图解析器
<bean id="BeanNameViewResolver"
class="org.springframework.web.servlet.view.BeanNameViewResolver">
<!-- 自定义order,越小越靠前 --
<property name="order" value="30"></property>
</bean>
// 3. demo.java
@Controller
public class HelloWorld{
@RequestMapping(value="/helloworld",method=RequestMethod.GET)
public String helloworld(){
System.out.println("执行成功");
return "helloView";
}
}
4. 请求转发和重定向
- 地址栏是否变化,参数能否取得,发送了几次请求;
- 请求转发:一个请求一个响应;
- 重定向:两个请求两个响应,两个请求之间毫无关系,所以第一个请求里面保存的信息在第二个请求里面无法获得;
// demo.java
@Controller
public class Helloworld{
// 重定向
@RequestMapping(value="/redirect",method=RequestMethod.GET)
public String helloworld(){
System.out.println("程序运行正常");
return "redirect:/1.jsp";
}
// 转发
@RequestMapping(value="/forward",method=RequestMethod.GET)
public String helloworld(){
System.out.println("程序运行正常");
return "forward:/2.jsp";
}
}
5. RESTful SpringMVC CRUD
5.1 REST(Representational State Transfer) 架构的主要原则
- 网络上的所有事物都可被抽象为资源(Resource);
- 每个资源都有一个唯一的资源标识符(Resource Identifier);
- 同一资源具有多种表现形式(xml,json等);
- 对资源的各种操作不会改变资源标识符;
- 所有的操作都是无状态的(Stateless);
- 符合REST原则的架构方式,即可称为RESTful;
// 需求:
// 1. 查询
// * URI: emps
// * 请求方式: GET
// 2. 添加所有员工信息
// 2.1 显示添加页面:
// * URI: emp
// * 请求方式: GET
// 2.2 添加员工
// * URI: emp
// * 请求方式: POST
// * 添加完成后,重定向到 list 页面
// 3. 删除
// * URI: emp/{id}
// * 请求方式: DELETE
// 4. 修改操作 (其中 lastName 不可修改!!)
// 4.1 显示修改页面
// * URI: emp/{id}
// * 请求方式: GET
// 4.2 修改员工信息
// * URI: emp
// * 请求方式: PUT
// * 完成修改,重定向到 list 页面
// index.jsp
显示所有员工信息: <a href="${pageContext.request.contextPath}/emps">显示所有</a>
// list.jsp (显示所有员工信息页面)
<head>
<!-- 引入 jquery 脚本 -->
<script type="text/javascript"
src="${pageContext.request.contextPath}/scripts/jquery-3.2.1.min.js">
</script>
<!-- 使用表单提交 delete 请求 -->
<script type="text/javascript">
$(function(){
$(".deleteCss").click(function(){
var action = $(this).attr("href");
$("#deleteForm").attr("action",action).submit();
<!-- 取消 click 的默认事件 -->
return false;
});
});
</script>
</head>
<body>
<h2>显示所有员工</h2>
<c:if test="${empty requestScope.employees}">
it's nothing...
</c:if>
<c:if test="${not empty requestScope.employees}">
<table border="1" cellpadding="10" cellspacing="2">
<tr>
<td>id</td>
<td>lastName</id>
<td>email</td>
<td>gender</id>
<td>department</td>
<td>edit</id>
<td>delete</td>
</tr>
<c:forEach items="${requestScope.employees}" var="employee">
<tr>
<td>${employee.id}</td>
<td>${employee.lastName}</id>
<td>${employee.email}</td>
<td>${employee.gender == 1 ? 'male' : 'female'}</id>
<td>${employee.department.departmentName}</td>
<td>
<a href="${pageContext.request.contextPath}/emp/${employee.id}">
edit</a></id>
<td>
<a class="deleteCss"
href="${pageContext.request.contextPath}/emp/${employee.id}>
delete
</a>
</td>
</tr>
</c:forEach>
</c:if>
添加员工: <a href="${pageContext.request.contextPath}/emp">添加</a>
<br/>
<!-- 需要执行RESTful风格的删除,需要使用form表单 post 提交 -->
<form id="deleteForm" action="" method="post">
<input type="hidden" name="_method" value="DELETE"/>
</form>
</body>
// add.jsp (添加之前的编辑页面)
// 需要引入 springframework 的标签
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<body>
<h2>添加客户</h2>
<form:form action="${pageContext.request.contextPath}/emp" method="post"
modelAttribute="employee">
lastName:<form:input path="lastName"/><br/>
email:<form:input path="email"/><br/>
gender:<form:radiobuttons path="gender" items="${requestScope.genders}"/><br/>
department:<form:select path="department.id" items="${requestScope.departments}"
itemLabel="departmentName" itemValue="id"/></form:select><br/>
<input type="submit" value="保存"/>
</form:form>
</body>
// edit.jsp (修改页面)
<h2>修改客户</h2>
<form:form action="${pageContext.request.contextPath}/emp" method="post"
modelAttribute="employee">
<input type="hidden" name="_method" value="PUT"/><br/>
<form:hidden path="id"/>
email:<form:input path="email"/><br/>
gender:<form:radiobuttons path="gender" items="${requestScope.genders}"/><br/>
department:<form:select path="department.id" items="${requestScope.departments}"
itemLabel="departmentName" itemValue="id"/></form:select><br/>
<input type="submit" value="修改"/>
</form:form>
</body>
// springDispatcherServlet-servlet.xml 配置文件
// 若将 web.xml 中 的 DispatcherServlet 请求映射配置为 "/", 则 SpringMVC 将捕获 Web 容器
// 的所有请求,包括静态资源的请求, SpringMVC 会将它们当成一个普通请求处理,会找不到对应处理器;
// 可以在 SpringMVC 的配置文件中配置 <mvc:default-servlet-handler/>,以解决静态资源的问题:
// * <mvc:default-servlet-handler/> 将在 SpringMVC 上下文中定义一个
// * DefaultServletHttpRequestHandler, 它会对 DispatcherServlet 的请求进行筛查,
// * 如果发现是没有经过映射的请求,就将该请求交由WEB应用服务器默认的 Servlet 处理,如果不是
// * 静态资源的请求,才由 DispatcherServlet 继续处理;
// 一般 WEB 应用服务器默认的 Servlet 的名称都是 default, 若所使用的 WEB 服务器的默认
// Servlet 名称不是 default, 则需要通过 default-servlet-name 属性显示指定;
<!-- 处理静态资源导入, 例如导入 jquery -->
<mvc:default-servlet-handler/>
<!-- 如果只有 mvc:default-servlet-handler, 注解类失效, 还需要配置 annotation-driven -->
<mvc:annotation-driven></mvc:annotation-driven>
// web.xml
// 默认情况下,PUT和DELETE请求是无法提交表单数据的;
// 解决方案: 在web.xml中配置spring提供的过滤器解决或者在页面中使用form表单设置
<filter>
<filter-name>HttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
将POST请求转化为DELETE或者是PUT
要用_method指定真正的请求参数
-->
<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>
// EmployeeHandler.java
@Controller
public class EmployeeHander{
@Autowired
private EmployeeService employeeService;
@Autowired
private DepartmentService departmentService;
// 跳转进入添加员工信息页面
// 需要查询出性别,全部部门
@RequestMapping(value="/emp",method=RequestMethod.GET)
public String addPre(Map<String,Object> map){
// 1. 查询出全部部门
map.put("departments",departmentService.getDepartments());
// 2. 查出性别
map.put("genders",getGenderUtils());
// 3. 新建承载的 bean, 实现与前台 form 表单的对应
// 在进入 spring form 标签设定 binding 对象页面前,必须有一个 binding 的对象
// 放在 context 中,spring 才能 binding.类似struts的context statck和value stack.
// 可以在 form 表单上通过 modelAttribute 属性指定绑定的模型属性,
// 如果没有指定该属性, 则默认从 request 域对象中读取 command 的表单 bean.
// 如果bean不存在,则会引发异常.
map.put("employee", new Employee());
return "add";
}
// 保存员工信息
@RequestMapping(value="/emp",method=RequestMethod.POST)
public String add(Employee employee){
employeeService.add(employee);
return "redirect:/emps";
}
// 删除员工信息
@RequestMapping(value="/emp/{id}",method=RequestMethod.DELETE)
public String delete(@PathVariable("id") Integer id){
employeeService.delete(id);
return "redirect:/emps";
}
// 修改之前,跳转到修改页面
// lastName 不可修改
@RequestMapping(value="/emp/{id}",method=RequestMethod.GET)
public String editPre(@PathVariable("id") Integer id, Map<String,Object> map){
map.put("departments",departmentService.getDepartments());
map.put("genders",getGenderUtils());
map.put(employee,employeeService.get(id));
return "edit";
}
// 修改
@RequestMapping(value="/emp",method=RequestMethod.PUT)
public String update(Employee employee){
employeeService.save(employee);
return "redirect:/emps";
}
// 保证 lastName 不能修改,且值不变
@ModelAttribute
public void getEmployeeById(@RequestParam(value="id",required=false) Integer id,
Map<String,Object> map){
if(null != id){
map.put("employee",employeeService.get(id));
}
}
// 查询所有员工
@RequestMapping(value="/emps",method=RequestMethod.GET)
public String list(Map<String,Object> map){
map.put("employees",employeeService.findAll());
return "list";
}
// 模拟从 LOV(list of value) 数据库查询出 gender 的值
private Map<String, String> getGenderUtils(){
Map<String,String> genders = new HashMap<String,String>();
genders.put("1","male");
genders.put("0","female");
return genders;
}
}
参考资料
SpringMVC 之 RESTful 风格的增删改查的更多相关文章
- nodejs+express+mysql实现restful风格的增删改查示例
首先,放上项目github地址:https://github.com/codethereforam/express-mysql-demo 一.前言 之前学的java,一直用的ssm框架写后台.前段时间 ...
- 进入全屏 nodejs+express+mysql实现restful风格的增删改查示例
首先,放上项目github地址:https://github.com/codethereforam/express-mysql-demo 一.前言 之前学的java,一直用的ssm框架写后台.前段时间 ...
- REST风格的增删改查(1)
一.RESTFUL风格的CRUD(增删改查)案例 1.需求: ①显示所有员工信息:URI:emps,请求方式:GET ②添加员工所有信息:显示添加页面:URI:emp,请求方式:GET, 添加员工信息 ...
- SpringMVC框架下数据的增删改查,数据类型转换,数据格式化,数据校验,错误输入的消息回显
在eclipse中javaEE环境下: 这儿并没有连接数据库,而是将数据存放在map集合中: 将各种架包导入lib下... web.xml文件配置为 <?xml version="1. ...
- ztree使用系列三(ztree与springmvc+spring+mybatis整合实现增删改查)
在springmvc+spring+mybatis里整合ztree实现增删改查,上一篇已经写了demo,以下就仅仅贴出各层实现功能的代码: Jsp页面实现功能的js代码例如以下: <script ...
- idea+spring4+springmvc+mybatis+maven实现简单增删改查CRUD
在学习spring4+springmvc+mybatis的ssm框架,idea整合简单实现增删改查功能,在这里记录一下. 原文在这里:https://my.oschina.net/finchxu/bl ...
- REST风格的增删改查(2)
一.源码 1.页面 index.jsp <a href="emps">List All Employee</a> <br><br> ...
- 如何用Spring框架的<form:form>标签实现REST风格的增删改查操作
1.首先创建两个bean类,Employee(职工)和Department(部门),一个部门可以有多个职工 Employee类(属性:职工ID:id:姓名:lastName:邮箱:email:性别:g ...
- maven+springMVC+mybatis+easyUI管理用户增删改查
1.项目演示图 2.项目简单介绍 项目分为两个projectdomain和manager.project结构例如以下图所看到的.当中domain是Maven javaproject主要完毕对数据库的操 ...
随机推荐
- Atitit.jquery 版本新特性attilax总结
Atitit.jquery 版本新特性attilax总结 1. Jq1.4 1 2. 1.5 1 3. 1.6 3 4. Jq1.7 3 ⒉提升了事件委派时的性能有了大幅度的提升,尤其是在ie7下: ...
- Atitit. Class 元数据的反射操作 api apache 工具
Atitit. Class 元数据的反射操作 api apache 工具 1 BeanUtils & PropertyUtils & MethodUtils类使用方法 - 短裤党 ...
- html页面中js判断浏览器是否是IE浏览器及IE浏览器版本
HTML里: HTML代码中,在编写网页代码时,各种浏览器的兼容性是个必须考虑的问题,有些时候无法找到适合所有浏览器的写法,就只能写根据浏览器种类区别的代码,这时就要用到判断代码了.在HTML代码中, ...
- lua的时间和日期函数
lua的时间和日期函数 -- ::| 分类: Lua | 标签:lua 时间 函数 |举报|字号 订阅 下载LOFTER客户端 --获取当前的时间戳,单位是秒. time=os.time(); pri ...
- 李洪强和你一起学习前端之(1)Html基础
1 快捷键的认识(虽然我用的是MAC,但是这里以windows快捷键来讲,但是MAC电脑可以把Ctrl换成command试试) Ctrl + c 复制 Ctrl + v 粘贴 Ctrl + a ...
- CRM认识的误区
众所周知,CRM,就是平时说的“客户关系管理”,指用CRM来管理 企业与客户之间的关系.纵观整个IT圈子,做CRM的厂商比比皆是,每个厂商都有自己的产品宣言,令人眼花缭乱.但是领很多老板们不解的是,我 ...
- IOS7.1-7.1.1越狱后无法读取越狱文件的解决办法
IOS7.1-7.1.1越狱后无法读取越狱文件的解决办法 申明: 下面安装PP源的方法已经失效,请不用按照下面的方法操作. 更新最新的方法,在cydia中搜索源 apple fil ...
- Master Sudoku:Get The Skill
自己做的小游戏 google play store: https://play.google.com/store/apps/details?id=com.ffipp.sodoku app store: ...
- 线程同步工具CountDownLatch
CountDownLatch的一个非常典型的应用场景是:有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以继续往下执行.假如我们这个想要继续往下执行的任务调用一个CountDownLatc ...
- usb 安装系统
写在前面 本文是先安装windows再安装linux,并通过windows引导linux的启动项.这样方便linux的反复重装.折腾等. 光盘安装和U盘安装基本差不多,只是U盘安装多了把镜像文件写到U ...