SpringMVC注解开发和请求转发
一、SpringMVC的注解式开发:
1.SpringMVC的注解式开发是指处理器是基于注解的类的开发方式,对于每一个处理器,无需在配置文件中注册,只需在代码中注解即可完成注册。
2.第一个SpringMVC注解应用:
开发步骤:
(1)注册组件扫描器:
<!-- 注册组件扫描器 -->
<context:component-scan base-package="com.edu.mvc.ctrl"/>
<!-- 注册注解驱动 -->
<mvc:annotation-driven/>
(2)定义控制器类,控制器类是一个POJO类。
//@Controller将这个POJO注解为控制器
@Controller
public class MyController {
//@RequestMapping表示当前方法为处理器方法,该注解的属性value值表示指定的URL进行处理和响应
@RequestMapping("/some")
public ModelAndView doSome(HttpServletRequest request,HttpServletResponse response) {
return null;
}
}
注意:SpringMVC的控制器对于请求是属于方法级别的拦截,可以用不同的处理器方法处理不同的请求。
//@Controller将这个POJO注解为控制器
@Controller
public class MyController {
//@RequestMapping表示当前方法为处理器方法,该注解的属性value值表示指定的URL进行处理和响应
@RequestMapping("/some")
public ModelAndView doSome(HttpServletRequest request,HttpServletResponse response) {
ModelAndView mv=new ModelAndView();
mv.addObject("msg","第一个SpringMVC注解应用");
mv.setViewName("/show.jsp");
return mv;
}
//@RequestMapping表示当前方法为处理器方法,该注解的属性value值表示指定的URL进行处理和响应
@RequestMapping("/other")
public ModelAndView doOther(HttpServletRequest request,HttpServletResponse response) {
ModelAndView mv=new ModelAndView();
mv.addObject("msg","第一个SpringMVC注解应用Other");
mv.setViewName("/show.jsp");
return mv;
}
@RequestMapping("/third")
public ModelAndView doThird(HttpServletRequest request,HttpServletResponse response) {
ModelAndView mv=new ModelAndView();
mv.addObject("msg","第一个SpringMVC注解应用Third");
mv.setViewName("/show.jsp");
return mv;
}
}
3.限制请求的方式:
//@Controller将这个POJO注解为控制器
@Controller
public class MyController {
//@RequestMapping表示当前方法为处理器方法,该注解的属性value值表示指定的URL进行处理和响应
@RequestMapping(value="/some",method = RequestMethod.POST)
public ModelAndView doSome(HttpServletRequest request,HttpServletResponse response) {
ModelAndView mv=new ModelAndView();
mv.addObject("msg","第一个SpringMVC注解应用");
mv.setViewName("/show.jsp");
return mv;
}
}
4.处理器方法的参数
处理器方法可以包含五类参数,这些参数会在系统调用时由系统自动注入,程序员直接就可以使用,分别是:
HttpServletRequest,HttpServletResponse,HttpSession,用于承载数据的Model,请求参数(表单参数)。
处理器方法参数为请求参数的情况:
(1)逐个参数接收:
@RequestMapping("/other")
public ModelAndView doOther(String name,int age) {
ModelAndView mv=new ModelAndView();
mv.addObject("myname",name);
mv.addObject("myage", age);
mv.setViewName("/show.jsp");
return mv;
}
对于字符编码问题SpringMVC提供了一个字符编码过滤器,只需对其进行配置就可使用:
<!-- 注册字符编码过滤器 -->
<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>
(2)整体参数接收:要求请求参数的名称和对象的属性名相同即可接收
@RequestMapping("/third")
public ModelAndView doThird(Student student) {
ModelAndView mv=new ModelAndView();
mv.addObject("student",student);
mv.setViewName("/show.jsp");
return mv;
}
(3)域属性参数的接收:要求请求参数名为"域属性名.属性"
<form action="third" method="post">
姓名:<input type="text" name="name"/><br>
年龄:<input type="text" name="age"/><br>
学校:<input type="text" name="school.name"/><br>
<input type="submit" value="提交"/>
</form>
@RequestMapping("/third")
public ModelAndView doThird(Student student) {
ModelAndView mv=new ModelAndView();
mv.addObject("student",student);
mv.setViewName("/show.jsp");
return mv;
}
5.处理器方法的返回值,常用的返回值类型有四种:
- ModelAndView
- String
- void
- 返回自定义类型对象
(1)返回ModelAndView:若处理器方法处理完后,需要跳转到其他资源,而且又要在资源间传递数据,可以返回它。
(2)返回String:此时处理器方法的返回值为逻辑视图的名称。
- 如果使用的是InternalResourceViewResolver视图解析器,则返回值为内部资源的逻辑视图名称。
- 如果使用的是BeanNameViewResolver视图解析器,则返回值为配置文件中配置的视图对象的id值。
(3)返回void:使用Servlet API完成视图跳转和数据传递。可以用来处理AJAX请求。
例子:使用AJAX:
gson.jar:谷歌公司提供的将java对象转换为json对象字符串的jar包。
var obj={key1:value1,key2:value2,key3:function(){}};
var arr=[
{key1:value1,key2:value2},
{key1:value1,key2:value2},
{key1:value1,key2:value2},
{key1:value1,key2:value2},
{key1:value1,key2:value2}
];
例子:见SpringMVCAn的get.html
(4)返回Ojbect:处理器方法可以返回Object类型,但是该Object并不是作为逻辑视图出现的,而是作为直接可以在页面上显示的数据出现的。
返回Object对象,需要使用@ResponseBody注解,将转换后的JSON数据放入到响应体中回送给客户端。
将这个Ojbect对象转换为JSON对象,需要导入Jackson的相关jar包。
- jackson-annotations-2.9.8.jar
- jackson-core-2.9.8.jar
- jackson-databind-2.9.8.jar
必须注册mvc注解驱动:
<!-- 注册mvc的注解驱动 -->
<mvc:annotation-driven/>
将Object数据转换为JSON数据,需要由Http消息转换器HttpMessageConverter完成,而转换器的开启,需要由<mvc:annotation-driven/>完成。
二、SpringMVC的核心技术
1.请求转发和重定向:
> 请求转发:
request.getRequestDispatcher("/index.jsp").forward(request,response)
(请求转发前和转发后是同一个请求,属于服务器内部跳转,此时浏览器地址栏为转发前的URL地址)
> 重定向:
response.sendRedirect("main.jsp")
重定向之前和之后总共发送了两次请求,不是同一个请求,此时浏览器地址栏发生变化,地址栏的URL地址为重定向之后的URL地址。
(1)返回ModelAndView的请求转发:默认的方式
语法:
mv.setViewName("forward:/show.jsp")或mv.setViewName("/show.jsp")
注意:请求转发时,不能再使用视图解析的的前缀和后缀拼接,必须给出跳转的完成URI路径。
I.请求转发到页面
ModelAndView mv=new ModelAndView();
mv.addObject("myname",name);
mv.addObject("myage", age);
mv.setViewName("/show.jsp");
II.请求转发到其他Controller:请求参数自动传递给下一个Controller
@RequestMapping("/forward")
public ModelAndView forward(Student student) {
System.out.println("forward()..."+student);
ModelAndView mv=new ModelAndView();
mv.setViewName("forward:last");
return mv;
}
@RequestMapping("/last")
public ModelAndView last(Student student) {
System.out.println("last()..."+student);
ModelAndView mv=new ModelAndView();
mv.addObject("msg", "转发后的控制器方法");
mv.setViewName("/show.jsp");
return mv;
}
III.重定向到页面:
ModelAndView mv=new ModelAndView();
mv.addObject("myname",name);
mv.addObject("myage", age);
mv.setViewName("redirect:/show.jsp");
重定向的参数传递情况:
A. 通过ModelAndView的Model携带参数:当ModelAndView的Model存入数据后,视图解析器会将该Model的键值对以请求参数的形式附加在重定向后的URL地址后面。由于是附加在URL地址后面,所以传递的参数只能是基本类型和String。
@RequestMapping("/redirect")
public ModelAndView forward(Student student) {
System.out.println("redirect()..."+student);
ModelAndView mv=new ModelAndView();
mv.addObject("name", student.getName());
mv.addObject("age", student.getAge());
mv.setViewName("redirect:/show.jsp");
return mv;
}
IV.重定向到Controller
ModelAndView mv=new ModelAndView();
mv.addObject("myname",name);
mv.addObject("myage", age);
mv.setViewName("redirect:last");
A. 通过ModelAndView的Model携带参数:保证目标Controller的形参名称和重定向之前的Controller发送的参数名称相同即可接收,如果是整体接收,则保证目标Controller的形参对象的属性名称和重定向之前的Controller发送的参数名称相同即可。
@RequestMapping("/redirect")
public ModelAndView forward(Student student) {
System.out.println("redirect()..."+student);
ModelAndView mv=new ModelAndView();
mv.addObject("name", student.getName());
mv.addObject("age", student.getAge());
mv.addObject("score", student.getScore());
mv.setViewName("redirect:last");
return mv;
}
@RequestMapping("/last")
public ModelAndView last(Student stu) {
System.out.println("last()..."+stu);
ModelAndView mv=new ModelAndView();
mv.addObject("msg", "转发后的控制器方法");
mv.setViewName("/show.jsp");
return mv;
}
B. 通过HttpSession携带参数
(2)返回String时的请求转发:此时只能使用域对象来传递参数。当处理器方法接收到请求参数时,如果该请求参数是类类型对象的话,则还会将该对象放在request域属性中。
I.请求转发到页面
@RequestMapping("/forward")
public String forward(Student student) {
System.out.println("forward()..."+student)
return "forward:/show.jsp";
}
II.重定向到页面:参数可以通过给控制器方法添加Model形参来携带,原理和返回ModelAndView的重定向到页面相同,也是将请求参数附加在重定向之后的URL地址后面作为请求参数。
@RequestMapping("/rstring")
public String rstring(Student student,Model model) {
System.out.println("forward()..."+student);
model.addAttribute("name", student.getName());
model.addAttribute("age", student.getAge());
return "redirect:/show.jsp";
}
III.重定向到Controller:参数同样可以通过Model携带,原理返回ModelAndView的重定向到Controller相同,即只要保证重定向之前的Model的参数名和目标Controller的方法的参数对象的属性相同即可接收。
@RequestMapping("/rstring")
public String rstring(Student student,Model model) {
System.out.println("forward()..."+student);
model.addAttribute("name", student.getName());
model.addAttribute("age", student.getAge());
model.addAttribute("score", student.getScore());
return "redirect:rlast";
}
@RequestMapping("/rlast")
public String rlast(Student stu) {
System.out.println("rlast()..."+stu);
return "redirect:/show.jsp";
}
(3)返回void类型:只能使用Servlet API来完成参数传递和跳转。