使用@RequestMapping映射请求
1.1 在控制器的类定义及方法定义处都可标注
@RequestMapping
- 类定义处,提供初步的请求的映射信息,相对于WEB应用的根目录
- 方法处,提供进一步的细分映射信息,若类定义处未标注@RequestMapping,则方法处标记的URL相对于WEB应用的根目录
DispatcherServlet截获请求后,就通过控制器上@RequestMapping提供的映射信息确定请求所对应的处理方法
@RequestMapping("/helloworld")
public String hello(){
System.out.println("hello");
return SUCCESS;
}
1.2 @RequestMapping除了可以使用请求URL映射请求外,还可以使用请求方法
@RequestMapping(value="/helloworld",method=RequestMethod.GET)
public String hello(){
System.out.println("hello");
return SUCCESS;
}
1.3 @RequestMapping支持Ant风格资源地址
-
?:匹配文件名中一个字符
-
*:匹配文件名中的任意字符
-
** :匹配多层路径
处理静态资源
若将DispatcherServlet请求映射配置为/,则Spring MVC将捕获Web容器的所有请求,包括静态资源的请求,SpringMVC会将他们当成一个普通请求处理,因找不到对应处理器而导致错误
解决办法
在SpringMVC配置文件中配置< mvc:default-servlet-handler/>的方式解决静态资源的问题:
- < mvc:default-servlet-handler/> 将在 SpringMVC 上下文中定义一个
DefaultServletHttpRequestHandler,它会对进入 DispatcherServlet 的
请求进行筛查,如果发现是没有经过映射的请求,就将该请求交由 WEB
应用服务器默认的 Servlet 处理,如果不是静态资源的请求,才由
DispatcherServlet 继续处理 - 一般 WEB 应用服务器默认的 Servlet 的名称都是 default。若所使用的
WEB 服务器的默认 Servlet 名称不是 default,则需要通过 defaultservlet-name 属性显式指定
使用@PathVariable映射URL绑定的占位符
通过@PathVariable可以将URL占位符参数绑定到控制器处理方法的入参中:URL中的{xxx}占位符可以通过@PathVariable(“xxx”)绑定到操作方法的入参中
@RequestMapping("/hello/{id}")
public String PathVariableTest(@PathVariable(value="id") Integer id){
System.out.println("hello----"+id);
return SUCCESS;
}
REST
REST:即Representtational State Transfer–资源表现层状态转化
- 资源:网络上的实体或者说是网络上的具体信息,可以是一段文本,一首歌,总之就是一个具体的存在,可以用一个URI指向它,每资源对于一个特定的URI,要获取资源访问它的URI即可
- 表现层:将资源具体呈现出来的形式,叫做它的表现层。比如,文本可以用txt格式表现,也可以用html格式,xml格式,json格式,甚至可以用二进制格式
- 状态转化:每发出一次请求,就代表了客户端和服务器端的一次交互。HTTP协议是无状态协议,即所有的状态保存在服务器上,如果客户端想要操作服务器,必须通过某种手段让服务器发生“状态转换”,而这种转换是建立在表现层之上的,具体就是HTTP协议里面,四个表示操作方式的动词:GET,POST,PUT,DELETE.它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源,PUT用来更新资源,DELETE用来删除资源
- /Student/1 HTTP GET :得到id为1的student
- /Student/ HTTP POST :新增学生
- /Student/1 HTTP DELETE :删除id为1的student
- /Student/1 HTTP PUT:更新id为1的student
简单理解REST,就是用HTTP协议实现的函数声明,URI指定想要操作的资源,HTTP指定请求动作,比如GET还是PUT等
HiddenHttpMethodFilter
浏览器form表单只支持GET与POST请求,而DELETE和POST等method并不支持。Spring添加过滤器,可以将这些请求转化为标准的HTTP方法,使得支持DELETE和PUT等请求
<!-- web.xml配置文件-->
<filter>
<filter-name>RestFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>RestFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<form action="test/put/1" method="post">
<!--使用Input隐藏域 声明name为_method,value为需要转化的请求 -->
<input type="hidden" name="_method" value="PUT">
<input type="submit" value="TEST PUT">
</form>
@RequestMapping("/test/put/{id}")
public String putTest(@PathVariable(value="id") Integer id){
System.out.println("put----"+id);
return SUCCESS;
}
使用@RequestParam绑定请求参数
在处理方法入参时使用@RequestParam可以把URL中的参数或者表单中的参数传递给请求方法
- value:参数名
- required:是否必须。默认为true,表示请求参数中必须包含对应的参数,若不存在,则抛出异常
- defaultValue:默认参数。当没有指定参数时,将使用该默认参数传入方法
@RequestMapping(value="/hello/test",method=RequestMethod.GET)
//@RequestParam绑定的value对应为URL地址传入或表单传入的
public String paramTest(@RequestParam(value="username",required=false) String username,@RequestParam(value="age",defaultValue="22")Integer age){
System.out.println("username--"+username+"age--"+age);
return SUCCESS;
}
如何在控制器处理方法中得到Servlet对象
直接在方法形参中声明Request,Session等,SpringMVC就会将参数自动注入
使用POJO对象绑定请求参数值
SpringMVC会按请求参数名和POJO属性进行自动匹配,自动为该对象填充属性值,支持级联属性
public class Student {
private String name;
private int age;
//Address为另一个POJO类
private Address address;
//...
}
public class Address {
private String province;
private String city;
//...
}
<form action="test/pojo" method="post">
name : <input type="text" name="name"/><br/>
age :<input type="text" name="age"/><br/>
province:<input type="text" name="address.province"/>
city:<input type="text" name="address.city"/>
<input type="submit" value="提交"/>
</form>
@RequestMapping("/test/pojo")
//方法参数传入POJO类即可,SpringMVC自动完成方法参数注入到POJO类
public String pojoTest(Student student){
System.out.println(student);
return SUCCESS;
}
处理模型数据
ModelAndView
处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据
控制器处理方法的返回值如果为ModelAndView,则其既包括视图信息,也包含模型数据信息。
//添加模型数据
MoelAndView addObject(String attributeName, Object attributeValue)
ModelAndView addAllObject(Map<String, ?> modelMap)
//设置视图
void setView(View view)
oid setViewName(String viewName)
@RequestMapping("/test/model")
public ModelAndView modelTest(){
String viewName = SUCCESS;
ModelAndView modelAndView = new ModelAndView();
//设置视图
modelAndView.setViewName(viewName);
//添加模型
modelAndView.addObject("time",new Date());
return modelAndView;
}
JSP页面
<!--请求域中调用ModelAndView传入的模型数据 -->
time : ${requestScope.time}
Map及Model
控制器处理方法入参为org.springframework.ui.Model或者为org.springframework.ui.ModelMap或java.util.Map时,控制器处理方法返回时,Map中的数据会自动添加到模型中
- SpringMVC在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器
- 如果方法入参为Map或者Model类型,SprngMVC会将隐含数据类型的引用传递给这些入参,在控制器处理方法中,可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据
RequestMapping("/test/sessionAttribute")
public String mapTest(Map<String,Object> map){
map.put("time",new Date());
return SUCCESS;
}
@SessionAttributes
若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注@SessionAttributes,SpringMVC将在模型中对应的属性暂存到HttpSession中;@SessionAttributes除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中
//会将隐含模型中所有类型为 User.class 的属性添加到会话中
@SessionAttributes(types=User.class)
//会将隐含对象
@SessionAttributes(value={“user1”, “user2”})
@SessionAttributes(value={"student"},types= {String.class})
@Controller
public class HelloWorld {
private static final String SUCCESS = "success";
//注入模式数据进隐含模型对象
@ModelAttribute("student")
public Student getStudent() {
Student student = new Student("Reyco",21);
return student;
}
//调用隐含模型对象并加以修改
@RequestMapping("/test/sessionAttribute")
public String ModelTest(Map<String,Object> map,@ModelAttribute("student")Student student){
map.put("time",new Date());
student.setAge(25);
return SUCCESS;
}
}
<!--Session域中调用对象 -->
Student: ${sessionScope.student}
关于mvc:annotation-driven
< mvc:annotation-driven>会自动注册以下三个Bean
- RequestMappingHandlerMapping
- RequestMappingHandlerAdapter
- ExceptionHandlerExceptionResolver
还提供以下支持: - 支持使用 ConversionService 实例对表单参数进行类型转换
- 支持使用 @NumberFormat annotation、@DateTimeFormat注解完成数据类型的格式化
- 支持使用 @Valid 注解对 JavaBean 实例进行 JSR 303 验证
- 支持使用 @RequestBody 和 @ResponseBody 注解