SpringMVC简介(网摘)
SpringMVC 全称是 Spring Web MVC,是spring框架一部分,是一个 mvc 的框架,和struts2一样是一个表现层框架。
SpringMVC 是 Spring 家族的一员,Spring是将现在开发中流行的组件进行组合而成的一个框架!它用在基于MVC的表现层开发,类似于struts2框架
mvc 是一种设计模式。设计模式理解为最佳实践。
一、配置 SpringMVC
导入相应的包
pom.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > 4.11</version > <scope > test</scope > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-context</artifactId > <version > 5.1.3.RELEASE</version > </dependency > <dependency > <groupId > com.mchange</groupId > <artifactId > c3p0</artifactId > <version > 0.9.5.2</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 8.0.13</version > </dependency > <dependency > <groupId > cglib</groupId > <artifactId > cglib</artifactId > <version > 3.2.10</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-aspects</artifactId > <version > 5.1.2.RELEASE</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-test</artifactId > <version > 5.1.3.RELEASE</version > <scope > test</scope > </dependency > <dependency > <groupId > commons-dbcp</groupId > <artifactId > commons-dbcp</artifactId > <version > 1.4</version > </dependency > <dependency > <groupId > commons-pool</groupId > <artifactId > commons-pool</artifactId > <version > 1.6</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-jdbc</artifactId > <version > 5.1.3.RELEASE</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-orm</artifactId > <version > 5.1.3.RELEASE</version > </dependency > <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis</artifactId > <version > 3.4.6</version > </dependency > <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis-spring</artifactId > <version > 1.3.2</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-web</artifactId > <version > 5.1.3.RELEASE</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-webmvc</artifactId > <version > 5.1.3.RELEASE</version > </dependency > <dependency > <groupId > jstl</groupId > <artifactId > jstl</artifactId > <version > 1.2</version > </dependency > <dependency > <groupId > taglibs</groupId > <artifactId > standard</artifactId > <version > 1.1.2</version > </dependency > <dependency > <groupId > javax.servlet</groupId > <artifactId > servlet-api</artifactId > <version > 2.5</version > <scope > provided</scope > </dependency >
Spring的配置文件
springmvc.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:context ="http://www.springframework.org/schema/context" xmlns:mvc ="http://www.springframework.org/schema/mvc" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd" > <context:component-scan base-package ="net.togogo.controller" > </context:component-scan > <mvc:annotation-driven /> </beans
Servlet的配置文件
顺序不能错,之前试过把 <filter>
放 <sevlet>
后面,报错了。
web.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app > <display-name > Archetype Created Web Application</display-name > <filter > <filter-name > characterEncodingFilter</filter-name > <filter-class > org.springframework.web.filter.CharacterEncodingFilter</filter-class > <init-param > <param-name > encoding</param-name > <param-value > UTF-8</param-value > </init-param > <init-param > <param-name > forceEncoding</param-name > <param-value > true</param-value > </init-param > </filter > <filter-mapping > <filter-name > characterEncodingFilter</filter-name > <url-pattern > /*</url-pattern > </filter-mapping > <servlet > <servlet-name > springmvc</servlet-name > <servlet-class > org.springframework.web.servlet.DispatcherServlet</servlet-class > <init-param > <param-name > contextConfigLocation</param-name > <param-value > classpath:springmvc.xml</param-value > </init-param > </servlet > <servlet-mapping > <servlet-name > springmvc</servlet-name > <url-pattern > *.do</url-pattern > </servlet-mapping > </web-app >
二、Hello, Contoroller !
一个简单的例子体会 SpringMVC 的神奇
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package net.togogo.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;@Controller public class HelloController { @RequestMapping ("/hello" ) public String sayHello () { System.out.println("-----HelloController.sayHello()-----" ); return "Hello.html" ; } }
@Controller
、 @Service
、@Repository
这三个注解的作用其实跟 @Component
一样,属于它的别名(不知道能不能这样理解),它方便程序员们区分这个类是属于哪个层面的。
@Repository
对应持久层,也就是dao层
@Service
对应业务层
@Controller
对应控制层(视图层),也就是 servlet
在 web.xml 里,配置了匹配 *.do
结尾的 url 交由 SpringMVC 处理,SpringMVC 去寻找声明为控制层的类,然后匹配相对应的 @RequestMapping
注解的方法,执行里面的内容。返回的 Hello.html
即为要显示给用户的前台页面,文件在 webapp/Hello.html
限制 Get/Post 方法
在 @RequestMapping
里指定 method
值就可以了,如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @Controller public class GetPost { @RequestMapping (value = "/onlyget" , method = RequestMethod.GET) public String onlyGet () { System.out.println("-----onlyGet()-----" ); return "Hello.html" ; } @RequestMapping (value = "/onlypost" , method = RequestMethod.POST) public String onlyPost () { System.out.println("-----onlyPost()-----" ); return "Hello.html" ; } @RequestMapping (value = "/getandpost" , method = {RequestMethod.POST,RequestMethod.GET}) public String GetAndPost () { System.out.println("-----GetAndPost-----" ); return "Hello.html" ; } }
获取页面传递过来的参数
传统方式获取
传入 HttpServletRequest
和 HttpServletResponse
,然后通过 .getParameter()
方法获取
getParameter.java 1 2 3 4 5 6 7 8 9 10 11 @Controller public class getParameter { @RequestMapping ("/getparameter" ) public String getParameter (HttpServletRequest request, HttpServletResponse response, HttpSession session, Model model) { String id = request.getParameter("id" ); model.addAttribute("id" , id); model.addAttribute("session" , session); return "/getparameter.jsp" ; } }
注解方式获取
使用 @RequestParam
注解 (Get/Post 都能用),该注解有两个参数:
value: 传入值的名称
required: 是否必须传来该参数 (为 true 时如果客户端没传来该参数会报400错误)
defaultValue:默认值,如果客户端没有传来该参数,那么就会指认该默认值。
1 2 3 4 @RequestMapping ("/getparameter2" ) public void getParameter (@RequestParam(value = "id" , required = true ) String aaa) { System.out.println(aaa); }
value值可以省略,省略的话,入参的名字就是要获取的参数的id,例:1 2 3 4 @RequestMapping ("/getparameter2" ) public void getParameter (@RequestParam(required = true ) String id) { System.out.println(id); }
URL占位符
通过在方法中使用 @PathVariable
获取 @RequestMapping
中的 {×××}
中的 ×××
变量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Controller public class ZhanWeiFu { @RequestMapping ("/getuser/{userid}" ) public String singleZhanWeiFu (@PathVariable String userid, Model model) { model.addAttribute("userid" , userid); return "/ZhanWeiFu.jsp" ; } @RequestMapping ("/getuser/{groupid}/{userid}" ) public String multiZhanWeiFu (@PathVariable String groupid, @PathVariable String userid, Model model) { model.addAttribute("groupid" , groupid); model.addAttribute("userid" , userid); return "/ZhanWeiFu.jsp" ; } }
checkbox 的获取
1 2 3 4 5 6 7 <form action="${pageContext.request.contextPath}/getcheckbox.do" method="post" > <input type="checkbox" name="checkid" value="001" /> <input type="checkbox" name="checkid" value="002" /> <input type="checkbox" name="checkid" value="003" /> <input type="checkbox" name="checkid" value="004" /> <input type="submit" /> </form>
1 2 3 4 5 6 7 8 @Controller public class GetCheckBox { @RequestMapping ("/getcheckbox" ) public void getCheckbox (String[] checkid) { String a = Arrays.toString(checkid); System.out.println(a); } }
输出结果(全选时):
[001, 002, 003, 004]
获取对象信息
假设有一个 pojo 类 User:
User.java 1 2 3 4 5 6 7 8 9 public class User { private int id; private String username; private String password; private int level; private String avatar; }
前台的表格中,name属性名要与 pojo 类的属性名一一对应,然后 SpringMVC 便会自动将属性设置到 pojo 对象中
1 2 3 4 5 6 7 8 <form action="${pageContext.request.contextPath}/getuserpojo.do" method="post" > <input type="text" name="id" value="1" /> <input type="text" name="username" value="crazykid" /> <input type="text" name="password" value="123456" /> <input type="text" name="level" value="0" /> <input type="text" name="avatar" value="" /> <input type="submit" /> </form>
Controller:
1 2 3 4 5 6 7 @Controller public class getUserPojo { @RequestMapping ("/getuserpojo" ) public void getUserPojo (Model model, User user) { System.out.println(user); } }
输出结果:
User{id=1, username=’crazykid’, password=’123456’, level=0, avatar=’’}
获取客户端的 Cookie 信息
使用 @CookieValue
注解
value : 要获取的 Cookie 名字
required:是否必须
如果 required = false ,客户端没有传过来该 Cookie ,就会报400错误:
Missing cookie ‘XXXXX’ for method parameter of type String
1 2 3 4 5 6 7 @Controller public class GetCookie { @RequestMapping ("/getcookie" ) public void GetCookie (@CookieValue(value = "JSESSIONID" ,required = true ) String sessionId, Model model) { System.out.println(sessionId); } }
转发页面
redirect 方法
相当于 response.sendRedirect()
,浏览器地址发生变化,执行一个新的 request 和 response。如果有 model 数据,会自动在 URL 后面加上 GET 参数。
1 2 3 4 5 @RequestMapping ("/redirect" )public String Redirect (Model model) { model.addAttribute("id" ,123 ); return "redirect:/redirect.jsp" ; }
forward 方法
相当于 request.getRequestDispatcher().forward(request,response)
,浏览器地址不发生变化,同时继承原来的 request 和 response,model 也可以继承
1 2 3 4 5 @RequestMapping ("forward" )public String Forward (Model model) { model.addAttribute("id" ,123 ); return "forward:/redirect.jsp" ; }
接收与返回 JSON 数据
接收JSON
首先导入相应的包
pom.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <dependency > <groupId > com.fasterxml.jackson.core</groupId > <artifactId > jackson-core</artifactId > <version > 2.9.8</version > </dependency > <dependency > <groupId > com.fasterxml.jackson.core</groupId > <artifactId > jackson-databind</artifactId > <version > 2.9.8</version > </dependency > <dependency > <groupId > com.fasterxml.jackson.core</groupId > <artifactId > jackson-annotations</artifactId > <version > 2.9.0</version > </dependency >
还是刚才的 User:
User.java 1 2 3 4 5 6 7 8 9 public class User { private int id; private String username; private String password; private int level; private String avatar; }
前台用 Ajax 提交 Json 数据到后台:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <a href="javascript:void(0)" id="senddata">点我发送数据</a> <script type="application/javascript" src="js/jquery-3.3.1.min.js"></script> <script type="application/javascript" > $(function () { $("#senddata" ).click(function(){ $.ajax({ type: 'post' , url: '${pageContext.request.contextPath}/requestbody.do' , contentType:'application/json;charset=utf-8' , data: JSON.stringify({ id: "1" , username: "crazykid" , password: "123456" , level: "1" , avatar: "default.jpg" }), success: function(data){ alert("发送成功啦" ); } }) }) }) </script>
控制器用 @RequestBody
注解将 Json 数据转换为对象:
1 2 3 4 5 6 7 8 @Controller public class RequestBodyTest { @RequestMapping ("/requestbody" ) public String RequestBody (@RequestBody User user) { System.out.println(user); return "Hello.html" ; } }
控制台打印内容:
User{id=1, username=’crazykid’, password=’123456’, level=1, avatar=’default.jpg’}
返回JSON
@ResponseBody
注解可以将对象信息转为 Json 数据输出给浏览器。
1 2 3 4 5 6 7 8 9 @Controller public class ResponseBodyTest { @RequestMapping ("responsebody" ) @ResponseBody public User ResponseBody () { User user = new User(1 ,"aaa" ,"123" ,0 ,null ); return user; } }
直接用浏览器访问 http://localhost:8080/SpringMVC/responsebody.do 已经可以看到 json 信息了:
1 {"id" :1 ,"username" :"aaa" ,"password" :"123" ,"level" :0 ,"avatar" :null }
然后尝试在前台利用 ajax 获取 json 信息并显示在页面上:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <script type="application/javascript" src="js/jquery-3.3.1.min.js"></script> id:<span id="id"></span><br /> username: <span id="username"></span><br /> password: <span id="password"></span><br /> level: <span id="level"></span><br /> avatar: <span id="avatar"></span><br /> <a href="javascript:void(0)" id="getdata">点我获取数据</a> <script type="application/javascript" > $(function () { $("#getdata" ).click(function(){ $.getJSON("${pageContext.request.contextPath}/responsebody.do" , function(data) { $.each( data, function( key, val ) { $("#" +key).text(val); }); }); }) }) </script>
运行结果:
id:1 username: aaa password: 123 level: 0 avatar:
也可以使用注解 @RestController
, 它是 @ResponseBody
+ @Controller
的结合,如下:
1 2 3 4 5 6 7 8 @RestController public class RestControllerTest { @RequestMapping (value="/restcontroller" ) public User getUserName () { User user = new User(1 , "crazykid" , "123456" , 0 , null ); return user; } }
一样也是可以把对象转换成 json 数据输出的。