目录
1、SpringMvc概述
2、SpringMvc入门,实现helloworld
4、REST风格URL
5、映射请求参数&请求头&Cookie
6、使用 Servlet 原生API 作为spring容器函数调入参数
(1)Spring 为展现层提供的基于 MVC 设计理念的优秀的 Web 框架,是目前最主流的 MVC 框架之一
(2)Spring3.0 后全面超越 Struts2,成为最优秀的 MVC 框架
(3)Spring MVC 通过一套 MVC 注解,让 POJO 成为处理请求的控制器,而无须实现任何接口。
(4)支持 REST风格的URL请求
(5)采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性
MVC模型简介
架构模式是一个通用的、可重用的解决方案,用于在给定上下文中的软件体系结构中经常出现的问题。架构模式与软件设计模式类似,但具有更广泛的范围。
模型-视图-控制器模式,也称为MVC模式(Model View Controller)。用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。它把软件系统分为三个基本部分:
模型(Model):负责存储系统的中心数据。
视图(View):将信息显示给用户(可以定义多个视图)。
控制器(Controller):处理用户输入的信息。负责从视图读取数据,控制用户输入,并向模型发送数据,是应用程序中处理用户交互的部分。负责管理与用户交互交互控制。
视图和控制器共同构成了用户接口。
且每个视图都有一个相关的控制器组件。控制器接受输入,通常作为将鼠标移动、鼠标按钮的活动或键盘输入编码的时间。时间被翻译成模型或试图的服务器请求。用户仅仅通过控制器与系统交互。
例如:小时候玩的那种卡带式游戏机,Control是主机,一般来说我买一个主机就行了,只要他不坏,他就能一直让我玩这一类的游戏。View则是电视机和游戏手柄,电视机可以独立工作,他不管输入的是电视信号、影碟机信号还是游戏机信号,他只管显示,而且他决定了我们看到的效果是怎么样的,如果我想要个尺寸更大的或者彩色的显示效果,我只需要买个相应的电视机就行了,手柄也是可以换的,遥杆还是带震动的。Model则是游戏卡带,他决定了我玩的是什么游戏,是魂斗罗还是超级玛莉,而且游戏机主机和电视机生产厂家永远也不知道在上面有可能会运行什么样的游戏。卡带中可能会有游戏代码和存储单元,都根据游戏的需要而设计。
运行流程概述:
(1)导入jar包(交给maven)
(2)在web.xml中配置DispatcherServlet(就是修改默认配置文件的名字和位置,建议用默认位置和名字,不修改)
说明:
Servlet的web.xml配置文件 就会读到 spring 的配置文件
配置 DispatcherServlet :DispatcherServlet 默认加载 /WEB- INF/<servletName-servlet>.xml (蓝色部分自由命名,就是Servlet-name标签里面的名字)的 Spring 配置文件, 启动 WEB 层的 Spring 容器。可以通过 contextConfigLocation 初始化参数自定义配置文件的位置和名称。
以下将配置文件位置修改为类路径下的springmvc.xml。如果不写
springDispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
1
springDispatcherServlet
/
src文件夹下新建springmvc.xml配置文件,idea中可选择好需要哪些名称空间,至少要勾选context 和 mvc
配置好需要自动扫描的包
在src下新建包 com.atguigu.springmvc.handlers,在该包下新建HelloWorld类
package com.atguigu.springmvc.handlers;
@Controller //注入spring容器
public class HelloWorld{
/**使用@RequestMapping注解来映射请求的URL
*/
@RequestMapping("/helloworld")
public String hello(){
System.out.println("hello world"); //打印到控制台
//返回值通过视图解析器解析为实际物理视图
//通过prefix+returnVal+后缀这样的方式得到物理视图,然后转发
return "success"; //返回被视图解析器解析额的xx/success.xx页面
}
}
前端的index.jsp 超链接的herf被服务端的@RequestMapping注解捕获
Hello World
继续在springmvc.xml中配置视图解析器,视图解析器可以解析返回哪个页面,并将请求转发
视图名称解析器:将视图逻辑名解析为: /WEB-INF/pages/
/WEB-INF/pages/: 前缀
/
.jsp: 后缀
对于InternalResourceViewResolver解析器,通过prefix+returnVal+后缀 这样的方式得到实际物理视图,然后做转发
在WebContent/WEB-INF(类路径)创建views文件夹,编写success.jsp(即返回到浏览器的页面)
Sucess Page
3、RequestMapping注解讲解
① Spring MVC 使用 @RequestMapping 注解为控制器指定可以处理哪些 URL 请求,在控制器的类定义及方法定义处都可标注
@RequestMapping
② 类定义处:提供初步的请求映射信息。相对于 WEB 应用的根目录方法处:提供进一步的细分映射信息。相对于类定义处的 URL。若类定义处未标注 @RequestMapping,则方法处标记的 URL 相对于WEB 应用的根目录
③ DispatcherServlet 截获请求后,就通过控制器上@RequestMapping 提供的映射信息确定请求所对应的处理方法。
exp:以下代码就是设置的返回web根目录/springmvc(类注解)/testRequestMapping(方法注解)下的xx.success.xxx
在com.atguigu.springmvc.handlers包下创建SpringMVCTest.java类
package com.atguigu.springmvc.handlers
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest{
private static final String SUCCESS="success";
@RequestMapping("/testRequestMapping")
public String testRequestMapping(){
System.out.println("testRequestMapping");
return SUCCESS;
}
}
3.1 @RequestMapping映射请求参数、请求方法或请求头
(1)@RequestMapping 除了可以使用请求 URL 映射请求外,还可以使用请求方法、请求参数及请求头映射请求
(2)@RequestMapping 的 value、method、params 及 heads 分别表示请求 URL、请求方法(post or get)、请求参数及请求头(这两个并不是很常用)的映射条件,他们之间是与的关系,联合使用多个条件可让请求映射更加精确化。(前端请求必须同时满足所有映射,服务端才能响应)
exp:继续在SpringMVCTest.java文件中演示
package com.atguigu.springmvc.handlers
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest{
private static final String SUCCESS="success";
//除了用value属性指定url,还用method指定了请求方式
@RequestMapping(value="/testMethod",method=RequestMethod.POST)
public String testMethod(){
System.out.println("testMethod");
return SUCCESS;
}
}
前端代码必须同时满足url和请求方式,服务端才会响应
前端index.jsp 路径和post都对了,才会响应
扩展1:关于params 和 heads(用的少,了解即可)
param1: 表示请求必须包含名为 param1 的请求参数
!param1: 表示请求不能包含名为 param1 的请求参数
param1 != value1: 表示请求包含名为 param1 的请求参数,但其值不能为 value1
exp:{“param1=value1”, “param2”}: 请求必须包含名为 param1 和param2 的两个请求参数,且 param1 参数的值必须为 value1
代码演示:继续在SpringMVCTest.java文件中演示
以下代码要求,路径必须为value的值,同时,请求必须为post,同时,请求里面必须有username参数,和age参数,并且age不能为10。请求头的语言,必须是中文
package com.atguigu.springmvc.handlers
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest{
private static final String SUCCESS="success";
//除了用value属性指定url,还用method指定了请求方式,而且还必须满足请求参数有username...
@RequestMapping(value="/testMethod",method=RequestMethod.POST,
params={"username","age!=10"},headers={"Accept-Language=zh-CN,zh;q=0.8"})
public String testParamsAndHeaders(){
System.out.println("testParamAndHeaders");
return SUCCESS;
}
}
前端代码:
此时就访问不到,因为服务端要求age!=10
Test ParasAndHeaders
扩展2:@RequestMapping注解的属性值支持通配符
@RequestMapping注解的属性值支持Ant风格通配符
Ant 风格资源地址支持 3 种匹配符:
① ?:匹配文件名中的一个字符 –
② *:匹配文件名中的任意字符 –
③ **:** 匹配多层路径
exp:
/user/*/createUser: 匹配
exp: /user/aaa/createUser、/user/bbb/createUser 等 URL
/user/**/createUser: 匹配
exp: /user/createUser、/user/aaa/bbb/createUser 等 URL
/user/createUser??: 匹配
exp: /user/createUseraa、/user/createUserbb 等 URL
演示
package com.atguigu.springmvc.handlers
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest{
private static final String SUCCESS="success";
//除了用value属性指定url,还用method指定了请求方式,而且还必须满足请求参数有username...
@RequestMapping(value="/testAntPath/*/abc")
public String testAntPath(){
System.out.println("testParamAndHeaders");
return SUCCESS;
}
}
以上代码说明,浏览器的访问地址可以是工程路径/springmvc/testAntPath/任意字符/abc,都可以访问到服务端。以下都访问得到
Test AntPath
扩展2:@RequestMapping的value属性值搭配@PathVariable占位符
占位符指用{xxx},可以将客户端访问路径里面的xxx读取出来, 搭配@PathVariable注解 可以将 URL 中占位符读取出来的参数 {xxx} 绑定到控制器处理方法的入参中:即通过@PathVariable("xxx") 绑定到操作方法的入参中。
说明:占位符中输入任何值,都可以访问到服务端
比如下例题 输入 URL:工程路径/springmvc/testPathVariable/234234234({xx}中的可以是任意值),都可以访问到服务端,并且被@PathVariable(value="id")截获
package com.atguigu.springmvc.handlers
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest{
private static final String SUCCESS="success";
@RequestMapping(value="/testPathVariable/{id}")
public String testPathVariable(@PathVariable("id") Integer id){
System.out.println("testParamAndHeaders"+id);
return SUCCESS;
}
}
4.1 REST风格是什么
① REST风格,就是一种风格的URL,用这种风格设计请求的url,正在越来越流行。REST理论认为网络上的所有试题都是资源(一张图片,一段文本,一种服务等等)。这样每种资源对应一个特定的URI。要获取资源,访问它的URI就可以了。即URI为每一个资源的独一无二的识别符
② 锁定好资源后,如何操作它呢,常规操作就是增删改查,根据请求方式不同(GET,POST,PUT,DELETE),代表要做不同的操作
4.2 举例说明
(1)没有rest风格之前,原有url设计
http://localhost:8080/user/queryUserById.action?id=3
url中定义了动作(操作),参数具体锁定到操作的是谁
(2) 有了rest风格之后
rest中,认为互联网中所有东西,都是资源,自然都会有一个唯一的uri标识,
http://localhost:8080/user/3 代表的是id为3的那个用户记录(资源)
Exp:
/order/1 HTTP GET :得到 id = 1 的 order
/order/1 HTTP DELETE:删除 id = 1的 order
/order/1 HTTP PUT:更新id = 1的 order
/order HTTP POST:新增 order
注意:由于浏览器表单只支持 GET 与 POST 请求,而DELETE、PUT 等 method 并不支持,Spring3.0 添加了一个过滤器HiddenHttpMethodFilter,可以将这些请求转换为标准的 http 方法,使得支持 GET、POST、PUT 与DELETE 请求。
4.1 HiddenHttpMethodFilter 使用方法
(1)配置过滤器
HiddenHttpMethodFilter
org.springframework.web.filter.HiddenHttpMethodFilter
HiddenHttpMethodFilter
/*
前端代码
Test Rest Get
后端SpringMVCTest类中,占位符{xxx},即可获取到前端给的id
package com.atguigu.springmvc.handlers
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest{
private static final String SUCCESS="success";
@RequestMapping(value="/testRest/{id}",method=RequestMethod.PUT)
public String testRestPut(@PathVariable Integer id){
System.out.println("testRest Put:"+id);
return SUCCESS;
}
@RequestMapping(value="/testRest/{id}",method=RequestMethod.DELETE)
public String testRestDelete(@PathVariable Integer id){
System.out.println("testRest Delete:"+id);
return SUCCESS;
}
@RequestMapping(value="/testRest",method=RequestMethod.POST)
public String testRest(){
System.out.println("testRest POST");
return SUCCESS;
}
@RequestMapping(value="/testRest/{id}",method=RequestMethod.GET)
public String testRest(@PathVariable Integer id){
System.out.println("testRest GET:"+id);
return SUCCESS;
}
@RequestMapping(value="/testPathVariable/{id}")
public String testPathVariable(@PathVariable("id") Integer id){
System.out.println("testParamAndHeaders"+id);
return SUCCESS;
}
}
5.1 使用@RequestParam绑定请求参数值
说明:
在处理方法入参处使用 @RequestParam 可以把请求参数传递给请求方法
value属性:参数名
required属性:是否必须。默认为 true, 表示请求参数中必须包含对应的参数,若不存在,将抛出异常。改成false以后,请求URL中没有value属性值,也不会报错了defaultValue属性:请求参数的默认值。如果是int等基本数据类型,如果为空值,int没有null,会报错,为了避免麻烦,就可设置defaultValue属性为0
exp:
完整演示:
前端
Test RequestParam
服务端
package com.atguigu.springmvc.handlers
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest{
private static final String SUCCESS="success";
@RequestMapping(value="/testRequestParam")
public String testRestParam(@RequestParam(value="username") String un,@RequestParam(value="age",required=false,defaultValue="0") int age){
//控制台输出testRequestParam,username:atguigu,age:11
System.out.println("testRequestParam,username:"+ un +",age:"+age);
return SUCCESS;
}
}
5.2 使用@RequestHeader绑定请求头属性值(请求头这个用的机会并不多)
请求头包含了若干个属性(直接进浏览器调试模式,很容易找到各种请求头),服务器可据此获知客户端的信息,通过 @RequestHeader 即可将请求头中的属性值绑定到处理方法的入参中
package com.atguigu.springmvc.handlers
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest{
private static final String SUCCESS="success";
@RequestMapping(value="/testRequestHeader")
//找请求头的属性,直接去浏览器的开发者模式下找
public String testRequestHeader(@RequestHeader(value="Accept-Language")String al){
System.out.println("testRequestHeader,Accept-Language:"+al);
return SUCCESS;
}
}
前端代码
Test RequestHeader
5.3 使用 @CookieValue 绑定请求中的 Cookie 值(用得少)
@CookieValue 可以让处理方法入参绑定某个 Cookie 值,用法和绑定参数是一样的
服务端代码
package com.atguigu.springmvc.handlers
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest{
private static final String SUCCESS="success";
@RequestMapping(value="/testCookieValue")
//找cookie,直接去浏览器的开发者模式下找
public String testCookieValue(@CookieValue(value="JESSIONID")String sessionId){
System.out.println("testCookieValue:sessionId:"+sessionId);
return SUCCESS;
}
}
前端代码
Test CookieValue
5.4 使用POJO对象绑定请求参数值
说明:如果表单里面有一堆属性和属性值,一个一个获取参数,太麻烦了。用POJO对象可以快速获取完整个表单
5.4.1POJO对象介绍
"Plain Ordinary Java Object",简单普通的java对象。主要用来指代那些没有遵循特定的java对象模型,约定或者框架的对象。
POJO的内在含义是指那些:
有一些private的参数作为对象的属性,然后针对每一个参数定义get和set方法访问的接口。
没有从任何类继承、也没有实现任何接口,更没有被其它框架侵入的java对象。
5.4.2 演示
Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值。支持级联属性(指属性的属性)。
级联属性如:dept.deptId、dept.address.tel 等
前端代码:
在com.atguigu.springmvc.entities包下新建一个User.java类。按照前端的属性来,会被自动封装进去
package com.atguigu.springmvc.entities;
public class User{
private String username;
private String password;
private String email;
private int age;
private Address address //级联属性,配合后面的Address类
}
再建一个Address.java 演示级联属性
package com.atguigu.springmvc.entities;
public class Address{
private String province;
private String city;
//后面就是标准的无参构造器,有参构造器,toString,get,set方法
public String getProvince(){
return province;
}
}
最后去springMVCTest.java中写服务端代码
获取以下值
package com.atguigu.springmvc.handlers
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest{
private static final String SUCCESS="success";
@RequestMapping(value="/testPojo")
public String testPojo(User user){
System.out.println("testPojo"+user);
return SUCCESS;
}
}
输出user对象,就是那个表单的所有属性
(1)MVC 的 Handler 方法可以接受的 ServletAPI 类型的参数 参考Servlet
HttpServletRequest
HttpServletResponse
HttpSession
java.security.Principal
Locale
InputStream
OutputStream
Reader
Writer
这些参数可直接作为形参,送进函数。
(2)演示
前端代码
Test ServletAPI
服务端代码
package com.atguigu.springmvc.handlers
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest{
private static final String SUCCESS="success";
@RequestMapping(value="/testServletAPI")
public String testServletAPI(HttpServletRequest request,HttpServletResponse response){
System.out.println("testServletAPI"+request+","+response);
return SUCCESS;
}
}