一.restful简介
1.REST
- Representational State Transfer 表现层资源状态转移
- 资源:服务器看作是很多离散的资源集合
- 资源状态的表述:多种格式
- 状态转移:在客户端和服务器端之间转移资源状态的表述
2.RESTful
- 不使用?键值对来携带参数,而是直接将数据作为URL的一部分
- 使用四个表示操作方式的动词来解决操作
3.如何实现四个操作方式(浏览器只提供两个)
- 配置过滤器
- HiddenHttpMethodFilter(转换请求方式)
- 条件
- 当前的请求方式为post
- 当前的请求参数_method
二.restful的案例
1.配置文件框架
①配置文件
②web.xml配置文件注意事项
- 编码过滤器需要配置到其他过滤器之前,因为需要最先进行编码
- springmvc.xml文件可重新配置位置到resources的位置中
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<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.xml注意事项
- 若只开启视图控制器,则不能跳转servlet
- 若只配置默认servlet,则只有默认servlet处理请求
- 配置默认servlet:dispatcherservlet无法处理静态资源
- 故需要开启mvc注解驱动
- 视图控制器跳转 + servlet服务
- 先由dispatcherservlet处理,处理不了交给默认servlet处理
<context:component-scan base-package="com.atguigu"></context:component-scan>
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/WEB-INF/templates/"/>
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8" />
</bean>
</property>
</bean>
</property>
</bean>
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<mvc:annotation-driven></mvc:annotation-driven>
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>
<mvc:view-controller path="/to/add" view-name="employee_add"></mvc:view-controller>
2.功能框架
①框架
②代码
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>
<a th:href="@{/employee}">查询所有的员工信息</a>
@RequestMapping(value = "/employee",method = RequestMethod.GET)
public String getAllEmployee(Model model){
//获取所有的员工信息
Collection<Employee> allEmployee = employeeDao.getAll();
//将员工信息在请求域中共享
model.addAttribute("allEmployee",allEmployee);
//跳转列表页面
return "employee_list";
}
<a th:href="@{/to/add}">add</a>
<mvc:view-controller path="/to/add" view-name="employee_add"></mvc:view-controller>
<form th:action="@{/employee}" method="post">
@RequestMapping(value = "/employee",method = RequestMethod.GET)
public String getAllEmployee(Model model){
//获取所有的员工信息
Collection<Employee> allEmployee = employeeDao.getAll();
//将员工信息在请求域中共享
model.addAttribute("allEmployee",allEmployee);
//跳转列表页面
return "employee_list";
}
@RequestMapping(value = "/employee",method = RequestMethod.POST)
public String addEmployee(Employee employee){
//保存员工信息
employeeDao.save(employee);
//重定向到列表功能:/employee
return "redirect:/employee";
}
- 配置put(需要先获取employee信息然后回显到页面中)
<a th:href="@{'/employee/'+${employee.id}}">update</a>
@RequestMapping(value = "/employee/{id}",method = RequestMethod.GET)
public String toUpdate(@PathVariable("id") Integer id,Model model){
//根据id查询员工信息
Employee employee = employeeDao.get(id);
//将员工信息共享到请求域中
model.addAttribute("employee",employee);
//跳转到employee_update.html
return "employee_update";
}
<form th:action="@{/employee}" method="post">
@RequestMapping(value = "/employee",method = RequestMethod.GET)
public String getAllEmployee(Model model){
//获取所有的员工信息
Collection<Employee> allEmployee = employeeDao.getAll();
//将员工信息在请求域中共享
model.addAttribute("allEmployee",allEmployee);
//跳转列表页面
return "employee_list";
}
@RequestMapping(value = "/employee",method = RequestMethod.POST)
public String addEmployee(Employee employee){
//保存员工信息
employeeDao.save(employee);
//重定向到列表功能:/employee
return "redirect:/employee";
}
<a class="deleteA" @click="deleteEmployee()" th:href="@{'/employee/'+${employee.id}}">delete</a>
<form method="post">
<input type="hidden" name="_method" value="delete">
</form>
var vue = new Vue({
el:"#app",
methods:{
deleteEmployee(){
//获取form表单
var form=document.getElementsByTagName("form")[0];
//将超链接的href属性值赋值给form表单的action属性
//表示当前触发事件的标签
form.action = event.target.href;
//将表单提交
form.submit();
event.preventDefault();
}
//阻止超链接的默认行为
}
})
@RequestMapping(value = "/employee/{id}",method = RequestMethod.DELETE)
public String deleteEmployee(@PathVariable("id") Integer id){
//删除员工信息
employeeDao.delete(id);
return "redirect:/employee";
}
@RequestMapping(value = "/employee",method = RequestMethod.GET)
public String getAllEmployee(Model model){
//获取所有的员工信息
Collection<Employee> allEmployee = employeeDao.getAll();
//将员工信息在请求域中共享
model.addAttribute("allEmployee",allEmployee);
//跳转列表页面
return "employee_list";
}
③细节
- 合理利用视图控制器和controller
- 只实现页面跳转,则可用视图控制器(POST)
- 若实现页面跳转,且需要获得信息,则需要Controller(PUT)
- 合理利用形参
- 向域中存数据 Model (PUT)
- 获取请求参数,@PathVariable(“id”) Integer id
- 获取表单信息,可直接封装为对象Employee