注:三层架构分为表述层(或表示层)、业务逻辑层、数据访问层,表述层表示前台页面和后台 servlet
-
war -
-
-
-
-
org.springframework -
spring-webmvc -
5.3.24 -
-
-
-
ch.qos.logback -
logback-classic -
1.2.11 -
-
-
-
javax.servlet -
javax.servlet-api -
4.0.1 -
provided -
-
-
-
org.thymeleaf -
thymeleaf-spring5 -
3.0.15.RELEASE -
-
- "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_4_0.xsd"
- version="4.0">
-
- <servlet>
- <servlet-name>SpringMVCservlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
- servlet>
- <servlet-mapping>
- <servlet-name>SpringMVCservlet-name>
-
- <url-pattern>/url-pattern>
- servlet-mapping>
- web-app>
- "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_4_0.xsd"
- version="4.0">
-
- <servlet>
- <servlet-name>SpringMVCservlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
-
- <init-param>
-
- <param-name>contextConfigLocationparam-name>
-
- <param-value>classpath:springMVC.xmlparam-value>
- init-param>
-
- <load-on-startup>1load-on-startup>
- servlet>
- <servlet-mapping>
- <servlet-name>SpringMVCservlet-name>
-
- <url-pattern>/url-pattern>
- servlet-mapping>
- web-app>
注:标签中使用 / 和 /* 的区别: / 所匹配的请求可以是 /login 或 .html 或 .js 或 .css 方式的请求路径,但是 / 不能匹配 .jsp 请求路径的请求因此就可以避免在访问jsp 页面时,该请求被 DispatcherServlet 处理,从而找不到相应的页面/* 则能够匹配所有请求,例如在使用过滤器时,若需要对所有请求进行过滤,就需要使用 /* 的写法
- @Controller
- public class HelloController {
- }
-
- <context:component-scan base-package="com.atguigu.mvc.controller"/>
-
-
- <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
- <property name="order" value="1"/>
- <property name="characterEncoding" value="UTF-8"/>
- <property name="templateEngine">
- <bean class="org.thymeleaf.spring5.SpringTemplateEngine">
- <property name="templateResolver">
- <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
-
- <property name="prefix" value="/WEB-INF/templates/"/>
-
- <property name="suffix" value=".html"/>
- <property name="templateMode" value="HTML5"/>
- <property name="characterEncoding" value="UTF-8"/>
- bean>
- property>
- bean>
- property>
- bean>
-
-
- <mvc:default-servlet-handler/>
-
- <mvc:annotation-driven>
- <mvc:message-converters>
-
- <bean
- class="org.springframework.http.converter.StringHttpMessageConverter">
- <property name="defaultCharset" value="UTF-8" />
- <property name="supportedMediaTypes">
- <list>
- <value>text/htmlvalue>
- <value>application/jsonvalue>
- list>
- property>
- bean>
- mvc:message-converters>
- mvc:annotation-driven>
- beans>
- @Controller
- public class HelloController {
- // "/"--> /WEB-INF/templates/index.html
- // @RequestMapping注解:处理请求和控制器方法之间的映射关系
- // @RequestMapping注解的value属性可以通过请求地址匹配请求,/表示的当前工程的上下文路径
- // localhost:8080/springMVC/
- @RequestMapping("/")
- public String index(){
- //返回视图名称
- return "index";
- }
- }
- html>
- <html lang="en" xmlns:th="http://www.thymeleaf.org">
- <head>
- <meta charset="UTF-8">
- <title>首页title>
- head>
- <body>
- <h1>欢迎进入首页h1>
- <a th:href="@{/target}">访问目标页面target.htmla>
- body>
- html>
- @Controller
- public class HelloController {
- // "/"--> /WEB-INF/templates/index.html
- // @RequestMapping注解:处理请求和控制器方法之间的映射关系
- // @RequestMapping注解的value属性可以通过请求地址匹配请求,/表示的当前工程的上下文路径
- // localhost:8080/springMVC/
- @RequestMapping("/")
- public String index(){
- //返回视图名称
- return "index";
- }
-
- @RequestMapping("/target")
- public String toTarget(){
- return "target";
- }
- }
- @Controller
- @RequestMapping("/hello")
- public class RequestMappingController {
-
- @RequestMapping("/testRequestMapping")
- public String success(){
- return "success";
- }
- }
index.html:
- html>
- <html lang="en" xmlns:th="http://www.thymeleaf.org">
- <head>
- <meta charset="UTF-8">
- <title>首页title>
- head>
- <body>
- <h1>欢迎你好啊!h1>
- <a th:href="@{/hello/testRequestMapping}">测试RequestMapping注解的位置a><br>
- body>
- html>
- <a th:href="@{/testRequestMapping}">测试RequestMapping注解的value位置-->testRequestMappinga><br>
- <a th:href="@{/test}">测试RequestMapping注解的value位置-->testa><br>
- @Controller
- //@RequestMapping("/hello")
- public class RequestMappingController {
-
- @RequestMapping(value = {"/testRequestMapping","/test"})
- public String success(){
- return "success";
- }
- }
- <a th:href="@{/test}">测试RequestMapping注解的method属性-->GETa><br>
-
- <form th:action="@{/test}" method="post">
- <input type="submit" value="测试RequestMapping注解的method属性--》POST"/>
- form>
当不指定method方法时,get和post请求都可以
- @Controller
- //@RequestMapping("/hello")
- public class RequestMappingController {
-
- @RequestMapping(
- value = {"/testRequestMapping","/test"},
- )
- public String success(){
- return "success";
- }
- }
当指定时,只能使用指定的请求方式
- @Controller
- //@RequestMapping("/hello")
- public class RequestMappingController {
-
- @RequestMapping(
- value = {"/testRequestMapping","/test"},
- method = {RequestMethod.GET,RequestMethod.POST}
- )
- public String success(){
- return "success";
- }
- }
注:1 、对于处理指定请求方式的控制器方法, SpringMVC 中提供了 @RequestMapping 的派生注解处理 get 请求的映射 -->@GetMapping处理 post 请求的映射 -->@PostMapping处理 put 请求的映射 -->@PutMapping处理 delete 请求的映射 -->@DeleteMapping2 、常用的请求方式有 get , post , put , delete但是目前浏览器只支持 get 和 post ,若在 form 表单提交时,为 method 设置了其他请求方式的字符串(put 或 delete ),则按照默认的请求方式 get 处理若要发送 put 和 delete 请求,则需要通过 spring 提供的过滤器 HiddenHttpMethodFilter ,在RESTful 部分会讲到
1.
- @GetMapping("/testGEtMapping")
- public String testGEtMapping(){
- return "success";
- }
<a th:href="@{/testGEtMapping}">测试GetMapping注解-->/testGetMappinga><br>
2 .
- @RequestMapping(value = "/testPut",method =RequestMethod.PUT)
- public String testPut(){
- return "success";
- }
- <form th:action="@{/testPut}" method="put">
- <input type="submit" value="测试form表单是否能够发送Put或delete请求方式"/>
- form>
<a th:href="@{/testParamsAndHeaders(username='admin',password=123456)}">测试RequestMapping注解的params属性a>
- @RequestMapping(
- value = "/testParamsAndHeaders",
- params = {"username","password=123456"}
- )
- public String testParamsAndHeaders(){
- return "success";
- }
注:若当前请求满足 @RequestMapping 注解的 value 和 method 属性,但是不满足 params 属性,此时 页面回报错400 : Parameter conditions "username, password!=123456" not met for actual request parameters: username={admin}, password={123456}
- @RequestMapping(
- value = "/testParamsAndHeaders",
- params = {"username","password=123456"},
- headers = {"Host=localhost:8080"}
- )
- public String testParamsAndHeaders(){
- return "success";
- }
<a th:href="@{/testParamsAndHeaders(username='admin',password=123456)}">测试RequestMapping注解的params属性a>
模糊匹配
- // ?:表示任意的单个字符
- // *:表示任意的0个或多个字符
- // **:表示任意的一层或多层目录
- // 注意:在使用**时,只能使用/**/xxx的方式
- @RequestMapping("/a?a/testAnt")
- // @RequestMapping("/a*a/testAnt")
- // @RequestMapping("/**/testAnt")
- public String testAnt(){
- return "success";
- }
<a th:href="@{/a.a/testAnt}">测试@RequestMapping可以匹配ant风格的路径-->?a><br>
<a th:href="@{/testPath/111/123456}">测试@RequestMapping支持路径中的占位符-->/testPatha><br>
- @RequestMapping("/testPath/{id}/{password}")
- public String testPath(@PathVariable("id") Integer id,@PathVariable("password") String password){
- System.out.println("id="+id+","+"password="+password);
- return "success";
- }
输出:id=111,password=123456
<a th:href="@{/testServletAPI(username='admin',password=123456)}">测试使用servletAPI获取请求参数a>
- @RequestMapping("/testServletAPI")
- //形参位置的request表示当前请求
- public String testServletAPI(HttpServletRequest request){
- String username = request.getParameter("username");
- String password = request.getParameter("password");
- System.out.println("username:"+username+",password:"+password);
- return "success";
- }
输出结果:username:admin,password:123456
<a th:href="@{/testParam(username='admin',password=123456)}">测试使用控制器的形参获取请求参数a><br>
- @RequestMapping("/testParam")
- public String testParamm(String username,String password){
- System.out.println("username:"+username+",password:"+password);
- return "success";
- }
输出结果:username:admin,password:123456
- <form th:action="@{/testParam}" method="get">
- 用户名:<input type="text" name="username"><br>
- 密码:<input type="password" name="password"><br>
- 爱好:<input type="checkbox" name="hobby" value="a">a
- <input type="checkbox" name="hobby" value="b">b
- <input type="checkbox" name="hobby" value="c">c
- <input type="checkbox" name="hobby" value="d">d<br>
- <input type="submit" value="测试使用控制器的形参获取请求参数">
- form>
- @RequestMapping("/testParam")
- public String testParamm(String username,String password,String[] hobby){
- //若请求所传输的请求参数中有多个同名的请求参数,此时可以在控制器方法的形参中设置字符串数组或者字符串类型的形参接收此请求参数
- //若使用字符串数组类型的形参,此参数的数组中包含了每一个数据
- //若使用字符串类型的形参,此参数的值为每个数据中间使用逗号拼接的结果
- System.out.println("username:"+username+",password:"+password+",hobby:"+ Arrays.toString(hobby));
-
- return "success";
- }
注:若请求所传输的请求参数中有多个同名的请求参数,此时可以在控制器方法的形参中设置字符串数组或者字符串类型的形参接收此请求参数若使用字符串数组类型的形参,此参数的数组中包含了每一个数据若使用字符串类型的形参,此参数的值为每个数据中间使用逗号拼接的结果
- <form th:action="@{/testParam}" method="get">
- 用户名:<input type="text" name="user_name"><br>
- 密码:<input type="password" name="pass_word"><br>
- 爱好:<input type="checkbox" name="hobby" value="a">a
- <input type="checkbox" name="hobby" value="b">b
- <input type="checkbox" name="hobby" value="c">c
- <input type="checkbox" name="hobby" value="d">d<br>
- <input type="submit" value="测试使用控制器的形参获取请求参数">
- form>
- @RequestMapping("/testParam")
- public String testParamm(@RequestParam("user_name") String username, @RequestParam("pass_word") String password, String[] hobby){
- //若请求所传输的请求参数中有多个同名的请求参数,此时可以在控制器方法的形参中设置字符串数组或者字符串类型的形参接收此请求参数
- //若使用字符串数组类型的形参,此参数的数组中包含了每一个数据
- //若使用字符串类型的形参,此参数的值为每个数据中间使用逗号拼接的结果
- System.out.println("username:"+username+",password:"+password+",hobby:"+ Arrays.toString(hobby));
- return "success";
- }
- @RequestMapping("/testParam")
- public String testParamm(@RequestParam(value = "user_name",required = false,defaultValue = "helloWorld") String username, @RequestParam("pass_word") String password, String[] hobby){
- //若请求所传输的请求参数中有多个同名的请求参数,此时可以在控制器方法的形参中设置字符串数组或者字符串类型的形参接收此请求参数
- //若使用字符串数组类型的形参,此参数的数组中包含了每一个数据
- //若使用字符串类型的形参,此参数的值为每个数据中间使用逗号拼接的结果
- System.out.println("username:"+username+",password:"+password+",hobby:"+ Arrays.toString(hobby));
- return "success";
- }
- @RequestMapping("/testParam")
- public String testParamm(
- @RequestParam(value = "user_name",required = false,defaultValue = "helloWorld") String username,
- @RequestParam("pass_word") String password,
- String[] hobby,
- @RequestHeader(value = "Host",required = true,defaultValue = "zxc")String host){
- //若请求所传输的请求参数中有多个同名的请求参数,此时可以在控制器方法的形参中设置字符串数组或者字符串类型的形参接收此请求参数
- //若使用字符串数组类型的形参,此参数的数组中包含了每一个数据
- //若使用字符串类型的形参,此参数的值为每个数据中间使用逗号拼接的结果
- System.out.println("username:"+username+",password:"+password+",hobby:"+ Arrays.toString(hobby));
- System.out.println("host:"+host);
- return "success";
- }
- @RequestMapping("/testParam")
- public String testParamm(
- @RequestParam(value = "user_name",required = false,defaultValue = "helloWorld") String username,
- @RequestParam("pass_word") String password,
- String[] hobby,
- @RequestHeader(value = "Host",required = true,defaultValue = "zxc")String host,
- @CookieValue("JSESSIONID")String JSESSIONID){
- //若请求所传输的请求参数中有多个同名的请求参数,此时可以在控制器方法的形参中设置字符串数组或者字符串类型的形参接收此请求参数
- //若使用字符串数组类型的形参,此参数的数组中包含了每一个数据
- //若使用字符串类型的形参,此参数的值为每个数据中间使用逗号拼接的结果
- System.out.println("username:"+username+",password:"+password+",hobby:"+ Arrays.toString(hobby));
- System.out.println("host:"+host);
- System.out.println("JSESSIONID:"+JSESSIONID);
- return "success";
- }
- <form th:action="@{/testpojo}" method="post">
- 用户名:<input type="text" name="username"><br>
- 密码:<input type="password" name="password"><br>
- 性别:<input type="radio" name="sex" value="男">男
- <input type="radio" name="sex" value="女">女<br>
- 年龄:<input type="text" name="age"><br>
- 邮箱:<input type="text" name="email"><br>
- <input type="submit" value="使用实体类接收请求参数">
- form>
User:
- public class User {
- private Integer id;
- private String username;
- private String password;
- private Integer age;
- private String sex;
- private String email;
-
- public User(){
-
- }
-
- public User(Integer id, String username, String password, Integer age, String sex, String email) {
- this.id = id;
- this.username = username;
- this.password = password;
- this.age = age;
- this.sex = sex;
- this.email = email;
- }
- //get,set,toString方法
- }
- @RequestMapping("/testpojo")
- public String testPojo(User user){
- System.out.println(user);
- return "success";
- }
输出结果:
User{id=null, username='?????????', password='123321', age=24, sex='??·', email='1234'}
但是会出现乱码现象
-
- <filter>
- <filter-name>CharacterEncodingFilterfilter-name>
- <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
- <init-param>
- <param-name>encodingparam-name>
- <param-value>UTF-8param-value>
- init-param>
- <init-param>
- <param-name>forceResponseEncodingparam-name>
- <param-value>trueparam-value>
- init-param>
- filter>
- <filter-mapping>
- <filter-name>CharacterEncodingFilterfilter-name>
- <url-pattern>/*url-pattern>
- filter-mapping>
注:SpringMVC 中处理编码的过滤器一定要配置到其他过滤器之前,否则无效