实现org.springframework.web.servlet.mvc.Controller接口,并重写handleRequest方法:
首先创建一个项目,编写web.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--配置DispatcherServlet-->
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--绑定SpringMVC的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMVC-servlet.xml</param-value>
</init-param>
<!--启动级别-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
再创建springMVC-servlet.xml文件:
<?xml version="1.0" encoding="UTF8"?>
<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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--自动扫描包,让指定包下的注解生效,有IOC容器统一管理-->
<context:component-scan base-package="controller" />
<!--过滤静态资源,让SpringMVC不处理静态资源,如.css、.js等等-->
<mvc:default-servlet-handler />
<!--支持MVC注解驱动,在Spring一般采用@RequestMapping注解来完成映射关系-->
<!--要想使@RequestMapping注解生效,-->
<!--必须向上下文中注册DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter实例-->
<!--这两个实例分别在类级别和方法级别处理,而annotation-driven配置帮助我们自动完成上述两个实例的配置注入 -->
<mvc:annotation-driven />
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!--前缀 -->
<property name="prefix" value="/WEB-INF/jsp/"></property>
<!--后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
创建一个ControllerTest1类实现Controller接口:
package controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// 实现Controller接口获得控制器功能
public class ControllerTest1 implements Controller {
@Override
// 处理请求并返回一个ModelAndView对象,包含数据和视图信息
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView modelAndView = new ModelAndView();
// 封装数据对象
modelAndView.addObject("msg","Controller Test 1");
// 封装要跳转的页面,会被视图解析器处理
modelAndView.setViewName("test");
return modelAndView;
}
}
然后去springMVC-servlet.xml文件注册bean,id对应请求的映射路径,class对应处理请求的控制类:
<bean id="/t1" class="controller.ControllerTest1"></bean>
编写一个test.jsp页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>${msg}</h3>
</body>
</html>
@Controller放在类上用来声明这个类是一个控制器,此时不需要重写方法
Spring使用扫描机制找到应用程序中所有基于注解的控制器类,所以要在配置文件springMVC-servlet.xml中声明组件扫描:
<!--自动扫描包,让指定包下的注解生效,有IOC容器统一管理-->
<context:component-scan base-package="controller" />
还要配置静态资源过滤和注解支持驱动:
<!--过滤静态资源,让SpringMVC不处理静态资源,如.css、.js等等-->
<mvc:default-servlet-handler />
<!--支持MVC注解驱动,在Spring一般采用@RequestMapping注解来完成映射关系-->
<mvc:annotation-driven />
创建一个ControllerTest2:
@Controller // 代表这个类被Spring托管
public class ControllerTest2 {
@RequestMapping("/t2") // 指定请求映射路径为 /t2
public String test1(Model model){
// 封装数据对象
model.addAttribute("msg","Controller Test 2");
return "test"; // 视图名字,即要跳转的页面,会被视图解析器拼接前缀后缀处理
}
}
上面ControllerTest2就是@RequestMapping用在方法上,现在举例说明@RequestMapping用在类上:
@Controller
@RequestMapping("/c3")
public class ControllerTest3 {
@RequestMapping("/t2") // 此时请求映射路径为 /c3/t2
public String test1(Model model){
// 封装数据对象
model.addAttribute("msg","Controller Test 3");
return "test"; // 视图名字,即要跳转的页面,会被视图解析器拼接前缀后缀处理
}
}
此时仅请求 /t2 还是走的ControllerTest2中的方法:
只有请求 /c3/t2 才会运行ControllerTest3中的处理程序方法:
Controller类可以拿到HttpServletRequest、HttpServletResponse对象,所以可以通过Servlet API实现:
此时不需要视图解析器,因为不会经过视图解析器:
@Controller
public class ControllerTest4 {
@RequestMapping("/c4/t1")
public void test1(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/index.jsp").forward(request,response);
}
@RequestMapping("c4/t2")
public void test2(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.sendRedirect("/sendRedirect.jsp");
}
}
@Controller
public class ControllerTest5 {
@RequestMapping("/c5/t1")
public String test1(Model model){
model.addAttribute("msg","Spring MVC");
return "test"; // 转发,会被视图解析器处理
}
@RequestMapping("/c5/t2")
public String test2(){
return "forward:/index.jsp"; // 转发,不会被视图解析器处理
}
@RequestMapping("c5/t3")
public String test3(){
return "redirect:/sendRedirect.jsp"; // 重定向,不会被视图解析器处理
}
}
或者这样编写,效果与上面一样:
@Controller
public class ControllerTest5 {
@RequestMapping("/c5/t1")
public ModelAndView test1(ModelAndView model){
model.addObject("msg","Spring MVC");
model.setViewName("test"); // 转发,会被视图解析器处理
return model;
}
@RequestMapping("/c5/t2")
public ModelAndView test2(ModelAndView model){
model.setViewName("forward:/index.jsp"); // 转发,不会被视图解析器处理
return model;
}
@RequestMapping("c5/t3")
public ModelAndView test3(ModelAndView model){
model.setViewName("redirect:/sendRedirect.jsp"); // 重定向,不会被视图解析器处理
return model;
}
}