第三部分 细节知识点
1.REST
什么是REST:
资源状态转化,读者可自行百度了解,这里不再详述:
配置org.springframework.web.filter.HiddenHttpMethodFilter
<!-- 配置org.springframework.web.filter.HiddenHttpMethodFilter: 可以把POST请求转为DELETE或POST请求 -->
<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>
用例:
index.jsp 添加以下代码
<a href="springmvc/testRest/1">Test Rest GET</a><br>
<form action="springmvc/testRest" method="post">
<input type="submit" value="TestRest POST">
</form>
<br>
<form action="springmvc/testRest/1" method="post">
<input type="hidden" name="_method" value="DELETE">
<input type="submit" value="TestRest DELETE">
</form>
<br>
<form action="springmvc/testRest/1" method="post">
<input type="hidden" name="_method" value="PUT">
<input type="submit" value="TestRest PUT">
</form>
<br>
SpringMVCTest.java 添加以下代码
/*
* Rest风格的URL
* 以CRUD为例:
* 新增:/order POST
* 修改:/order/1 PUT
* 获取:/order/1 GET
* 删除:/order/1 DELETE
*
* 如何发送PUT请求与DELETE请求呢?
* 1.需要配置HiddenHttpMethodFilter
* 2.需要发送POST请求
* 3.需要在发送POST请求时携带一个name="_method"的隐藏域,值为PUT或DELETE
*
* 在SpringMVC的目标方法中如何得到id呢?
* 使用@PathVariable注解
* */
@RequestMapping(value = "/testRest/{id}",method = RequestMethod.GET)
public String testRest(@PathVariable Integer id) {
System.out.println("testRest GET: " + id);
return SUCCESS;
}
@RequestMapping(value = "/testRest",method = RequestMethod.POST)
public String testRest() {
System.out.println("testRest POST");
return SUCCESS;
}
@RequestMapping(value = "/testRest/{id}",method = RequestMethod.DELETE)
public String testRestDelete(@PathVariable Integer id) {
System.out.println("testRest DELETE: " + id);
return SUCCESS;
}
@RequestMapping(value = "/testRest/{id}",method = RequestMethod.PUT)
public String testRestPut(@PathVariable Integer id) {
System.out.println("testRest PUT: " + id);
return SUCCESS;
}
2.POJO对象绑定请求参数
- SpringMVC会按请求参数名和POJO属性名进行自动匹配,自动为该对象填充属性值。支持级联属性。如dept.deptId、dept.address.tel等
测试:
- User.java(省略setter与getter、toString方法)
public class User {
private String username;
private String password;
private String email;
private int age;
private Address address;
}
- Address.java(省略setter与getter、toString方法)
public class Address {
private String province;
private String city;
}
- index.jsp添加
<form action="springmvc/testPojo" method="post">
username: <input type="text" name="username"/>
<br>
password: <input type="password" name="password"/>
<br>
email: <input type="text" name="email"/>
<br>
age: <input type="text" name="age"/>
<br>
province: <input type="text" name="address.province"/>
<br>
city: <input type="text" name="address.city"/>
<br>
<input type="submit" value="Submit"/>
</form>
- SpringMVCTest.java添加
/*
* SpringMVC 会按请求参数名和POJO属性名进行自动匹配
* 自动为该对象填充属性值。支持联机属性
* 如dept.deptId、dept.address.tel等
* */
@RequestMapping(value = "/testPojo",method = RequestMethod.POST)
public String testPojo(User user) {
System.out.println("testPojo: " + user);
return SUCCESS;
}
3.使用Servlet API作为参数
- 可以使用Servlet原生的API作为目标方法的参数 具体支持一下类型
用例:
/*
* 可以使用Servlet原生的API作为目标方法的参数 具体支持一下类型
* HttpServletRequest
* HttpServletResponse
* HttpSession
* java.security.Principal
* Local InputStream
* OutputStream
* Reader
* Writer
* */
@RequestMapping("/testServletAPI")
public void testServletAPI(HttpServletRequest request,
HttpServletResponse response,
Writer out) throws IOException {
System.out.println("testServletAPI, " + request + ", " + response);
out.write("Hello Spring MVC");
// return SUCCESS;
}
4.处理模型数据
Spring MVC提供以下几种途径输出模型数据:
- ModelAndView
- 示例:
SpringMVCTest.java添加:
/*
* 目标方法的返回值可以是 ModelAndView 类型。
* 其中可以包含视图和模型信息
* Spring MVC 会把 ModelAndView 的 model 中数据放入到 request 域对象中
* */
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView() {
String viewName = SUCCESS;
ModelAndView modelAndView = new ModelAndView(viewName);
// 添加模型数据到 ModelAndView 中.
modelAndView.addObject("time",new Date());
return modelAndView;
}
index.jsp添加:
<a href="springmvc/testModelAndView">Test ModelAndView</a><br>
sussess.jsp添加:
time:${requestScope.time }
- 注意:这里有一种错误可能使页面无法跳转(导包问题):
正确: :import org.springframework.web.servlet.ModelAndView;
错误: :import org.springframework.web.portlet.ModelAndView;
- Map及Model
- 示例:
SpringMVCTest.java添加:
/*
* 目标方法可以添加 Map 类型(实际上也可以是 Model 类型或ModelMap类型)
* */
@RequestMapping("/testMap")
public String testMap(Map<String,Object> map) {
map.put("names", Arrays.asList("Tom","Jerry","Mike"));
return SUCCESS;
}
index.jsp添加:
<a href="springmvc/testMap">Test Map</a><br>
success.jsp添加:
names:${requestScope.names }
5.视图解析器
5.自定义视图解析器
作用:用来解析自定义视图
常见的视图解析器实现类
这里以使用 BeanNameViewResolver 为例:
示例:
首先需要创建一个包views,然后创建一个HelloView类,HelloView.java实现代码如下
package com.wss.views;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.View;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.Map;
// @Component 将视图放入 IOC 容器里
@Component
public class HelloView implements View {
@Override
public String getContentType() {
return "text/html";
}
@Override
public void render(Map<String, ?> map, HttpServletRequest request,
HttpServletResponse response) throws Exception {
response.getWriter().print("hello View, time: " + new Date());
}
}
springmvc.xml 添加:
<!-- 这一步必不可少。如果没有这一行,SpringMVC将无法从views包中扫描到需要解析的类 -->
<context:component-scan base-package="com.wss.views"></context:component-scan>
<!-- 配置视图 BeanNameViewResolver 解析器:使用视图的名字来解析视图 -->
<!-- 通过 order 属性来定义视图解析器的优先级,order值越小优先级越高 -->
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order" value="100"></property>
</bean>
SpringMVCTest.java添加:
@RequestMapping("/testView")
public String testView() {
System.out.println("Test View");
return "helloView";
}
index.jsp添加:
<a href="https://www.baidu.com">Go to Baidu</a>
6.重定向
- 关于重定向
示例(redirect):
SpringMVCTest.java 添加:
@RequestMapping("/testRedirect")
public String testRedirect() {
System.out.println("testRedirect");
return "redirect:/index.jsp";
}
index.jsp 添加:
<a href="/springmvc/testRedirect">Test Redirect</a>
7.数据的格式化
- 第一步:添加下述标签(必须):
<!-- 在实际开发中通常需要配置 MVC:annotation-driven 标签 -->
<mvc:annotation-driven></mvc:annotation-driven>
- 第二步:在目标属性上添加注解:
例(@DateTimeFormat):
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birth;
8.数据校验
1.如何校验?注解?
a.使用JSR 303验证
b.加入Hibernate Validator验证框架
c.在SpringMVC配置文件中添加<mvc:annotation-driven></mvc:annotation-driven>
d.需要在bean的属性上添加对应的注解
e.在目标方法bean类型参数的前面添加@Valid注解
注意:需要引入相应的jar包
OpenSource -> hibernate-validator文件夹里的jar文件
OpenSource -> hibernate-validator -> lib -> required里的部分文件:
-------classmate.jar
-------jboss-logging.jar
-------validation-api.jar
2.验证出错转向那一个页面?
注意:需校验的Bean对象与其绑定结果对象或错误对象成对出现时,他们之间不允许声明其它入参
3.错误消息?如何显示,如何把错误消息进行国际化
-
JSR 303
-
Hibernate Validator扩展注解
-
SpringMVC数据校验
9.JSON数据实现原理
-
处理JSON
-
负责处理请求与接受信息的对象
-
HttpMessageConverter
10.文件上传
- 文件上传
- 配置MultipartResolver
11.拦截器
- 自定义拦截器
- 示例:
首先创建interceptors,然后创建FirstInterceptor 类,FirstInterceptor .java文件内容如下:
--------------------------------------------------------------------------------------------------------------
package com.wss.interceptors;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FirstInterceptor implements HandlerInterceptor {
/*
* 该方法在目标方法之前被调用
* 若返回值为true,则继续调用后续的拦截器和目标方法
* 若返回值为false,则不会再调用后续的拦截器和目标方法
*
* 可以考虑做权限,日志,事务等
* */
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("FirstInterceptor preHandle");
return true;
}
/*
* 调用目标方法之后,但渲染视图之前
* 可以对请求域中的属性或视图做出修改
* */
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("FirstInterceptor postHandle");
}
/*
* 渲染视图之后被调用,释放资源
* */
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("FirstInterceptor afterCompletion");
}
}
springmvc.xml添加:
<mvc:interceptors>
<!-- 配置自定义的拦截器 -->
<bean class="com.wss.interceptors.FirstInterceptor"></bean>
</mvc:interceptors>
- 拦截器的配置
在springmvc.xml中做出如下改变:
<mvc:interceptors>
<!-- *************************************************************************************** -->
<!-- 配置拦截器(不)作用的路径 -->
<mvc:interceptor>
<mvc:mapping path="/emps"/>
<bean class="com.wss.interceptors.FirstInterceptor"></bean>
</mvc:interceptor>
<!-- *************************************************************************************** -->
<!-- 配置自定义的拦截器 -->
<bean class="com.wss.interceptors.FirstInterceptor"></bean>
</mvc:interceptors>
11.Spring整合SpringMVC
需要进行Spring整合SpringMVC吗?
还是否需要再加入Spring的IOC容器?
是否需要web.xml文件中配置启动Spring IOC容器的ContextLoaderListener?
1.需要:通常情况下,类似于数据源、事务、整合其它框架都是放在Spring的配置文件中(而不是放在SpringMVC的配置文件中)。实际上放入Spring配置文件对应的IOC容器中还有Service和Dao
2.不需要:都放入SpringMVC的配置文件中。也可以分多个Spring的配置文件,然后使用import节点导入其他的配置文件