前端控制器 ( Controller )
什么是 Controller ?
在mvc 框架中 , 都会存在一个前端控制器 , 在 WEB 应用的前端(Front)设置一个入口控制器(Controller),是用来提供一个集中的请求处理机制,所有的请求都被发往该控制器统一处理,然后把请求分发给各自相应的处理程序。一般用来做一个共同的处理,如权限检查,授权,日志记录等。因为前端控制的集中处理请求的能力,因此提高了可重用性和可拓展性。
Spring MVC 中的前端控制器
Spring MVC 已经提供了一个 DispatcherServlet 类作为前端控制器,所以要使用 Spring MVC 必须在web.xml 中配置前端控制器。
把处理请求的对象称之为处理器或后端控制器,Spring MVC 中习惯称之为 Controller,如处理员工请求的就会命名为 EmployeeController。
注意 :
初始化我们配置的前端控制器DispatcherServlet
我们在DispatcherServlet中配置了mvc.xml,因此也会启动Spring容器。Spring容器会帮我们创建相应的bean并管理 . ( 记得 在 web.xml 中 配置 DispatcherServlet , 接着再 把 mvc.xml 也给配上 . )
百说不如一练 . 接下来我们就来练练 :
1.使用 注解方式开发我们的 HelloWorld 程序 .
配置 POM.xml (工欲善其事 , 必先利其器 )
<modelVersion>4.0.0</modelVersion> <groupId>cn.wolfcode</groupId> <artifactId>springmvc-demo</artifactId> <version>1.0.0</version> <packaging>war</packaging> <properties> <spring.version>5.0.8.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.1</version> <configuration> <port>80</port> <path>/</path> <uriEncoding>UTF-8</uriEncoding> </configuration> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build>
配置前端控制器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<!--*******************************************************************-->
<!--Spring 前端控制器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--指定 Spring MVC 加载的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:mvc.xml</param-value>
</init-param>
<!--Tomcat 启动初始化-->
<load-on-startup>1</load-on-startup>
<!--配置上传文件的大小设置-->
<multipart-config>
<max-file-size>52428800</max-file-size>
<max-request-size>52428800</max-request-size>
</multipart-config>
</servlet>
<!--*******************************************************************-->
<!--关联 mapper 文件-->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<!--<url-pattern>/</url-pattern>-->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
编写一个 处理类 和 jsp
@Controller
public class HelloController {
//提供 方法处理请求 , 在浏览器 localhost/hello , 就会执行下面的方法
@RequestMapping("/hello")
public ModelAndView hello() {
System.out.println("1111");
ModelAndView mv = new ModelAndView();
//向作用域域存入 值
mv.addObject("msg", "HelloWorld");
//找视图
mv.setViewName("/WEB-INF/views/welcome.jsp");
return mv;
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>入门学习案例</title>
</head>
<body>
${msg}
</body>
</html>
编写 Spring MVC 配置文件
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--配置IoC DI 注解扫描器-->
<context:component-scan base-package="cn.wolfcode"></context:component-scan>
<!--配置 MVC 注解解析器-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--Tomcat 容器处理静态资源是交由内置 DefaultServlet 来处理的(拦截路径是 /)如果要访问静态资源 加下面这条 这只是方式之一 , 还有 另外的方式 *.do -->
<!--<mvc:default-servlet-handler/>-->
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--视图前缀-->
<property name="prefix" value="/WEB-INF/views/"></property>
<!--视图后缀-->
<property name="suffix" value=".jsp"></property
</bean>
<bean class="org.springframework.web.multipart.support.StandardServletMultipartResolver" id="multipartResolver"></bean>
</beans>
疑惑 : 为什么 要 在 mvc.xml 中 添加注解扫描器 哪个对应哪个 , 都蒙了是吧 , 莫慌 !
<!--配置IoC DI 注解扫描器 @Service ...等等注解 -->
<context:component-scan base-package="cn.wolfcode"></context:component-scan>
<!--配置 MVC 注解解析器 入 RequestMappingHandlerMapping、RequestMappingHandlerAdapter、
ExceptionHandlerExceptionResolver 等三个 bean .. -->
<mvc:annotation-driven></mvc:annotation-driven>
处理响应
一般处理方法返回的类型为 ModelAndView 和 String。
方式一 : 返回的类型为 ModelAndView
@Controller
public class ResponseController {
@RequestMapping("resp1")
public ModelAndView resp1() {
//创建模型
ModelAndView mv = new ModelAndView();
//往作用域或者模型中添加数据
mv.addObject("msg","会当凌绝顶");
//找视图
mv.setViewName("welcome");
return mv;
}
}
方式二 : 返回的类型为 String { 推荐使用 }
@Controller
public class ResponseController {
@RequestMapping("/resp2")
public String resp2(Model model) {
//往作用域或者模型中存入数据
model.addAttribute("msg2", "一览纵山小");
//返回视图名
return "welcome"; //底层还是上面那个 这里可以直接 写 "welcome" 是因为我上面 配置了一段注解 消除前后缀
}
}
配置视图解析器
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--视图前缀-->
<property name="prefix" value="/WEB-INF/views/"></property>
<!--视图后缀-->
<property name="suffix" value=".jsp"></property>
</bean>
请求转发及 URL 重定向 ( forward & redirect )
image-20200607152726484.png
@Controller
public class forwardController {
@RequestMapping("/f")
public String forward() {
return "forward:/WEB-INF/views/welcome.jsp";
}
@RequestMapping("/r")
public String redirect(){
return "redirect:/aa.html";
//return "redirect:/f.do"; 可以 跳到控制器
//return "redirect:/WEB-INF/views/welcome.jsp"; 不可以
//重定向是不能跳到 WEB-INF 中的
}
处理简单类型请求参数
@Controller
public class RequestController {
@RequestMapping("/req3")
public ModelAndView req3(String username, int age) {
System.out.println(username);
System.out.println(age);
ModelAndView mv = new ModelAndView();
mv.addObject("username",username);
mv.addObject("age",age);
mv.setViewName("QQ");
return mv;
//后面有更好的 直接 引用
}
@RequestMapping("/req4")
public ModelAndView req4(@RequestParam("name") String username, int age) {
System.out.println(username);
System.out.println(age);
return null;
}
//使用对象接收
@RequestMapping("/req5")
public ModelAndView req5(User user) {
System.out.println(user.getName());
System.out.println(user.getAge());
return null;
}
//处理复合类型请求参数
@RequestMapping("/req6")
public ModelAndView req6(Long ids[]) {
System.out.println(Arrays.toString(ids));
return null;
}
//处理日期格式参数 要接收参数的格式 yyyy-MM-dd
@RequestMapping("/req7")
public ModelAndView req7(@DateTimeFormat(pattern="yyyy-MM-dd")Date date) {
System.out.println(date.toLocaleString());
System.out.println(date);
return null;
}
@RequestMapping("/req8")
public ModelAndView req8(User user) {
System.out.println(user);
return null;
}
//回显
@RequestMapping("/req9")
public String req9(@ModelAttribute("u") User user) {
return "welcome";
}
}