我爱Java系列---【 SpringMVC 入门案例】
一、整体流程(三大件:DispatcherServlet,HandlerMapping,HandlerAdapter)
二、具体步骤(对上图步骤做了精简化处理,便于理解)
第一步:浏览器付出请求
第二步:请求到达服务器(springmvc 对地址进行处理 )前端控制器 (拿到地址)
第三步:前端控制器找处理器映射器 对地址进行处理 变成数据链 返回给前端控制器
第四步:去找适配器 适配根据数据链找到对应的处理器(就是我们自己写的那个controller类)
第五步:处理器进行业务处理 然后得到结果吧这个结果(把结果放到一个模型(modelandview)对象)给适配器 适配器中转给前端控制器
第六步:找视图解析器 把模型(modelandview)进行整理 整理后的结果有给前端控制器
第七步:把6步得到的结果进行页面的渲染得到一张页面同时响应回浏览器
三、开发步骤
1.导入依赖
2、配置前端控制器(配置在web.xml 参考servlet的配置方式)
3、在springMVC的核心配置文件里面配<mvc: 作用:相当于拥有了映射器和适配器
4、配视图解析器
5、使用的时候传入参数(模型(modelandview)对象)
四、代码演示
准备工作:导入依赖
1 <dependency> 2 <groupId>javax.servlet</groupId> 3 <artifactId>javax.servlet-api</artifactId> 4 <version>3.1.0</version> 5 <scope>provided</scope> 6 </dependency> 7 <dependency> 8 <groupId>javax.servlet.jsp</groupId> 9 <artifactId>javax.servlet.jsp-api</artifactId> 10 <version>2.3.3</version> 11 <scope>provided</scope> 12 </dependency> 13 <dependency> 14 <groupId>javax.servlet</groupId> 15 <artifactId>jstl</artifactId> 16 <version>1.2</version> 17 </dependency> 18 <!-- JSTL stop --> 19 <dependency> 20 <groupId>taglibs</groupId> 21 <artifactId>standard</artifactId> 22 <version>1.1.2</version> 23 </dependency> 24 25 <dependency> 26 <groupId>org.springframework</groupId> 27 <artifactId>spring-context</artifactId> 28 <version>5.1.8.RELEASE</version> 29 </dependency> 30 <dependency> 31 <groupId>org.springframework</groupId> 32 <artifactId>spring-webmvc</artifactId> 33 <version>5.1.8.RELEASE</version> 34 </dependency> 35 <dependency>
1、 创建 web.xml 文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 5 version="3.1"> 6 7 <servlet> 8 <servlet-name>springmvc</servlet-name> 9 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 10 <!--配置初始化参数,用于读取 SpringMVC 的配置文件 11 在springmvc配置文件中指定要扫描的controller所在的包的路径--> 12 <init-param> 13 <param-name>contextConfigLocation</param-name> 14 <param-value>classpath:springmvc.xml</param-value> 15 </init-param> 16 17 <!-- 配置 servlet 的对象的创建时间点:应用加载时创建。 18 取值只能是非 0 正整数,表示启动顺序 --> 19 <load-on-startup>1</load-on-startup> 20 </servlet> 21 <servlet-mapping> 22 <servlet-name>springmvc</servlet-name> 23 <!-- <url-pattern>*.do</url-pattern>--> 24 <url-pattern>/</url-pattern><!--接收所有请求--> 25 </servlet-mapping> 26 27 <filter> 28 <filter-name>encodingFilter</filter-name> 29 <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 30 <init-param> 31 <param-name>encoding</param-name> 32 <param-value>utf-8</param-value> 33 </init-param> 34 </filter> 35 <filter-mapping> 36 <filter-name>encodingFilter</filter-name> 37 <url-pattern>/*</url-pattern> 38 </filter-mapping> 39 40 </web-app>
2.创建springmvc.xml文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:mvc="http://www.springframework.org/schema/cache" 6 7 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> 8 <!--指定要扫描的UserController所在的包的路径,这样就可以扫描类中的注解了,此时类中的注解才能正常被spring容器所操作--> 9 <context:component-scan base-package="com.heima.web"></context:component-scan> 10 11 <!--指明我就是要用requestMapping handler映射处理器 12 //两个原因: 13 版本原因 其实RequestMappingHandlerMapping在以前版本就已经有这个类了,但是5.0以前版本,默认并不是这个 14 其他的原因 转换 Jason转换 自定义格式转换 都需要他 15 --> 16 <!--<mvc:annotation-driven></mvc:annotation-driven>-->相当于有了映射器和适配器 17 18 <!--定制化内部视图解析器--> 19 <bean id="InternalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 20 21 <property name="prefix" value="/WEB-INF/pages/"/> 22 <property name="suffix" value=".jsp"/> 23 </bean> 24 </beans>
3.创建UserController类
1 @Controller//1.把UserController这个类放进spring容器中 2 @RequestMapping("/user") 3 public class UserController { 4 @RequestMapping("/test1")//2.指定下面这个方法所映射的路径 5 public ModelAndView test1(ModelAndView modelAndView){ 6 Date date = new Date(); 7 String content = "当前时间:"+date.toLocaleString(); 8 //类似于request.setAttribute("属性名","属性值") 9 modelAndView.addObject("content",content); 10 //等同于request.getDispatcher("").forward(request,response) 11 modelAndView.setViewName("user/list"); 12 return modelAndView; 13 14 } 15 16 @RequestMapping("/test2_1") 17 public ModelAndView test2(ModelAndView modelAndView,int id){ 18 System.out.println(id); 19 Date date = new Date(); 20 String content = "当前时间:"+date.toLocaleString(); 21 //类似于request.setAttribute("属性名","属性值") 22 modelAndView.addObject("content",content); 23 //等同于request.getDispatcher("").forward(request,response) 24 modelAndView.setViewName("hello/Hello"); 25 return modelAndView; 26 27 } 28 @RequestMapping("/test2_2") 29 public ModelAndView test2_2(ModelAndView modelAndView,User user){ 30 System.out.println(user); 31 Date date = new Date(); 32 String content = "当前时间:"+date.toLocaleString(); 33 //类似于request.setAttribute("属性名","属性值") 34 modelAndView.addObject("content",content); 35 //等同于request.getDispatcher("").forward(request,response) 36 modelAndView.setViewName("hello/Hello"); 37 return modelAndView; 38 39 } 40 41 @RequestMapping(value = "/test3",method = RequestMethod.POST) 42 public ModelAndView test3(ModelAndView modelAndView,User user){ 43 System.out.println(user); 44 Date date = new Date(); 45 String content = "当前时间:"+date.toLocaleString(); 46 //类似于request.setAttribute("属性名","属性值") 47 modelAndView.addObject("content",content); 48 //等同于request.getDispatcher("").forward(request,response) 49 modelAndView.setViewName("user/list"); 50 return modelAndView; 51 52 } 53 /*params表示必须传的参数*/ 54 @RequestMapping(value = "/test4",params = "username") 55 public ModelAndView test4(ModelAndView modelAndView,User user){ 56 System.out.println(user); 57 Date date = new Date(); 58 String content = "当前时间:"+date.toLocaleString(); 59 //类似于request.setAttribute("属性名","属性值") 60 modelAndView.addObject("content",content); 61 //等同于request.getDispatcher("").forward(request,response) 62 modelAndView.setViewName("user/list"); 63 return modelAndView; 64 65 } 66 67 /*headers表示必须带"user-agent"请求头,这个默认带,换一个就报404了*/ 68 @RequestMapping(value = "/test5",headers = "user-agent")// 69 public ModelAndView test5(ModelAndView modelAndView,User user){ 70 System.out.println(user); 71 Date date = new Date(); 72 String content = "当前时间:"+date.toLocaleString(); 73 //类似于request.setAttribute("属性名","属性值") 74 modelAndView.addObject("content",content); 75 //等同于request.getDispatcher("").forward(request,response) 76 modelAndView.setViewName("user/list"); 77 return modelAndView; 78 79 } 80 81 /*@RequestParam 解决三个问题:1.大部分情况为了解决不传参问题,给定默认值 82 2.为了解决前后端参数名不同步问题,前后端参数名不一致 83 3.最后才是为了解决编译导致无参数名问题 84 */ 85 86 @RequestMapping(value = "/test6")//@RequestParam(name = "id")可以防止setting-->java compiler-->generate debugging info没有被选中 87 //若没有被选中,程序只认识数据类型,却识别不出来数据名,@RequestParam(name = "id")可以强制指明数据名 88 public ModelAndView test6(ModelAndView modelAndView, @RequestParam(name = "id",defaultValue = "123") int id, @RequestParam(name = "username")String username,@RequestParam(name = "price")double price){ 89 System.out.println(id+"---"+username+"---"+price); 90 91 Date date = new Date(); 92 String content = "当前时间:"+date.toLocaleString(); 93 //类似于request.setAttribute("属性名","属性值") 94 modelAndView.addObject("content",content); 95 //等同于request.getDispatcher("").forward(request,response) 96 modelAndView.setViewName("user/list"); 97 return modelAndView; 98 99 } 100 101 /*javaBean数据的绑定,注意参数名一定要与类里的属性名保持一致*/ 102 @RequestMapping(value = "/test7") 103 public ModelAndView test7(ModelAndView modelAndView,User user){ 104 System.out.println(user); 105 106 Date date = new Date(); 107 String content = "当前时间:"+date.toLocaleString(); 108 //类似于request.setAttribute("属性名","属性值") 109 modelAndView.addObject("content",content); 110 //等同于request.getDispatcher("").forward(request,response) 111 modelAndView.setViewName("user/list"); 112 return modelAndView; 113 114 } 115 116 /*javaBean数据的绑定,注意参数名一定要与类里的属性名保持一致*/ 117 @RequestMapping(value = "/test8") 118 public ModelAndView test8(ModelAndView modelAndView,User user){ 119 System.out.println(user); 120 121 Date date = new Date(); 122 String content = "当前时间:"+date.toLocaleString(); 123 //类似于request.setAttribute("属性名","属性值") 124 modelAndView.addObject("content",content); 125 //等同于request.getDispatcher("").forward(request,response) 126 modelAndView.setViewName("user/list"); 127 return modelAndView; 128 129 } 130 131 132 /*复合对象类型数组是参数数据的绑定,注意:前端name=user.username*/ 133 @RequestMapping(value = "/test9") 134 public ModelAndView test9(ModelAndView modelAndView, QueryVo queryVo){ 135 System.out.println(queryVo); 136 137 Date date = new Date(); 138 String content = "当前时间:"+date.toLocaleString(); 139 //类似于request.setAttribute("属性名","属性值") 140 modelAndView.addObject("content",content); 141 //等同于request.getDispatcher("").forward(request,response) 142 modelAndView.setViewName("user/list"); 143 return modelAndView; 144 145 } 146 147 /*复合对象类型map集合是对象数据的绑定,注意:前端name=smap['name'],定义map不能用map关键字*/ 148 @RequestMapping(value = "/test10") 149 public ModelAndView test10(ModelAndView modelAndView, QueryVo queryVo){ 150 System.out.println(queryVo); 151 152 Date date = new Date(); 153 String content = "当前时间:"+date.toLocaleString(); 154 //类似于request.setAttribute("属性名","属性值") 155 modelAndView.addObject("content",content); 156 //等同于request.getDispatcher("").forward(request,response) 157 modelAndView.setViewName("user/list"); 158 return modelAndView; 159 } 160 161 //练习11 演示复合对象类型list集合是对象参数绑定 162 @RequestMapping(value = "/test11") 163 public ModelAndView test11(ModelAndView modelAndView, QueryVo queryVo){ 164 System.out.println(queryVo); 165 166 Date date = new Date(); 167 String content = "当前时间:"+date.toLocaleString(); 168 //类似于request.setAttribute("属性名","属性值") 169 modelAndView.addObject("content",content); 170 //等同于request.getDispatcher("").forward(request,response) 171 modelAndView.setViewName("user/list"); 172 return modelAndView; 173 } 174 }
4.创建User类,和QueryVo类
1 public class User { 2 private int id; 3 private String username; 4 private String desc; 5 6 @Override 7 public String toString() { 8 return "User{" + 9 "id=" + id + 10 ", username='" + username + '\'' + 11 ", desc='" + desc + '\'' + 12 '}'; 13 } 14 15 public int getId() { 16 return id; 17 } 18 19 public void setId(int id) { 20 this.id = id; 21 } 22 23 public String getUsername() { 24 return username; 25 } 26 27 public void setUsername(String username) { 28 this.username = username; 29 } 30 31 public String getDesc() { 32 return desc; 33 } 34 35 public void setDesc(String desc) { 36 this.desc = desc; 37 } 38 }
1 public class QueryVo { 2 private User user; 3 private int age; 4 private String [] hobbies; 5 private Map smap; 6 private List<User> users; 7 8 public List<User> getUsers() { 9 return users; 10 } 11 12 public void setUsers(List<User> users) { 13 this.users = users; 14 } 15 16 public Map getSmap() { 17 return smap; 18 } 19 20 public void setSmap(Map smap) { 21 this.smap = smap; 22 } 23 24 public String[] getHobbies() { 25 return hobbies; 26 } 27 28 public void setHobbies(String[] hobbies) { 29 this.hobbies = hobbies; 30 } 31 32 public User getUser() { 33 return user; 34 } 35 36 public void setUser(User user) { 37 this.user = user; 38 } 39 40 public int getAge() { 41 return age; 42 } 43 44 public void setAge(int age) { 45 this.age = age; 46 } 47 48 49 @Override 50 public String toString() { 51 return "QueryVo{" + 52 "user=" + user + 53 ", age=" + age + 54 ", hobbies=" + Arrays.toString(hobbies) + 55 ", smap=" + smap + 56 ", users=" + users + 57 '}'; 58 } 59 }
5.创建前端页面list.jsp和index.jsp
list.jsp页面
1 <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 <html> 3 <head> 4 <title>Title</title> 5 </head> 6 <body> 7 <div style="text-align: center ;margin:100px 100px;color: blue;"> 8 <font size="20px">${content}</font> 9 </div> 10 </body> 11 </html>
index.jsp页面
1 <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 </head> 6 <body> 7 <h2>Hello World!</h2> 8 <div> 9 <fieldset> 10 <legend>练习1</legend> 11 <a href="/user/test1">常规使用1</a> 12 </fieldset> 13 14 <fieldset> 15 <legend>练习2</legend> 16 <a href="/user/test2_1">常规使用2</a> 17 </fieldset> 18 19 <fieldset> 20 <legend>练习3</legend> 21 <a href="/user/test3">指明请求必须是某类型</a> 22 <form action="/user/test3" method="post"> 23 <input type="text" name="username"><br> 24 <input type="submit" value="点我提交"> 25 </form> 26 27 </fieldset> 28 29 <fieldset> 30 <legend>练习4</legend> 31 <a href="/user/test4">演示RequestMapping必须传某某参数</a> 32 <form action="/user/test4" > 33 <input type="text" name="username"><br> 34 <input type="submit" value="点我提交"> 35 </form> 36 37 </fieldset> 38 39 <fieldset> 40 <legend>练习5</legend> 41 <a href="/user/test5">演示带某某请求</a> 42 <form action="/user/test5" > 43 <input type="text" name="username"><br> 44 <input type="submit" value="点我提交"> 45 </form> 46 47 </fieldset> 48 49 <fieldset> 50 <legend>练习6</legend> 51 <a href="/user/test6">演示简单类型的参数绑定</a> 52 <form action="/user/test6" > 53 id:<input type="text" name="id"><br> 54 username:<input type="text" name="username"><br> 55 price:<input type="text" name="price"><br> 56 <input type="submit" value="点我提交"> 57 </form> 58 59 </fieldset> 60 61 <fieldset> 62 <legend>练习7</legend> 63 <a href="/user/test7">演示javaBean的参数绑定</a> 64 <form action="/user/test7" > 65 id:<input type="text" name="id"><br> 66 用户名:<input type="text" name="username"><br> 67 描述:<input type="text" name="desc"><br> 68 <input type="submit" value="点我提交"> 69 </form> 70 71 </fieldset> 72 73 <fieldset> 74 <legend>练习8</legend> 75 <a href="/user/test8">演示复合对象的参数绑定</a> 76 <form action="/user/test8" > 77 id:<input type="text" name="user.id"><br> 78 age:<input type="text" name="age"><br> 79 用户名:<input type="text" name="user.username"><br> 80 描述:<input type="text" name="user.desc"><br> 81 <input type="submit" value="点我提交"> 82 </form> 83 84 </fieldset> 85 86 <fieldset> 87 <legend>练习9</legend> 88 <a href="/user/test9">演示复合对象的数组参数的绑定</a> 89 <form action="/user/test9" > 90 id:<input type="text" name="user.id"><br> 91 age:<input type="text" name="age"><br> 92 用户名:<input type="text" name="user.username"><br> 93 描述:<input type="text" name="user.desc"><br> 94 爱好:<input type="checkbox" name="hobbies" value="抽烟">抽烟 95 <input type="checkbox" name="hobbies" value="喝酒">喝酒 96 <input type="checkbox" name="hobbies" value="烫头">烫头 <br> 97 <input type="submit" value="点我提交"> 98 </form> 99 </fieldset> 100 101 <fieldset> 102 <legend>练习10</legend> 103 <a href="/user/test10">演示复合对象的map集合参数的绑定</a> 104 <form action="/user/test10" > 105 id:<input type="text" name="user.id"><br> 106 age:<input type="text" name="age"><br> 107 用户名:<input type="text" name="user.username"><br> 108 描述:<input type="text" name="user.desc"><br> 109 爱好:<input type="checkbox" name="hobbies" value="抽烟">抽烟 110 <input type="checkbox" name="hobbies" value="喝酒">喝酒 111 <input type="checkbox" name="hobbies" value="烫头">烫头 <br> 112 收款人:<input type="text" name="smap['name']"> 113 电话:<input type="text" name="smap['tel']"> 114 <input type="submit" value="点我提交"> 115 </form> 116 </fieldset> 117 118 <fieldset> 119 <legend>练习11</legend> 120 <a href="/user/test11">演示复合对象类型list集合是对象的参数绑定</a> 121 <form action="/user/test11" > 122 用户名:<input type="text" name="user.username"><br> 123 爱好:<input type="checkbox" name="hobbies" value="抽烟">抽烟 124 <input type="checkbox" name="hobbies" value="喝酒">喝酒 125 <input type="checkbox" name="hobbies" value="烫头">烫头 <br> 126 收款人:<input type="text" name="smap['name']"> 127 电话:<input type="text" name="smap['tel']"> 128 129 收货人列表:<br> 130 收货人1:<input type="text" name="users[0].id"><input type="text" name="users[0].username"><br> 131 收货人2:<input type="text" name="users[1].id"><input type="text" name="users[1].username"><br> 132 收货人3:<input type="text" name="users[2].id"><input type="text" name="users[2].username"><br> 133 <input type="submit" value="点我提交"> 134 </form> 135 </fieldset> 136 </div> 137 </body> 138 </html>
6.创建好的工程结构
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?