SpringMVC视图解析
- 视图解析器
- 作用:通过视图逻辑名,解析指定视图对象。
- 源码解析:当前视图解析器
- UrlBasedViewResolver->180行代码如下:
AbstractUrlBasedView view = (AbstractUrlBasedView)BeanUtils.instantiateClass(this.getViewClass());
- UrlBasedViewResolver->181行代码如下(将逻辑视图名->物理视图名):
view.setUrl(this.getPrefix() + viewName + this.getSuffix());
<!-- 视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
-
视图
- 作用
- 将数据存放到域对象中
- 转发或重定向跳转路径
-
源码解析:
- InternalResourceView->60行代码调用到AbstractView中182行代码,如下:
request.setAttribute(modelName, modelValue);
- InternalResourceView->79行代码,如下:
rd.forward(requestToExpose, response); //转发
-
视图实现类
-
转发视图
1.InternalResourceView
2.JstlView- 属性InternalResourceView子类
- 重定向视图
3.RedirectView
- 具体应用:return “redirect:/xxx.jsp”;
- 源码解析:UrlBasedViewResolver->151行代码如下:
if (viewName.startsWith("redirect:")) { forwardUrl = viewName.substring("redirect:".length()); RedirectView view = new RedirectView(forwardUrl, ...); }
-
注意:
重定向地址由浏览器解析:http://localhost:8080/,为什么没有404?
- RedirectView的134行代码如下:if (this.contextRelative && this.getUrl().startsWith("/")) { targetUrl.append(request.getContextPath()); }
-
-
总结:只要重定向逻辑视图名,以“redirect:/”开头,底层就会创建RedirectView对象,并拼接/+当前项目名称到URL中。所以不用担心路径问题。
RestFul的CRUD综合案例
使用Spring表单标签优化传统表单标签
- 优势
- 简化代码
- 数据回显
- 使用标签步骤
1. 导入相关spring核心jar包
2. 引入标签库
<%@ taglib prefix=“form” uri=“http://www.springframework.org/tags/form” %>
3. form:xxx - 注意事项
- 属性
1. path:类似传统表单中的name,自带数据回显属性功能。
2. items:需要转换表单项的数据
3. itemLable:设置下拉列表的显示文本
4. itemValue:设置下拉列表的真实数值 - 使用spring表单,会默认从request域对象(名为:command对象)中回显数据,
可以使用modelAttibute属性,设置域对象中的可以。
- 属性
<%--
Created by IntelliJ IDEA.
User: fjc02
Date: 2020/3/16
Time: 14:31
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<title>更新员工</title>
</head>
<body>
<c:if test="${empty employee.id}" var="flag">
<h1 align="center">添加员工信息-spring表单</h1>
</c:if>
<c:if test="${!flag}">
<h1 align="center">修改员工信息-spring表单</h1>
</c:if>
<div align="center">
<form:form action="${pageContext.request.contextPath}/emp" method="POST" modelAttribute="employee">
<%-- 设置修改员工信息以PUT方式提交--%>
<c:if test="${!flag}">
<form:hidden path="id"/>
<%-- <form:hidden path="_method"/> 错误的--%>
<input type="hidden" name="_method" value="PUT">
</c:if>
<table>
<tr>
<td>LastName</td>
<td>
<form:input path="lastName"/>
</td>
</tr>
<tr>
<td>Email</td>
<td>
<form:input path="email"/>
</td>
</tr>
<tr>
<td>Gender</td>
<td>
<%--
map<key,value> -> (0,"女")(1,"男")
--%>
<form:radiobuttons path="gender" items="${requestScope.genders}"/>
</td>
</tr>
<tr>
<td>DeptName</td>
<td>
<form:select path="department.id" items="${requestScope.depts}"
itemLabel="departmentName" itemValue="id"></form:select>
</td>
</tr>
<br>
<tr align="right">
<td colspan="2">
<c:if test="${flag}">
<input type="submit" value="添加员工信息">
</c:if>
<c:if test="${!flag}">
<input type="submit" value="修改员工信息">
</c:if>
</td>
</tr>
</table>
</form:form>
<hr>
<h1 align="center">添加员工信息-传统表单方式</h1>
<form action="${pageContext.request.contextPath}/emp" method="post">
<table align="center">
<tr>
<td>
<br>LastName:
<input type="text" name="lastName">
</td>
</tr>
<tr>
<td>
<br>Email:
<input type="text" name="email">
</td>
</tr>
<tr>
<td>
<br>Gender:
<input type="radio" name="gender" value="0" >女
<input type="radio" name="gender" value="1">男
</td>
</tr>
<tr>
<td>
<br>DeptName:
<select name="department.id">
<c:forEach var="dept" items="${requestScope.depts}">
<option value="${dept.id}">${dept.departmentName}</option>
</c:forEach>
</select>
</td>
</tr>
<tr align="right">
<td colspan="2">
<br>
<input type="submit" value="添加员工信息">
</td>
</tr>
</table>
</form>
</body>
</html>
完成修改功能(Restful)的注意事项
- 提交表单的方式:PUT
- 必须携带id数据
<c:if test="${!flag}">
<form:hidden path="id"/>
<%--<form:hidden path="_method"/> 错误的--%>
<input type="hidden" name="_method" value="PUT">
</c:if>
完成删除员工功能的注意事项
- 提交表单的方式:DELETE
- 问题:超链接默认提交方式为:GET
- 解决思路
1. 准备一个以DELETE方式提交的表单。
2. 单击超链接,获取超链接中的url(href属性),为表单(DELETE)中的action属性赋值
3. 触发提交(submit)表单事件
4. 取消超链接默认行为(return false) - springMVC中解决静态资源加载问题
- 问题:默认静态资源会被DispatcherServlet拦截到.
因为DispatcherServlet的URL配置的:“/” - 如:引入外部jQuery文件时,具体问题如下:
No mapping found for HTTP request with URI [/day07_springMVC_RestDemo/static/js/jquery-1.7.2.min.js] in DispatcherServlet with name ‘dispatchServlet’
- 具体解决方案
- 在springMVC核心配置文件中添加如下配置
<mvc:default-servlet-handler default-servlet-name=“default”/> - 作用:如URL没有指定请求处理器处理,就交给当前配置的default,Servlet处理
- 注意:一旦添加该配置文件,之前所有的请求均请求不到DispatcherServlet映射的
Controller。 - 所有必须在添加一个配置文件,如下
mvc:annotation-driven/
- 在springMVC核心配置文件中添加如下配置
- 扩展(了解)
- default默认Servlet是Tomcat提供的。
- 之所以可以解决静态资源加载问题:defaultServlet的Url配置:/
- 当URL配置相同时,优先识别程序员属性的URL,再识别Tomcat自动的URL。
- “/”:除了【*.jsp】路径之外的所有路径,原因如下:
<servlet-mapping> <servlet-name>jsp</servlet-name> <url-pattern>*.jsp</url-pattern> <url-pattern>*.jspx</url-pattern> </servlet-mapping>
- 问题:默认静态资源会被DispatcherServlet拦截到.
注意:【*.jsp】的优先级高于【/】 配置规则
<script src="${pageContext.request.contextPath}/static/js/jquery-1.7.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
//alert($); //验证jQuery导入成功
/*
1. 准备一个以DELETE方式提交的表单。
2. 单击超链接,获取超链接中的url(href属性),为表单(DELETE)中的action属性赋值
3. 触发提交(submit)表单事件
4. 取消超链接默认行为(return false)
*/
$(function(){
//单击超链接事件
$(".delEmp").click(function(){
if(!confirm("确定删除该员工吗?")){
return false;
}
//获取超链接中的url(href属性)
var url = $(this).attr("href"); //this.href;
//为表单(DELETE)中的action属性赋值
$("#delForm").attr("action",url);
//3. 触发提交(submit)表单事件
$("#delForm").submit();
//4. 取消超链接默认行为(return false)
return false;
});
});
</script>