域对象共享数据
使用servletAPI向request域对象共享数据



使用ModelAndView向request域对象共享数据
- ModelAndView有Model和View的功能
- Model主要用于向请求域共享数据
- View主要用于设置视图,实现页面跳转


使用Model向request域对象共享数据

使用map向request域对象共享数据

使用ModelMap向request域对象共享数据

Model、ModelMap、Map的关系
Map与Model都是接口,无法直接创建对象,通过实现类创建。
ModelMap是一个普通类。
通过反射对象名.getClass().getName()获得的类型一致,都是BindingAwareModelMap。
向session域共享数据


向appllication域共享数据


SpringMVC视图
SpringMVC中的视图是view接口,视图的作用是渲染数据,将模型Model中的数据展示给用户
SpringMVC视图的种类很多,默认有转发视图(InternalReaourceView)和重定向视图(RedirectView)。
工程引入jstl 的依赖,转发视图会自动转换为jstlView
若使用的视图技术为Thymeleaf,在SpringMVC的配置文件中配置了Thymeleaf的视图解析器,由此视图解析器解析之后所得到的是ThymeleafView。
Thymeleaf
在控制器方法中设置的视图名称没有任何前缀时,此时的视图名称会被SpringMVC配置文件中所配置的视图解析器 解析,视图名称拼接视图前缀和视图后缀 所得到的最终路径,会通过转发的方式实现跳转。 解析器解析之后所得到的是ThymeleafView



转发视图
SpringMVC默认的转发视图是InternalResourceView
SpringMVC中创建转发视图的情况:
当控制器方法中所设置的视图名称以"forward"为前缀时,创建internalResourceView 视图,此时视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而时会将前缀"forward"去掉 ,剩余部分作为最终路径通过转发的方式实现跳转。
转发是一次请求:第一次是浏览器发送,第二次是发生在服务器内部(地址栏还是第一次发送的请求地址)。转发可以获得请求域中的数据。可以访问web-inf下的资源。转发不可以跨域
eg:"forward:/","forward:/employee"



转发显示的是转发自己的地址栏
重定向视图
业务完成后,需要使用重定向。
SpringMVC中默认的重定向视图是RedirectView
当控制器方法中所设置的视图名称以"redirect:"为前缀时,创建RedirectView视图 ,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀"redirect:"去掉 ,剩余部分作为最终路径通过重定向的方式实现转发。
两次请求:第一次访问Servlet,第二次访问重定向地址(两次地址不同)。请求不可以获得请求域中的数据。不可以访问web-inf下的资源。转发可以跨域
eg:"redirect:/","redirect:/employyee"



跳转之后,显示的是重定向后的地址栏。
视图控制器view-controller
当控制器方法中,仅仅用来实现页面跳转,即只需要设置视图名称时,可以将处理方法使用view-controller标签进行表示。
XML
<!--视图控制器配置之后,所有转发给重定向都会失效-->
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>
<!--开启mvc的注解驱动-->
<mvc:annotation-driven/>
注:当SpringMVC中设置任何一个view-controller时,其他控制器中的请求映射将会全部失效,此时需要在SpringMVC的核心配置文件中设置开启MVC注解驱动的标签。
使用jsp时使用的视图解析器:
XML
<!--配置解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/templates/"/>
<property name="suffix" value=".jsp"/>
</bean>


RESTFUL
表现层资源状态转移
RESTFUL实现
在HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE
分别对应四种基本操作:GET用来获取资源,POST用来新建资源,DELETE用来删除资源。
- 查询操作 user/1 get请求
- 保存操作 user post请求
- 删除操作 user/1 delete请求
- 更新操作 user put请求
java
@RequestMapping(value = "/user",method = RequestMethod.GET)
public String getAllUser(){
System.out.println("查询所有用户信息");
return "success";
}
//需要使用一个占位符
@RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
public String getUserById(){
System.out.println("根据id查询用户信息");
return "success";
}
@RequestMapping(value = "/user",method = RequestMethod.POST)
public String insert(String username,String password){
System.out.println("添加用户信息:"+username+password);
return "success";
}

HiddenHttpMethodFilter处理PUT和DELETE
浏览器只支持get和post,



RESTFUL案例
员工管理
java
package com.serenity.mvc.bean;
public class Employee {
private Integer id;
private String lastName;
private String email;
private Integer gender;
public Employee() {
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
", gender=" + gender +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
public Employee(Integer id, String lastName, String email, Integer gender) {
this.id = id;
this.lastName = lastName;
this.email = email;
this.gender = gender;
}
}
java
package com.serenity.mvc.dao;
import com.serenity.mvc.bean.Employee;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@Repository
public class employeeDao {
private static Map<Integer, Employee> employees=null;
static {
employees=new HashMap<Integer,Employee>();
employees.put(1001,new Employee(1001,"E-AA","aa@123.com",1));
employees.put(1001,new Employee(1002,"E-BB","bb@123.com",1));
employees.put(1001,new Employee(1003,"E-CC","cc@123.com",0));
employees.put(1001,new Employee(1004,"E-DD","dd@123.com",0));
employees.put(1001,new Employee(1005,"E-EE","ee@123.com",1));
}
private static Integer initId=1006;
public void save(Employee employee){
if (employee.getId()==null){
employee.setId(initId++);
}
employees.put(employee.getId(),employee);
}
public Collection<Employee> getAll(){
return employees.values();
}
public Employee get(Integer id){
return employees.get(id);
}
public void delete(Integer id){
employees.remove(id);
}
}
java
package com.serenity.mvc.controller;
import com.serenity.mvc.bean.Employee;
import com.serenity.mvc.dao.employeeDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class EmployeeController {
@Autowired
private employeeDao employeeDao;
}
功能
|-----------|-------------|--------|
| 功能 | URL地址 | 请求方式 |
| 访问首页 | / | GET |
| 查询全部数据 | /employee | GET |
| 删除 | /employee | DELETE |
| 跳转到添加数据页面 | /toAdd | GET |
| 执行保存 | /employee | POST |
| 跳转到更新数据页面 | /employee/2 | GET |
| 执行更新 | /employee | PUT |
查询全部数据
java
@GetMapping("/employee")
public String getAllEmployee(Model model){
Collection<Employee> employeeList = employeeDao.getAll();
//查询到的数据,在页面中想要访问,想要存储在域对象中
//域对象有request、session、servletContext
model.addAttribute("employeeList",employeeList);
return "employees";
}
遍历数组用each,数据填充用text。在域对象共享数据中。
html
<table>
<tr>
<th colspan="5">Employee Info</th>
</tr>
<tr>
<th>id</th>
<th>lastName</th>
<th>email</th>
<th>gender</th>
<th>options</th>
</tr>
<!--利用${}获取请求域中的数据-->
<tr th:each="employee : ${employeeList}">
<td th:text="${employee.id}"></td>
<td th:text="${employee.lastName}"></td>
<td th:text="${employee.email}"></td>
<td th:text="${employee.gender}"></td>
<td>
<!--获取id信息,用${}获取-->
<a th:href="@{/employee/}+${employee.id}">delete</a>
<a href="">update</a>
</td>
</tr>
</table>

删除功能


html
<form id="deleteForm" method="post">
<input type="hidden" name="_method" value="delete">
</form>
<script type="text/javascript" th:src="@{/static/js/vue.js}"></script>
<script type="text/javascript">
var vue=new Vue({
el:"#dataTable",
methods:{
deleteEmployee:function (event) {
//根据id获取表单元素
var deleteForm= document.getElementById("deleteForm");
//触发点击事件的超链接的href属性赋值给表单的action
deleteForm.action=event.target.href;
//提交表单
deleteForm.submit();
//取消超链接的默认行为
event.preventDefault();
}
}
});
java
//删除完成后,重新跳转到列表页面,需要使用转发或重定向,此处不要之前的地址栏,
//使用重定向
@RequestMapping(value = "/employee/{id}",method = RequestMethod.DELETE)
public String deleteEmployee(@PathVariable("id") Integer id){
employeeDao.delete(id);
return "redirect:/employee";
}
注意:404错误,也有可能是静态资源未找到,需要重新在打war包,因为静态资源未在服务器中。

需要导入新的标签
<!--开放对静态资源的访问-->
<mvc:default-servlet-handler/>

添加功能



java
@RequestMapping(value = "/employee",method = RequestMethod.POST)
public String addEmployee(Employee employee){
employeeDao.save(employee);
return "redirect:/employee";
}
修改功能





添加一个控制类,完成修改的保存操作。

