SpringMVC(一)概述、解析器与注解
个人博客网:https://wushaopei.github.io/ (你想要这里多有)
一、SpringMVC的概述
1、概述
Spring MVC框架是一个开源的Java平台,为开发强大的基于JavaWeb应用程序提供全面的基础架构支持,并且使用起来非常简单容易。
Spring web MVC框架提供了MVC(模型 - 视图 - 控制器)架构,用于开发灵活和松散耦合的Web应用程序的组件。 MVC模式使应用程序的不同组件(输入逻辑,业务逻辑和UI逻辑)合理有效的分离,同时又有效的将各组件组合一起完成功能。
- 模型(Model)封装了应用程序数据,通常它们将由POJO类组成。
- 视图(View)负责渲染模型数据,一般来说它负责生成客户端浏览器可以解释HTML输出。
- 控制器(Controller)负责处理用户请求并构建适当的模型,并将其传递给视图进行渲染。
2、SpringMVC的核心DispatcherServlet程序

二、SpringMVC 示例及配置
1、SpringMVC——Hello world示例的步骤
【1】创建一个动态web工程
【2】导入需要的jar包

【3】SpringMVC的 Hello 程序目录结构:

【4】web.xml中的配置:
<!-- The front controller of this Spring Web application, responsible for handling all application requests -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--
初始化参数,配置Spring的配置文件
-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<!-- load-on-startup标签是在web工程启动之后就会创建Servlet程序 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<!-- 支持全部的请求,包含 restful请求 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
【5】HelloController代码:
@Controller
public class HelloController {
/**
* @RequestMapping 配置一个请求地址跟方法对应<br/>
* /hello是请求地址。表示http://ip:port/工程名/hello<br/>
*/
@RequestMapping("/hello")
public String hello() {
System.out.println("这是SpringMVC的 hello 程序!");
// 跳转的地址
return "/target.jsp";
}
}
【6】页面 jsp 内容:
index.jsp 内容:
<a href="${ pageContext.request.contextPath }/hello">hello程序</a>
target.jsp 内容:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
hello 请求跳转过来啦……
</body>
</html>
【7】applicationContext.xml配置文件内容:
<!-- 配置包扫描 -->
<context:component-scan base-package="com.atguigu"></context:component-scan>
【8】业务逻辑流程分析:

2、SpringMVC的配置文件的另一种存放方式

三、视图解析器
视图解析器配置:
<!-- InternalResourceViewResolver 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置前缀地址 -->
<property name="prefix" value="/pages/user/"/>
<!-- 配置后缀地址 -->
<property name="suffix" value=".jsp"/>
</bean>

四、@RequestMapping注解详解
1、value属性
value属性是给方法配置一个请求地址
/**
* @RequestMapping 是给资源配置(Controller中的方法或Controller)一个访问地址。 <br/>
*
* value属性表示请求的地址<br/>
* value="/abc" 就表示请求地址是:http://ip:port/工程名/abc<br/>
* path属性同value作用一样,一般用value居多
*/
@RequestMapping(path="/abc")
public String abc() {
System.out.println("这是abc方法被调用了");
return "target2";
}
2、params属性
params是要求此请求的参数匹配
- params="username" 表示 请求地址必须带有username参数
- params="username=abc" 表示 请求参数中必须要有username,而且值还必须是abc
- params="username!=abc" 表示 1、请求参数中不能有username参数。2、有username参数,但值不能等于abc
- params="!username" 表示 请求地址不能带有username参数
- params= {"username!=abc","!password"} params可以有多个值,每个值之间是&&关系
以上条件表示要求:
( 请求地址中不能有username参数 || username参数值不能等于 abc && 不能有password参数 )
/**
* @RequestMapping 是给资源配置(Controller中的方法或Controller)一个访问地址。 <br/>
*
* value属性表示请求的地址<br/>
* value="/abc" 就表示请求地址是:http://ip:port/工程名/abc<br/>
* path属性同value作用一样,一般用value居多<br/>
*
* params属性表示当前请求必须要有指定参数的匹配<br/>
* params="password",表示请求中必须包含有password这个参数<br/>
* params="password=wzg168",表示请求中必须要的password参数。而且值还要等于wzg168(也就是给定值)<br/>
* params="password!=wzg168",表示两种情况,1:是可以没有password这个参数。2.如果有这个参数。值不能等于wzg168(也就是给定值)<br/>
* params="!password",表示请求中不能有此参数<br/>
* params= {"!password","username"}表示请求中,不能有password参数,必须有username参数
*/
@RequestMapping(path="/abc",params= {"!password","username"})
public String abc() {
System.out.println("这是abc方法被调用了");
return "target2";
}
3、headers属性
是匹配请求头规则
/**
* headers属性可以规则此请求中的请求头信息<br/>
* headers="User-Agent=Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"
* 表示当前请求必须是谷歌浏览器
* @return
*/
@RequestMapping(value="/aaa",headers="User-Agent=Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36")
public String aaa() {
System.out.println("这是aaa方法被调用了");
return "target2";
}
4、method属性
GET:表示GET请求
POST:表示POST请求
PUT:表示PUT请求
DELETE:表示DELETE请求
- method 规定当前请求必须是什么请求才能访问此方法
- method=RequestMethod.GET 表示必须是GET请求
- method=RequestMethod.POST表示必须是POST请求
GET请求演示:
@RequestMapping(value="/bbb",method=RequestMethod.GET)
public String bbb() {
System.out.println("这是bbb方法被调用了");
return "target2";
}
POST请求演示:
/**
* GET:表示GET请求 <br/>
* POST:表示POST请求<br/>
* PUT:表示PUT请求<br/>
* DELETE:表示DELETE请求<br/>
*
* method 规定当前请求必须是什么请求才能访问此方法<br/>
* method=RequestMethod.GET 表示必须是GET请求<br/>
* method=RequestMethod.POST表示必须是POST请求<br/>
*/
@RequestMapping(value="/bbb",method=RequestMethod.POST)
public String bbb() {
System.out.println("这是bbb方法被调用了");
return "target2";
}
GET 请求和 POST 请求 的区别与调用方式

5、@RequestMapping标注在Controller类上

6、通配符在@RequestMapping中的使用
【绝对匹配】
创建path.jsp文件
由地址栏输入连接方法的地址,然后进入方法,直接进行执行跳转到 path 路径下!
该 path 路径 声明精确!

跳转到 path页面
@Controller
public class PathController {
/**
* 精确匹配<br/>
* value="/fun" 表示http://ip:port/工程名/fun<br/>
*/
@RequestMapping(value="/fun")
public String fun() {
System.out.println("精确匹配");
return "path";
}
}
【2】 ?问号 匹配资源路径
? 问号表示一个任意字符
/**
* ? 问号表示一个任意字符<br/>
* http://ip:port/工程名/fun 或 http://ip:port/工程名/fua
*/
@RequestMapping(value="/fu?")
public String fun1() {
System.out.println("这是fun1方法被调用了 /fu? ");
return "path";
}

【3】 * 星号 匹配资源路径
* 星号 可以匹配任意个字符
/**
* * 星号表示任意个字符<br/>
* http://ip:port/工程名/fun 或 http://ip:port/工程名/fuabc
*/
@RequestMapping(value="/fu*")
public String fun2() {
System.out.println("这是fun2方法被调用了 /fu* ");
return "path";
}
注:当一个路径同时匹配多个规则的时候,调用方法的优先顺序是:
绝对匹配--->>>>?问号匹配---->>>>*星号匹配

【4】 ? 匹配一个字符目录
/**
* value="/?/fun" 这里的问题号匹配一个字符的目录<br/>
*/
@RequestMapping(value="/?/fun")
public String fun3() {
System.out.println("这是fun3方法被调用了 /?/fun ");
return "path";
}

【5】* 星号 匹配一层目录(多个字符)
// value="/*/fun"这里的星号,表示匹配一层任意多个字符的目录
@RequestMapping(value="/*/fun")
public String fun4() {
System.out.println("这是fun4方法被调用了 /*/fun ");
return "path";
}

【6】* * 星星号 匹配多层目录
// value="/**/fun" 这里的星星 可以匹配多层任意的目录
@RequestMapping(value="/**/fun")
public String fun5() {
System.out.println("这是fun5方法被调用了 /**/fun ");
return "path";
}

五、Controller中如何接收请求参数
1、原生API参数类型
【1】HttpServletRequest类
@RequestMapping(value="/param1")
public String param1(HttpServletRequest request) {
System.out.println("reqeust对象 ===>>>" + request.getHeader("User-Agent"));
System.out.println("param1方法被调用了");
return "param";
}
从请求头获取请求参数:
打印结果:

【2】HttpSession类
@RequestMapping(value="/param2")
public String param2(HttpSession session) {
System.out.println("HttpSession对象 ===>>>" + session);
System.out.println("我想念晶晶姑娘啦!");
return "param";
}
获取当前请求会话
打印结果:

【3】HttpServletResponse类
@RequestMapping(value="/param3")
public String param3(HttpServletResponse response) {
System.out.println("HttpServletResponse对象 ===>>>" + response);
System.out.println("param3方法被调用了");
return "param";
}

@RequestMapping(value = "/param4")
public String param4(HttpServletRequest request, HttpServletResponse response,
HttpSession session) {
System.out.println("reqeust对象 ===>>>" + request.getHeader("User-Agent"));
System.out.println("HttpSession对象 ===>>>" + session);
System.out.println("HttpServletResponse对象 ===>>>" + response);
System.out.println("param4方法被调用了");
return "param";
}

2、普通类型入参
在请求的方法上,写上类型和参数名,那么 SpringMVC模型就会自动的将参数值注入到方法的参数中。
@RequestMapping("/param5")
public String param5(String username,String password) {
System.out.println( "请求参数username的值:" + username );
System.out.println( "请求参数password的值:" + password );
return "param";
}
测试的地址是:
http://localhost:8080/springmvc_hello/param5?username=wzg186&password=123456

3、普通类型数组的参数
把请求的参数名做为方法的参数名用来接收请求参数值即可。数组也一样。
@RequestMapping("/param6")
public String param6(String[] hobby) {
if (hobby != null && hobby.length > 0) {
for (String h : hobby) {
System.out.println("兴趣爱好:" + h);
}
}
return "param";
}
测试地址:
http://localhost:8080/springmvc_hello/param6?hobby=cpp&hobby=java&hobby=javaScript

4、普通类型使用@RequestParam入参
/**
* 我们的方法参数名是username,而客户端无法(或不方便)传username的参数名。而只能传user参数,给username赋值。怎么办?<br/>
* @RequestParam(name="user") 把请求的参数user的值。注入到方法参数的username。<br/>
* @RequestParam注解name属性指定的值,要求客户端必须传递。否则就报错。<br/>
* required属性设置请求的参数user是否必须传递。默认是true,表示必须。<br/>
* defaultValue属性是默认值。也就是如果客户端没有传递user参数,则使用defaultValue来设置username的值<br/>
*/
@RequestMapping("/param7")
public String param7(@RequestParam(name="user",required=false,defaultValue="我是默认值,帅帅哒!!") String username) {
System.out.println("username的值:" + username);
return "param";
}
我们的方法参数名是username,而客户端无法(或不方便)传username的参数名。而只能传user参数,给username赋值。怎么办?<br/>
@RequestParam(name="user") 把请求的参数user的值。注入到方法参数的username。<br/>
@RequestParam注解name属性指定的值,要求客户端必须传递。否则就报错。

如果这个时候,我希望客户端哪怕没有传递user的参数的时候。也可以调用方法怎么办?
解决一:
修改@RequestParam注解的required=false的属性。表示这个参数不是必须传递。
设置 defaultValue属性是默认值。也就是如果客户端没有传递user参数,则使用defaultValue来设置username的值<br/>
5、@RequestHeader获取请求头入参
@RequestHeader 可以把请求头的值注入到,方法参数中。
@RequestMapping("/param8")
public String param8(@RequestHeader("User-Agent") String userAgent,
@RequestHeader("Accept") String accept) {
System.out.println("请求头User-Agent的值是:" + userAgent);
System.out.println("请求头Accept的值:" + accept);
return "param";
}
6、@CookieValue获取Cookie值入参
@CookieValue是可以取得客户端发送过来的某个指定了名称的Cookie的值,注入到方法参数。
@RequestMapping("/param9")
public String param9(@CookieValue(name = "JSESSIONID") String jSessionId,
@CookieValue(name = "abcde", defaultValue = "这是晶晶姑娘") String abcde) {
System.out.println("获取了【JSESSIONID】Cookie的值是:" + jSessionId);
System.out.println("获取了【abcde】Cookie的值是:" + abcde);
return "param";
}

7、一个Pojo对象类型的参数
JavaBean对象
public class Person {
private Integer id;
private String name;
private Integer age;
private String phone;
有一个表单(表单项的name的属性值一定要跟javaBean的属性名一致):
<form action="${ pageContext.request.contextPath }/param10">
id:<input name="id" /><br/>
name:<input name="name" /><br/>
age:<input name="age" /><br/>
phone:<input name="phone" /><br/>
<input type="submit" />
</form>
Controller中的代码:
@RequestMapping("/param10")
public String param10(Person person) {
System.out.println("用户的信息:" + person);
return "param";
}
8、对象中套对象(级联属性)
GET请求中文乱码,找到Servers工程下Tomcat的配置文件server.xml配置文件,找到Connector标签,添加属性URIEncoding

javaBean对象
public class Book {
private String name;
private BigDecimal price;
public class Person {
private Integer id;
private String name;
private Integer age;
private String phone;
private Book book;
表单设置:
<h1>添加用户</h1>
<form action="${ pageContext.request.contextPath }/param10">
id:<input name="id" /><br/>
name:<input name="name" /><br/>
age:<input name="age" /><br/>
phone:<input name="phone" /><br/>
书名:<input name="book.name" /><br/>
价格:<input name="book.price" /><br/>
<input type="submit" />
</form>
SpringMVC(一)概述、解析器与注解的更多相关文章
- spring mvc:内部资源视图解析器2(注解实现)@Controller/@RequestMapping
spring mvc:内部资源视图解析器2(注解实现) @Controller/@RequestMapping 访问地址: http://localhost:8080/guga2/hello/goo ...
- SpringMVC——说说视图解析器
学习SpringMVC——说说视图解析器 各位前排的,后排的,都不要走,咱趁热打铁,就这一股劲我们今天来说说spring mvc的视图解析器(不要抢,都有位子~~~) 相信大家在昨天那篇如何获取请 ...
- SpringMVC 多视图解析器配置以及问题
在SpringMVC模式当中可以通过如下配置来支持多视图解析 <!-- jsp jstl --> <bean id="JSPViewResolver" class ...
- 学习SpringMVC——说说视图解析器
各位前排的,后排的,都不要走,咱趁热打铁,就这一股劲我们今天来说说spring mvc的视图解析器(不要抢,都有位子~~~) 相信大家在昨天那篇如何获取请求参数篇中都已经领略到了spring mvc注 ...
- springMVC自定义方法属性解析器
使用场景例子: 用户登陆系统一般会往Session里放置一个VO对象,然后在controller里会来获取用户的userId等信息. 之前的写法是:@SessionAttributes配合@Model ...
- SpringMVC(AbstractController,拦截器,注解)
1.Controller接口及其实现类 Controller是控制器/处理器接口,只有一个方法handleRequest,用于进行请求的功能处理(功能处理方法),处理完请求后返回ModelAndVie ...
- SpringMVC的视图解析器
ViewResolver和View介绍 SpringMVC用于处理视图最重要的两个接口是ViewResolver和View.ViewResolver的主要作用是把一个逻辑上的视图名称解析为一个真正的视 ...
- springMVC初探视图解析器——InternalResourceViewResolver
springmvc在处理器方法中通常返回的是逻辑视图,如何定位到真正的页面,就需要通过视图解析器. springmvc里提供了多个视图解析器,InternalResourceViewResolver就 ...
- SpringMVC 自定义参数解析器.
一.简述 有没有想过像 @RequestParam.@RequestBody 这些注解的工作原理呢?为什么 form 表单.application/json 的参数能够直接封装进 Bean 对象中呢? ...
随机推荐
- 错误:Several ports (8005, 8080, 8009) required by Tomcat v7.0 Server at localhost are already in use.
Several ports (8005, 8080, 8009) required by Tomcat v7.0 Server at localhost are already in use. The ...
- Java BC包做sm2加密方法 ,签名验签方法
package com.sdyy.common.bc_sm2; import org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateF ...
- C#黔驴技巧之去重(Distinct)
前言 关于C#中默认的Distinct方法在什么情况下才能去重,这个就不用我再多讲,针对集合对象去重默认实现将不再满足,于是乎我们需要自定义实现来解决这个问题,接下来我们详细讲解几种常见去重方案,孰好 ...
- cdp协议简介
啥是cdp 根据官网的说法,cdp(Chrome DevTools Protocol) 允许我们检测,调试Chromium, Chrome 和其他基于 Blink的 浏览器. 这个协议被广泛使用. 其 ...
- 仿真FFT(quartus安装)
软件下载:http://dl.altera.com/13.1/?edition=subscription 安装步骤: 接下来,仿真FFT: http://www.openhw.org/article/ ...
- 3D三栅极晶体管(摘抄)
英特尔的科学家们在2002年发明了三栅极晶体管——这是根据栅极有三面而取名的. 传统“扁平的”2D平面栅极被超级纤薄的.从硅基体垂直竖起的3D硅鳍状物所代替.电流控制是通过在鳍状物三面的每一面安装一个 ...
- JVM入门--类加载器
一.基础架构 概览 我们平时说的栈是指的Java栈,native method stack 里面装的都是native方法 细节架构图 二.类加载器 1.类的加载 方法区并不是存放方法的区域,其是存放类 ...
- 在ef core中使用postgres数据库的全文检索功能实战之中文支持
前言 有关通用的postgres数据库全文检索在ef core中的使用方法,参见我的上一篇文章. 本文实践了zhparser中文插件进行全文检索. 准备工作 安装插件,最方便的方法是直接使用安装好插件 ...
- wangeditor在移动端的web应用
废话不多说,直接上代码 前端(前端多说一句,在初始使用阶段,不知道是怎么回事,复制在看云上的文档的配置参数时,一直有错误,后台获取不到$_file,整整一上午,下午上网搜了一下别人的上传图片代码才好用 ...
- 2018-06-18 Javascript 基础1
js是一门基于对象的若类型语言,他和JAVA没有关系: js标签放置位置:1.内联 2.外部 3.内部: js代码是有执行顺序的,这点和css代码有所区别:当对象没有加载完或者还没加载的情况下js代码 ...