springMVC后端处理器包括三个部分:
- 映射处理器 (HandlerMapping)
- 控制器 (Controller)
- 视图解析器 (ViewResolver)
博文记录一下控制的实现方式与返回方式
控制器:处理由DispatcherServlet分发的请求
tip:它把用户请求的数据经过业务处理层处理之后分装成一个Model,然后再把Model 返回给对应的View进行展示
springMVC提供多种多种控制器用于继承实现:
1、AbstractController
最简单的控制器, 一个类只能处理一次请求,实现抽象类中的handleRequestInternal方法处理请求
package com.chaol.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
@Controller
@RequestMapping(value="/") //指定类的访问路径
public class HelloController extends AbstractController {
@RequestMapping(value="/hello.action") //指定方法的访问路径
// 像这样配置,用户的请求如果是/hello.action,则映射到了这个controller ,当然,这里的 ‘/’是指项目的根目录
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
throws Exception {
ModelAndView mav = new ModelAndView("login/login");
return mav;
}
}
2、MultiActionController
可以将多个请求处理方法,放在一个控制器类中 ( 本质就是一个类);那么这个时候,用户请求怎么去匹配到相对应的控制器处理方法呢?
-- 需要配置一个方法名解析器,方法名解析器解析用户请求的 URI 资源请求符,去寻找对应的控制器方法处理请求,比如URI 为/test/getUser.action, 那么此时,由控制器配置找到要处理请求的控制器(类),由方法名解析器解析得到控制器中处理请求的方法getUser(..),这个方法名和请求URI 中的标识符一致
控制层代码:
package com.chaol.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
public class LsjmUserController extends MultiActionController {
public ModelAndView getUser(HttpServletRequest request, HttpServletResponse response)
{
ModelAndView mav = new ModelAndView("login/userManage");
mav.addObject("msg", "这里是用户管理controller");
return mav;
}
public ModelAndView addUser(HttpServletRequest request, HttpServletResponse response)
{
ModelAndView mav = new ModelAndView("login/userManage");
mav.addObject("msg", "管理用户-->添加一条用户信息");
return mav;
}
}
springmvc-servlet.xml配置信息:
比如下面的配置中,映射处理器映射了/user/*类型的请求 用 lsjmUserController控制器来处理,具体的处理方法由方法名解析器去解析
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置 映射处理器 SimpleUrlHandlerMapping -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello.action">helloController</prop>
<prop key="/user/*">lsjmUserController</prop>
</props>
</property>
<!-- order值越小,映射处理器优先级越高 -->
<property name="order" value="1"></property>
</bean>
<!-- 配置控制器 -->
<bean id="helloController" class="com.chaol.controller.HelloController"></bean>
<bean id="lsjmUserController" class="com.chaol.controller.LsjmUserController"></bean>
<!-- 配置 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 配置方法名解析器 -->
<bean id="internalPathMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver"></bean>
</beans>
使用注解实现控制器配置
和前面的映射处理配置相差不大,不过有几点不同处需要注意
1、映射处理器、控制器注解驱动的启动,自动扫描开启,
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解自动扫描 -->
<context:component-scan base-package="com.chaol.controller"></context:component-scan>
<!-- 配置注解 映射处理器 、 控制器 -->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
使用注解时,可以不用配置方法解析器,也就是说,只要在加上视图解析器的配置就可以了;
<!-- 配置 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
使用注解配置控制层(controller)
使用注解配置,控制层类也可以不用继承 MultiActionController 类(这里不贴出例子了,把下面类上的 extends MultiActioncontroller 去掉就可以了)
package com.chaol.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
@Controller
@RequestMapping(value="/user/")
public class LsjmUserController extends MultiActionController {
@RequestMapping(value="getUser.action")
public ModelAndView getUser(HttpServletRequest request, HttpServletResponse response)
{
ModelAndView mav = new ModelAndView("login/userManage");
mav.addObject("msg", "这里是用户管理controller");
return mav;
}
@RequestMapping(value="addUser.action")
public ModelAndView addUser(HttpServletRequest request, HttpServletResponse response)
{
ModelAndView mav = new ModelAndView("login/userManage");
mav.addObject("msg", "管理用户-->添加一条用户信息");
return mav;
}
}
对于控制层程序的方法,其返回值 ModelAndView
ModelAndView: 代表MVCweb程序的Model 和 View 对象,ModelAndView 的作用是封装这两个对象,以方便一次返回这两个对象,其中Model中封装了处理请求后的返回数据,View 封装了View的名称,后续用于渲染视图返回给用户界面
那么,控制层程序除了可以返回ModelAndView 对象外,还可以返回什么类型的值呢?
-- String类型(视图名称)
比如:
@RequestMapping(value="deleteUser.action")
public String deleteUser(HttpServletRequest request, HttpServletResponse response)
{
return "login/userManage";
}
那么,此时如果需要返回数据到跳转后的页面展示,需要在方法中传入一个Model对象:
@RequestMapping(value="insertUser.action")
public String insertUser(HttpServletRequest request, HttpServletResponse response, Model model)
{
model.addAttribute("msg", "管理用户--> 更新一条用户信息");
return "login/userManage";
}
有时候,我们可能只是需要做一些后台处理,不需要传参也不需要返回数据,那么此时方法中可以不带参数(返回值是String类型时才可以这样):
@RequestMapping(value="test.action")
public String test()
{
return "login/userManage";
}
返回值为String类型时,可以通过返回值指定跳转页面的方式(请求转发、重定向)
页面跳转可以跳转到 jsp 页面,也可以跳转到 其他的控制器方法
return "redirect : 页面的访问路径"
浏览器地址会改变 ; request不共享,即不能通过request.setAttribute(..)的方式传值,可以在返回值后面拼接字符串传值、或者用model.addAttribute(..)、或者使用RedirerectAttributes类传值(参考大牛博文:redirect重定向跳转传值)。
return "forward : 页面的访问路径"
浏览器地址不会改变; request共享
重定向:redirect
1、重定向到jsp页面:
@RequestMapping(value="test.action")
public String test(Model model)
{
model.addAttribute("msg", "test"); //在页面可以通过EL表达式${param.msg},如果是中文,可能会出现乱码
model.addAttribute("test1", "test");
return "redirect:/login/userManage.jsp";
}
2、重定向到其他的controller
需求场景例:如新增一个信息后,需要跳转到信息列表页面,那么新增完成后就需要跳转到展示信息的controller而不是jsp
@RequestMapping(value="test.action")
public String test(Model model)
{
model.addAttribute("msg", "test");
model.addAttribute("test1", "test"); //前台页面可以使用${param.test1}取值
return "redirect:test1.action"; //也可以使用绝对路径 /user/test1.action : /user/是类上的注解,也叫命名空间
}
@RequestMapping(value="test1.action")
public String test1(Model model, HttpServletRequest request)
{
model.addAttribute("msg", "redirect到action");
return "login/userManage";
}
转发:forward
1、转发到jsp页面:
@RequestMapping(value="test.action")
public String test(Model model)
{
model.addAttribute("msg", "test"); // 前台页面通过${requestScope.msg} 或者 ${msg}取值都可以
model.addAttribute("test1", "test");
return "forward:/login/userManage.jsp";
}
2、转发到其他的controller(因为request可以共享,此时可以直接用request.setAttribute(..)来传值)
@RequestMapping(value="test1.action")
public String test(Model model, HttpServletRequest request)
{
model.addAttribute("msg", "test");
model.addAttribute("test1", "test");
request.setAttribute("name", "chaol");
return "forward:test1.action"; // 转发到下面的controller
}
@RequestMapping(value="test1.action")
public String test1(Model model, HttpServletRequest request)
{
model.addAttribute("msg", "redirect到action"); // 页面通过${requestScope.msg}取值
System.out.println(request.getAttribute("name")); // test传过来的值 "chaol"
return "login/userManage";
}
对于String类型的返回值做一下总结:
1、参数的类型可变(可以有,也可以没有,可以自定义需要的参数)
2、可以通过返回值指定跳转页面的方式(可以跳转到jsp 也可以跳转到其他的controller)
控制器的入门初步学习就到此,有一些需要补充的后续更新此博文
贴一下Demo的目录结构: