Spring MVC框架是一个开源的Java平台,为开发强大的基于JavaWeb应用程序提供全面的基础架构支持,并且使用起来非常简单容易。
Spring web MVC框架提供了MVC(模型 - 视图 - 控制器)架构,用于开发灵活和松散耦合的Web应用程序的组件。 MVC模式使应用程序的不同组件(输入逻辑,业务逻辑和UI逻辑)合理有效的分离,同时又有效的将各组件组合一起完成功能。
模型(Model) 封装了应用程序数据,通常它们将由POJO类组成。视图(View) 负责渲染模型数据,一般来说它负责生成客户端浏览器可以解释HTML输出。控制器(Controller) 负责处理用户请求并构建适当的模型,并将其传递给视图进行渲染。【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】业务逻辑流程分析:
视图解析器配置:
<!-- InternalResourceViewResolver 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 配置前缀地址 --> <property name="prefix" value="/pages/user/"/> <!-- 配置后缀地址 --> <property name="suffix" value=".jsp"/> </bean>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"; }params是要求此请求的参数匹配
params="username" 表示 请求地址必须带有username参数params="username=abc" 表示 请求参数中必须要有username,而且值还必须是abcparams="username!=abc" 表示 1、请求参数中不能有username参数。2、有username参数,但值不能等于abcparams="!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"; }是匹配请求头规则
/** * 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"; }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 请求 的区别与调用方式
【绝对匹配】
创建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"; }从请求头获取请求参数:
打印结果:
获取当前请求会话
打印结果:
在请求的方法上,写上类型和参数名,那么 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
把请求的参数名做为方法的参数名用来接收请求参数值即可。数组也一样。
@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
我们的方法参数名是username,而客户端无法(或不方便)传username的参数名。而只能传user参数,给username赋值。怎么办?<br/> @RequestParam(name="user") 把请求的参数user的值。注入到方法参数的username。<br/> @RequestParam注解name属性指定的值,要求客户端必须传递。否则就报错。
如果这个时候,我希望客户端哪怕没有传递user的参数的时候。也可以调用方法怎么办?
解决一:
修改@RequestParam注解的required=false的属性。表示这个参数不是必须传递。
设置 defaultValue属性是默认值。也就是如果客户端没有传递user参数,则使用defaultValue来设置username的值<br/>
@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"; }@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"; }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"; }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>