Spring Mvc的核心类与注解
DispatcherServlet
- 它的全名是org.springfarmework.web.servlet.DispatcherServlet,它在程序中充当着前端控制器的角色,在使用的将配置在项目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_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--initparam元素存在并且通过其子元素配置了
Spring MVC配置文件的路径,则应用程序在启动时会加载配置路径下的配置文件-->
<!--如果这里面没有通过<init-param>元素配置,则应用程序会默认去WEB-INF目录下寻找
以servletName-servlet.xml方式命名的配置文件,这里的servletName指的下面的springmvc-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-config.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>
@ Controller注解类型
org.springframework.steretype.Controller注解类型用于指示Spring类的实例是一个控制器,它的注解形式是@Controller,该注解在使用时不需要在使用Controller接口,只需要将@Controller注解加入到控制器类上,然后通过Spring的扫描机制找到标注了该注解的控制器即可,
代码
FirstController
package com.yzb.chapter12;
import org.springframework.stereotype.Controller;
@Controller
public class FirstController {
}
springmvc.xml
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!--上面引入context的信息-->
<!--指定需要扫描的包-->
<context:component-scan base-package="com.yzb.chapter12"/>
<!--使用注解的时候,程序的运行需要依赖Spring的AOP包,因此需要注入aop的jar包-->
</beans>
RequestMapping注解的使用
- Spring通过@Controller注解找到相应的控制类后,还需要知道控制器内部对每个请求是如何处理的,这就需要使用@RequestMapping注解类型,它用于映射一个请求或一个方法,使用时,可以标注在一个方法或类上,
FirstController
package com.yzb.chapter12;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class FirstController {
@RequestMapping(value = "/firstController")
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//创建一个对象ModelAndView对象
ModelAndView modelAndView = new ModelAndView();
//像模型对象中添加数据
modelAndView.addObject("msg","这是我的一个程序");
//设置逻辑视图名
modelAndView.setViewName("/WEB-INF/JSP/first.jsp");
//返回ModelAndView对象
return modelAndView;
}
}
- 该类中的所有的方法都映射为相对于类级别的请求,表示该控制器所处理的所有请求都被映射到value属性值所制定的路径下。
package com.yzb.chapter12;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
@RequestMapping(value = "/hello")
public class FirstController {
@RequestMapping(value = "/firstController")
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//创建一个对象ModelAndView对象
ModelAndView modelAndView = new ModelAndView();
//像模型对象中添加数据
modelAndView.addObject("msg","这是我的一个程序");
//设置逻辑视图名
modelAndView.setViewName("/WEB-INF/JSP/first.jsp");
//返回ModelAndView对象
return modelAndView;
}
}
由于在类上添加@RequestMapping注解,并且其value属性值“/hello”,请求代码就会变成:http://localhost:8080/chapter12/hello/firstController
- 所有属性都是可选的,但其 默认的属性是value,当value是唯一的属性值是可以省略。
组合注解
为了简化常用的HTTP方法的映射,
@GetMapping:匹配GET方式的请求
@PostMapping:匹配POST方式的请求
@PutMapping:匹配PUT方式的请求
@DeleteMapping:匹配DELETE方式的请求
@PatchMapping:匹配PATCH方式的请求
例如:
@GetMapping(value="/user/{id}")=@RequestMapping(value="/user/{id}",method=RequestMethod.GET);
请求处理方法的参数和返回类型
参数
@PathVariable
@RequestParam
@RequestHeader
@RequestBody
@MatrixVariable
@QRequestPart
@SessionAttribute
@RequestAttribute
在这里面org.springframework.ui.Model,它不是一个ServletAPI类型,而是一个包含了Map对象的Spring MVC类型,如果方法中添加了Model的参数,则每次调用该请求处理方法时,SpringMVC都会创建Moodel对象,并将其作为参数传递给方法。
返回类型
- ModelAndView:可以添加M数据,并指定视图
- Model
- Map
- View
- String:可以跳转视图,但不能携带数据
- void:在异步请求时使用,它只返回数据,而不会跳转视图
- HttpEntity<?>或ReponseEntity<?>
- Callable<?>
- DeferredResult<?>
@@@
- 由于ModelAndView类型不能实现数据与视图之间的解耦
- 在企业开发时的返回类型都会使用String
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_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--initparam元素存在并且通过其子元素配置了
Spring MVC配置文件的路径,则应用程序在启动时会加载配置路径下的配置文件-->
<!--如果这里面没有通过<init-param>元素配置,则应用程序会默认去WEB-INF目录下寻找
以servletName-servlet.xml方式命名的配置文件,这里的servletName指的下面的springmvc-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.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.xml
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!--上面引入context的信息-->
<!--指定需要扫描的包-->
<context:component-scan base-package="com.yzb.chapter12"/>
<!--使用注解的时候,程序的运行需要依赖Spring的AOP包,因此需要注入aop的jar包-->
</beans>
FirstController
package com.yzb.chapter12;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
@RequestMapping(value = "/hello")
public class FirstController {
@RequestMapping(value = "/firstController")
public String handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Model model) throws Exception {
//使用model对象存储数据
model.addAttribute("msg","这是我的一个程序");
//设置逻辑视图名
return "/WEB-INF/JSP/first.jsp";
}
}
first.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--EL表达式--%>
${msg}
</body>
</html>
结果图
String返回类型的两种用法
String类型出了可以返回上述代码中视图页面外,还可以进行重定向与请求转发,
redirect重定向
例如在修改用户信息操作后,将请求重定向到用户查询方法的实现代码
@RequestMapping(value="/update")
public String update(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Model model){
......
return "redirect:queryUser";
}
forward请求转发
用户执行修改操作时,转发到用户修改页面的实现
@RequestMapping(value="/toEdit")
public String update(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Model model){
......
return "forward:editUser";
}
ViewResolver视图解析器
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!--上面引入context的信息-->
<!--指定需要扫描的包-->
<context:component-scan base-package="com.yzb.chapter12"/>
<!--使用注解的时候,程序的运行需要依赖Spring的AOP包,因此需要注入aop的jar包-->
<!--配置视图解析器的前缀和后缀,-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--设置前缀-->
<property name="prefix" value="/WEB-INF/jsp"></property>
<!--设置后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
package com.yzb.chapter12;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
@RequestMapping(value = "/hello")
public class FirstController {
@RequestMapping(value = "/firstController")
public String handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Model model) throws Exception {
//使用model对象存储数据
model.addAttribute("msg","这是我的一个程序");
//设置逻辑视图名
//return "/WEB-INF/JSP/first.jsp";
return "first";
}
}
<?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_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--initparam元素存在并且通过其子元素配置了
Spring MVC配置文件的路径,则应用程序在启动时会加载配置路径下的配置文件-->
<!--如果这里面没有通过<init-param>元素配置,则应用程序会默认去WEB-INF目录下寻找
以servletName-servlet.xml方式命名的配置文件,这里的servletName指的下面的springmvc-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.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>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--EL表达式--%>
${msg}
</body>
</html>
SpringMVC应用
在web.xml中配置一个DispatcherServlet,初始化文件配置里加上配置文件
在配置文件中加入扫描的组件,和视图解析器的前后缀,
编写controller类加注解,返回类型String类型
上面就是该实例的代码。