SpringMVC02--SpringMVC注解式开发
1.1 @RequestMapping 定义请求规则
1.1.1 指定模块名称
通过@RequestMapping 注解可以定义处理器对于请求的映射规则。该注解可以注解在方法上,也可以注解在类上,但意义是不同的。value 属性值常以“/”开始。
@RequestMapping 的 value 属性用于定义所匹配请求的 URI。但对于注解在方法上与类上,其 value 属性所指定的 URI,意义是不同的。
一个@Controller 所注解的类中,可以定义多个处理器方法。当然,不同的处理器方法所匹配的 URI 是不同的。这些不同的 URI 被指定在注解于方法之上的@RequestMapping 的 value 属性中。但若这些请求具有相同的 URI 部分,则这些相同的 URI,可以被抽取到注解在类之上的@RequestMapping 的 value 属性中。此时的这个 URI 表示模块的名称。URI 的请求是相对于 Web 的根目录。
换个角度说,要访问处理器的指定方法,必须要在方法指定 URI 之前加上处理器类前定义的模块名称。
controller
@Controller
public class MyController {
@RequestMapping(value = {"/some.do","first.do"})
public ModelAndView doSome(){
ModelAndView mv = new ModelAndView();
mv.addObject("msg","欢迎使用springmvc做web开发");
mv.addObject("fun","执行的是doSome方法");
mv.setViewName("show");
return mv;
}
@RequestMapping(value = {"other.do","secend.do"})
public ModelAndView doOther(){
ModelAndView mv = new ModelAndView();
mv.addObject("msg","欢迎使用springmvc做web开发");
mv.addObject("fun","执行的是doOther方法");
mv.setViewName("other");
return mv;
}
}
other.jsp
show.jsp
index.jsp
运行结果:
1.1.2 对请求提交方式的定义
对于@RequestMapping,其有一个属性 method,用于对被注解方法所处理请求的提交方式进行限制,即只有满足该method属性指定的提交方式的请求,才会执行该被注解方法。
Method 属性的取值为 RequestMethod 枚举常量。常用的为RequestMethod.GET 与 RequestMethod.POST,分别表示提交方式的匹配规则为 GET 与 POST 提交。
上述处理器方法只能处理 GET 方式提交的请求。客户端浏览器常用的请求方式,及其提交方式有以下几种:
序号 | 请求方式 | 提交方式 |
---|---|---|
1 | 表单请求 | 默认为GET,可以指定POST |
2 | Ajax请求 | 默认为GET,可以指定POST |
3 | 地址栏请求 | GET请求 |
4 | 超链接请求 | GET请求 |
5 | src资源路径请求 | GET请求 |
也就是说,只要指定了处理器方法匹配的请求提交方式为 POST,则相当于指定了请求发送的方式:要么使用表单请求,要么使用 AJAX 请求。其它请求方式被禁用。
当然,若不指定 method 属性,则无论是 GET 还是 POST 提交方式,均可匹配。即对于请求的提交方式无要求。
1.2 处理器方法的参数
处理器方法可以包含以下四类参数,这些参数会在系统调用时由系统自动赋值,即程序员可在方法内直接使用。
- HttpServletRequest
- HttpServletResponse
- HttpSession
- 请求中所携带的请求参数
1.2.1 逐个请求接收
修改index.jsp页面:
修改处理器MyController:
@RequestMapping(value = "/receiveproperty.do",method = RequestMethod.POST)
public ModelAndView doReceiveproperty(String name,Integer age){
System.out.println("doReceiveproperty:"+"name="+name+",age="+age);
ModelAndView mv = new ModelAndView();
mv.addObject("name",name);
mv.addObject("age",age);
mv.setViewName("show");
return mv;
}
添加show.jsp页面:
运行结果:
1.2.2 请求参数中文乱码问题
对于前面所接收的请求参数,若含有中文,则会出现中文乱码问题。Spring 对于请求参数中的中文乱码问题,给出了专门的字符集过滤器:spring-web-5.2.5.RELEASE.jar 的 org.springframework.web.filter 包下的 CharacterEncodingFilter 类。
1)解决方案
在 web.xml 中注册字符集过滤器,即可解决 Spring 的请求参数的中文乱码问题。不过,最好将该过滤器注册在其它过滤器之前。因为过滤器的执行是按照其注册顺序进行的。
<!--注册声明过滤器,解决post请求乱码的问题-->
<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>
<!--强制请求对象(HttpServletRequest)使用encoding编码的值-->
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<!--强制应答对象(HttpServletResponse)使用encoding编码的值-->
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2)源码分析
字符集设置核心方法:
1.2.3 校正请求参数名@RequestParam
修改index.jsp页面:
修改处理器MyController:
/**
* 请求中参数名和处理器方法的形参名不一样
* @RequestParam: 逐个接收请求参数中, 解决请求中参数名形参名不一样的问题
* 属性: 1. value 请求中的参数名称
* 2. required 是一个boolean,默认是true
* true:表示请求中必须包含此参数。
*/
@RequestMapping(value = "/receiveparam.do",method = RequestMethod.POST)
public ModelAndView doReceiveparam(@RequestParam(value = "rname",required = false) String name,
@RequestParam(value = "rage",required = false) Integer age){
System.out.println("doReceiveparam:"+"name="+name+",age="+age);
ModelAndView mv = new ModelAndView();
mv.addObject("name",name);
mv.addObject("age",age);
mv.setViewName("show");
return mv;
}
运行结果:
1.2.4 对象参数接收
定义Student类:
package com.suyv.vo;
public class Student {
private String name;
private Integer age;
public Student() {
System.out.println("Student的无参构造函数");
}
public String getName() {
System.out.println("name="+name);
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
System.out.println("age="+age);
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
修改index.jsp页面:
修改处理器MyController:
@RequestMapping(value = "/receiveobject.do",method = RequestMethod.POST)
public ModelAndView doReceiveobject(Student mystudent){
System.out.println("doReceiveobject:"+"name="+mystudent.getName()+",age="+mystudent.getAge());
ModelAndView mv = new ModelAndView();
mv.addObject("name",mystudent.getName());
mv.addObject("age",mystudent.getAge());
mv.addObject("student",mystudent);
mv.setViewName("show");
return mv;
}
修改show.jsp页面:
运行结果:
1.3 处理器方法的返回值
使用@Controller 注解的处理器的处理器方法,其返回值常用的有四种类型:
- 第一种:ModelAndView
- 第二种:String
- 第三种:无返回值 void
- 第四种:返回自定义类型对象
根据不同的情况,使用不同的返回值。
1.3.1 返回 ModelAndView
1.3.2 返回String
修改控制器MyController:
1.3.3 返回void
1.3.4 返回对象 Object
1.4 url-pattern
1.4.1 配置详解
1)*.do
在没有特殊要求的情况下,SpringMVC 的中央调度器 DispatcherServlet 的<url-pattern/>
常使用后辍匹配方式,如写为*.do 或者 *.action, *.mvc 等。
2) /
可以写为/,因为 DispatcherServlet 会将向静态资源的获取请求,例如.css、.js、.jpg、.png等资源的获取请求,当作是一个普通的 Controller 请求。中央调度器会调用处理器映射器为其查找相应的处理器。当然也是找不到的,所以在这种情况下,所有的静态资源获取请求也均会报 404 错误。
2.4.2 静态资源访问
<url-pattern/>
的值并不是说写为/后,静态资源就无法访问了。经过一些配置后,该问题也是可以解决的。
1)使用<mvc:default-servlet-handler/>
声明了 <mvc:default-servlet-handler />
后 ,springmvc 框 架 会 在 容 器 中 创 建 DefaultServletHttpRequestHandler 处理器对象。它会像一个检查员,对进入 DispatcherServlet的 URL 进行筛查,如果发现是静态资源的请求,就将该请求转由 Web 应用服务器默认的 Servlet 处理。一般的服务器都有默认的 Servlet。
在 Tomcat 中,有一个专门用于处理静态资源访问的 Servlet 名叫 DefaultServlet。其<servlet-name/>
为 default。可以处理各种静态资源访问请求。该 Servlet 注册在 Tomcat 服务器的 web.xml 中。在 Tomcat 安装目录/conf/web.xml。
2)使用<mvc:resources/>
方法1:
方法2:
3)声明注解驱动
解决动态资源和静态资源冲突的问题,在 springmvc 配置文件加入:
<mvc:annotation-driven />