1.2(Spring MVC学习笔记) Spring MVC核心类及注解
一、DispatcherServlet
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"
metadata-complete="true">
<display-name>SpringMVC</display-name> <!-- 配置前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class >
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!-- 初始化时加载配置文件,该配置文件是在src目录下创建的。 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-config.xml</param-value>
</init-param>
<!-- 当前servlet与容器一起加载 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 所有请求都会被前端控制器拦截-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
其中<init-param>和<load-on-startup>是可选项.
如果<init-param>配置了xml文件的路径,则容器加载时会去指定路径加载文件。
如果没有配置则会在WEB-INF目录下选择命名格式为servletName-servlet.xml的文件。
servletName是我们配置的前端控制器的<servlet-name>,本例为springmvc,则会寻找springmvc-servlet.xml。
<load-on-startup>配置为1,代表当前Servlet在容器启动时加载。
如果没有配置,则在请求该Servelt时才对其进行加载。
二、Controller注解
在控制类可以通过实现Controller接口,也可以通过注解来实现。
通过注解实现只需要在控制类上添加@Controller注解即可。
添加注解后再xml中可通过扫描语句进行扫描。
扫描语句:<context:component-scan base-package = "指定包" />
三、RequestMapping注解
3.1Spring通过@Controller注解找到控制器类后,还需将请求映射到具体的处理程序。
RequesMapping注解就是用于映射请求。
例如:
public class FirstController{
@RequestMapping(value = "/firstController")
public String handleRequest(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
// TODO Auto-generated method stub
model.addAttribute("msg", "hello SpringMVC");
return "first";
}
}
上例中间/firstController这个请求映射到handleRequest方法。
在浏览器地址栏输入localhost:8080/SpringMVC/firstController就可以了调用handleRequest方法。
@RequestMapping注解也可以映射到类上。
@RequestMapping(value = "/hello")
public class FirstController{
@RequestMapping(value = "/firstController")
public String handleRequest(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
// TODO Auto-generated method stub
model.addAttribute("msg", "hello SpringMVC");
return "first";
}
}
映射在类上时,要想访问类中的方法必须加上类的映射请求路径。
例如想访问handleRequest方法,完整路径为:localhost:8080/SpringMVC/hello/firstController
value属性除了上述直接表示一个固定路径外,还有以下写法:
3.2指定变量和值 {变量}
例如
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
@RequestMapping(value = "/hello")
public class FirstController{
@RequestMapping(value = "/firstController/{id}")//指定变量
public String handleRequest(@PathVariable String id ,HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
// TODO Auto-generated method stub System.out.println("into mv");
System.out.println(id);
model.addAttribute("msg", "hello SpringMVC");
return "first";
}
}
在地址栏输入loaclhost:8080/SpringMVC/hello/firsstController/xx,才能访问指定路径所映射的方法。
而xxx可以被@pathVariable String id 中的id获取,形参名xx和路径{xx}中的名称要一致。如果没有/xxx则出现404页面。
3.3指定变量和正则表达式 ({变量:正则表达式})
例如将RequestMapping改为:@RequestMapping(value = "/firstController/{id:\\d}")
\\代表\,正则\d中\d代表0-9任意一个数字,这样配置后:
/firstController/0-9任意一个数字可以访问成功(注意是一个数字,多个不符合条件),且可以通过@pathVariable获取id的值。
/firstController/0-9之外的字符或多个数字(大于1个),访问失败,出现404页面。
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
@RequestMapping(value = "/hello")
public class FirstController{
//末尾加上任意一位数字访问成功,反正失败
@RequestMapping(value = "/firstController/{id:\\d}")
public String handleRequest(@PathVariable String id ,HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
// TODO Auto-generated method stub
System.out.println("into mv");
System.out.println(id);
model.addAttribute("msg", "hello SpringMVC");
return "first";
}
}
访问失败:
访问成功:
RequestMapping中还有一个属性method,用于指定处理何种类型的请求方法。
例如@RequestMapping(value = "/firstController/{id:\\d}" ,method = RequestMethod.POST)处理POST类型的请求
@RequestMapping(value = "/firstController/{id:\\d}" ,method = RequestMethod.GET)处理GET类型的请求
我们来看一个例子
@Controller
@RequestMapping(value = "/hello")
public class FirstController{
@RequestMapping(value = "/firstController/{id:\\d}" ,method = RequestMethod.POST)//处理POST类型请求
public String handleRequest(@PathVariable String id ,HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
// TODO Auto-generated method stub
System.out.println("into mv");
System.out.println(id);
model.addAttribute("msg", "hello SpringMVC");
return "first";
}
}
我们将方法设置为处理POST类型请求,使用GET类型的请求去访问会出现不支持GET类型的请求方法。
method可以设置多个值,中间用“,”隔开@RquestMapping(method = {xxx.GET,xx.xPOST})
Spring4.3中又引入了组合注解,例如上例中的@RequestMapping(method = Request.GET)可以简化为:
GetMapping(),从字面上可以看出这个注解是包含了GET和Mapping。处理Get类型的请求映射。
除此之外,还有一些组合注解:
PostMapping,PutMapping,DeleteMapping,PatcherMapping.
params属性:指定请求中必须包含、不包含某些参数、或者指定某些参数名和值要对应,才能被当前方法处理。
例如params = {"name"} 代表请求中要包含name参数。例如:localhost:8080/SpringMVC/hello/firstController/1?name=hcf;
这样的就可以正确访问指定的方法,反之不行。
params={“!name”}代表请求中不包含name参数可以正确访问,反正不行。
params={"name = hcf"},代表请求参数name要和指定的值匹配才可以正常访问,反正不行。例如
localhost:8080/SpringMVC/hello/firstController/1?name=hcf;可以访问,
localhost:8080/SpringMVC/hello/firstController/1?name=h;就不能访问。
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; @Controller
@RequestMapping(value = "/hello")
public class FirstController{//请求参数name为“hcf”才能访问
@RequestMapping(value = "/firstController/{id:\\d}" ,method = {RequestMethod.POST,RequestMethod.GET},params = {"name=hcf"})
public String handleRequest(@PathVariable String id ,HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
// TODO Auto-generated method stub
System.out.println("into mv");
System.out.println(id);
model.addAttribute("msg", "hello SpringMVC");
return "first";
}
}
访问成功:
访问失败:
四、请求处理方法类型和返回值。
支持的请求参数类型
Request or response objects (Servlet API).
Session object (Servlet API)
org.springframework.web.context.request.WebRequest
or org.springframework.web.context.request.NativeWebRequest
java.util.Locale
java.util.TimeZone
(Java 6+) / java.time.ZoneId
(on Java 8)
java.io.InputStream
/ java.io.Reader
java.io.OutputStream
/ java.io.Writer
org.springframework.http.HttpMethod
java.security.Principal
@PathVariable
@RequestParam
@RequestHeader
@RequestBody
@RequestPart
@SessionAttribute
@RequestAttribute
HttpEntity<?>
java.util.Map
/ org.springframework.ui.Model
/ org.springframework.ui.ModelMap
org.springframework.web.servlet.mvc.support.RedirectAttributes
org.springframework.validation.Errors
/ org.springframework.validation.BindingResult
org.springframework.web.bind.support.SessionStatus
org.springframework.web.util.UriComponentsBuilder
这些是方法参数支持的类型,
例如上例中的:
public String handleRequest(@PathVariable String id ,HttpServletRequest request, HttpServletResponse response, Model model) throws Exce
参数类型都是受支持的参数类型。
支持的返回类型:
上例子中的返回值为“first”,返回字符串被解释为逻辑视图名。
(返回first对应为/WEB-INF/jsp/first.jsp,这是因为在视图解析器中设置了前缀和后缀,后续会有具体使用方法)
五、视图解析器(ViewResolver)
视图解析器将DispatcherServlet中的view参数传递给视图解析器,视图解析器将解析的视图传递给DispatcherServlet。
在视图解析中,可以设置前缀和后缀。
例如我们设置前缀为“/WEB-INF/jsp/”,后缀设置为“.jsp”。
以前面的Controller类为例,Controller执行完后将“first”返回给HandlerAdapter,然后返回DispathcerServlet。
DispatcherServlet将“first”交给视图解析器,视图解析器将“first”添加前缀和后缀,变成“/WEB-INF/jsp/first.jsp”.
然后解析指定路径视图将视图返回给DispatcherServlet。
我们来看下前缀与后缀的具体设置:
<bean id = "viewResolver" class = "org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 视图解析器-->
<!--设置前缀-->
<property name="prefix" value = "/WEB-INF/jsp/"></property>
<!--设置后缀-->
<property name="suffix" value = ".jsp"></property>
</bean>
最后结合上述,使用注解实现SpringMVC
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"
metadata-complete="true">
<display-name>SpringMVC</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list> <!-- 配置前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class >
org.springframework.web.servlet.DispatcherServlet
</servlet-class> <!-- 初始化时加载配置文件,该配置文件是在src目录下创建的。 -->
<!-- <init-param> 该选项不配做会自动寻找WEB-INF下名为springmvc-servlet.xml的文件。-->
<!-- <param-name>contextConfigLocation</param-name>-->
<!-- <param-value>classpath:springmvc-config.xml</param-value>-->
<!--</init-param>-->
<!-- 当前servlet与容器一起加载 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 所有请求都会被前端控制器拦截-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Controller类
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; @Controller
@RequestMapping(value = "/hello")
public class FirstController{
@RequestMapping(value = "/firstController/{id:\\d}" ,method = {RequestMethod.POST,RequestMethod.GET},params = {"name=hcf"})
public String handleRequest(String name ,HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
// TODO Auto-generated method stub
System.out.println("into mv");
name = request.getParameter("name");
System.out.println(name);
//返回类型为String会被解释为逻辑视图名View就解决了。
//Model交由Model对象来完成。
model.addAttribute("msg", "hello SpringMVC");
return "first";
}
}
springmvc-servlet.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:component-scan base-package = "com.springmvc.firstmvc"></context:component-scan>
<!-- 配置处理器(Handle),映射/firstController请求 (Controller类),已由注解完成-->
<!-- <bean name = "/firstController" class = "com.springmvc.firstmvc.FirstController"/> -->
<!-- 配置映射处理器(handlerMapping) 将处理器(Handle)的name作为url进行查找(Spirng4.0以后无需配置) -->
<!-- 配置适配处理器(HandlerAdapter) 适配处理器会调用处理器(Handle)即FirstController类(Spirng4.0以后无需配置) -->
<!-- 处理器会返回一个ModelAndView,适配处理器将返回的ModelAndView交给前端控制器去处理了 -->
<!-- 前端控制器根据ModelAndView中的View选择一个视图解析器(ViewReslover) -->
<!-- 前端控制器将Model(msg "hello SpringMVC")填充进视图解析器返回的视图,用户看到最后页面 -->
<!-- 设置视图处理器及其前缀后缀 -->
<bean id = "viewResolver" class = "org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value = "/WEB-INF/jsp/"></property>
<property name="suffix" value = ".jsp"></property>
</bean>
<!-- 视图处理器解析后会将视图传递给前端控制器,前端控制对View进行渲染(将模型数据填入视图) -->
<!-- 渲染结果会返回客户端浏览器显示 -->
</beans>
WEB-INF/jsp/first.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
${msg}
</body>
</html>
可以看到加载的是springmvc-servlet.xml
如果firstController/后面不是一位数字,或者name不等于hcf都会出现404页面。
完整结构:
参考资料:
SpringFramework/spring-framework-4.3.6.RELEASE/docs/spring-framework-reference/html/mvc.html
https://www.cnblogs.com/qq78292959/p/3760560.html
1.2(Spring MVC学习笔记) Spring MVC核心类及注解的更多相关文章
- Spring MVC 学习笔记 spring mvc Schema-based configuration
Spring mvc 目前支持5个tag,分别是 mvc:annotation-driven,mvc:interceptors,mvc:view-controller, mvc:resources和m ...
- Spring Cloud学习笔记--Spring Boot初次搭建
1. Spring Boot简介 初次接触Spring的时候,我感觉这是一个很难接触的框架,因为其庞杂的配置文件,我最不喜欢的就是xml文件,这种文件的可读性很不好.所以很久以来我的Spring学习都 ...
- Spring Boot学习笔记——Spring Boot与MyBatis的集成(项目示例)
1.准备数据库环境 # 创建数据库 CREATE DATABASE IF NOT EXISTS zifeiydb DEFAULT CHARSET utf8 COLLATE utf8_general_c ...
- [Spring入门学习笔记][Spring Boot]
什么是Spring Boot Spring Boot正是在这样的一个背景下被抽象出来的开发框架,它本身并不提供Spring框架的核心特性以及扩展功能,只是用于快速.敏捷地开发新一代基于Spring框架 ...
- [spring入门学习笔记][spring的IoC原理]
什么叫IoC 控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度.其中最常见的方式叫做依赖注入(Dependency ...
- Spring Boot学习笔记---Spring Boot 基础及使用idea搭建项目
最近一段时间一直在学习Spring Boot,刚进的一家公司也正好有用到这个技术.虽然一直在学习,但是还没有好好的总结,今天周末先简单总结一下基础知识,等有时间再慢慢学习总结吧. Spring Boo ...
- [Spring入门学习笔记][Spring的AOP原理]
AOP是什么? 面向切面编程 软件工程有一个基本原则叫做“关注点分离”(Concern Separation),通俗的理解就是不同的问题交给不同的部分去解决,每部分专注于解决自己的问题.这年头互联网也 ...
- MVC学习笔记:MVC实现用户登录验证ActionFilterAttribute用法并实现统一授权
在项目下新建一个文件夹来专门放过滤器类,首先创建一个类LoginFilter,这个类继承ActionFilterAttribute.用来检查用户是否登录和用户权限.: using System; us ...
- Spring Boot学习笔记——Spring Boot与ActiveMQ的集成
Spring Boot对JMS(Java Message Service,Java消息服务)也提供了自动配置的支持,其主要支持的JMS实现有ActiveMQ.Artemis等.这里以ActiveMQ为 ...
随机推荐
- egrep对于conf文件中去掉#注释,排除无用项
[root@localhost conf]# egrep -v "#|^$" nginx.conf.default > nginx.conf dd
- Optimize Prime Sieve
/// A heavily optimized sieve #include <cstdio> #include <cstring> #include <algorith ...
- java程序在centos7里面开机自启动
1.我们先来个简单的start,status,stop程序: [root@localhost ~]# cat /home/tomcat/jarservice.sh #!/bin/bashCU_PID= ...
- php函数-shuffle
Shuffle()函数说明: -随机乱序现有数组并不保留键值: -shuffle()函数把数组中的元素按随机顺序重新排列,该函数为数组中的元素分配新的键名,已有键名将被删除. 语法说明: shuffl ...
- 转:Spring AOP详解
转:Spring AOP详解 一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址: ...
- C++11 自动释放锁(转)
原文转自 https://blog.csdn.net/lmb1612977696/article/details/77712170 c++11加入了很多新的特性,值得我们去探索. 先看一个例子:普通的 ...
- Django-Form 补充
一.Form的前端循环 class LoginForm(Form): name = ... pwd = ... def func(request): form = LoginForm() return ...
- mysql七:数据备份、pymysql模块
阅读目录 一 IDE工具介绍 二 MySQL数据备份 三 pymysql模块 一 IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具 下载链接:https:/ ...
- 在shell脚本中添加暂停,按任意键继续
分析一个复杂脚本的时候,有时候需要加点暂停,分段来看,比较清晰 于是参考了一些实现,目前自己用的是这样子的 #add for debug by zqb function get_char() { SA ...
- camera驱动框架分析(中)
camera host的驱动 下面开始分析camera host吧,如果仅仅是想知道camera sensor驱动怎么写,而不想知道内部具体怎么个调用流程,怎么个架构设计,那可以跳过该部分,直接去看i ...