先讲一些自己的理解和概念性的东西,可以跳过直接看第3部分
1. SpringMVC的作用 SpringMVC实际上就是代替了原来Servlet中的作用,为什么使用SpringMVC,其实我们内心也很清楚,原来写Servlet的时候要么是继承了Servlet接口复写5个生命周期方法(init service … destory),要么继承HttpServlet接口复写doGet和doPost方法,非常繁琐。或者高级一点的进行servlet抽取,通过方法名代表访问路径,其实这就相当于springmvc的简易模型。
而SpringMVC就是完成了*“一个普通类也可以处理http请求” * 这么一个功能。
作用和servlet一样,接收前端请求参数,调用service层方法,返回json数据
1.1 MVC模型
MVC全名是Model View Controller 模型视图控制器,每个部分各司其职。
Model:数据模型,JavaBean的类,用来进行数据封装。
View:指JSP、HTML用来展示数据给用户
Controller:用来接收用户的请求,整个流程的控制器。用来进行数据校验等。
1.2 SpringMVC中的一些组件
前端控制器(DispatcherServlet)
处理器映射器(HandlerMapping)
处理器(Handler)
处理器适配器(HandlAdapter)
视图解析器(View Resolver)
视图(View)
流程如下
2. web项目的环境搭建 既然是web应用,当然要使用Maven骨架创建一个webapp项目,这样结构比较标准!注意不要选错了
这里添加archetypeCatalog参数的值为internal可以快一点
后面就一路next了
注意 ,由于使用骨架创建的项目没有java和resources目录,而我们熟悉的项目结构是
└─src
└─main
├─java
├─resources
└─webapp
└─WEB-INF
所以我们需要手动创建java和resources目录并把他们标记成source root和resources root,否则的话没有办法创建java类和配置文件,具体做法如下
配置好tomcat就可以了,这里就不介绍了
3. SpringMVC使用 3.1 pom坐标 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 <properties > <project.build.sourceEncoding > UTF-8</project.build.sourceEncoding > <maven.compiler.source > 1.8</maven.compiler.source > <maven.compiler.target > 1.8</maven.compiler.target > <spring.version > 5.2.3.RELEASE</spring.version > </properties > <dependencies > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-context</artifactId > <version > ${spring.version}</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-web</artifactId > <version > ${spring.version}</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-webmvc</artifactId > <version > ${spring.version}</version > </dependency > <dependency > <groupId > javax.servlet</groupId > <artifactId > servlet-api</artifactId > <version > 2.5</version > <scope > provided</scope > </dependency > <dependency > <groupId > javax.servlet.jsp</groupId > <artifactId > jsp-api</artifactId > <version > 2.0</version > <scope > provided</scope > </dependency > </dependencies >
3.2 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 <web-app > <display-name > Archetype Created Web Application</display-name > <servlet > <servlet-name > dispatcherServlet</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 > <load-on-startup > 1</load-on-startup > </servlet > <servlet-mapping > <servlet-name > dispatcherServlet</servlet-name > <url-pattern > /</url-pattern > </servlet-mapping > <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 > </filter > <filter-mapping > <filter-name > characterEncodingFilter</filter-name > <url-pattern > /*</url-pattern > </filter-mapping > </web-app >
3.3 resources文件夹下新建springmvc.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 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:mvc ="http://www.springframework.org/schema/mvc" xmlns:context ="http://www.springframework.org/schema/context" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation =" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" > <context:component-scan base-package ="com.wjw" > </context:component-scan > <bean id ="internalResourceViewResolver" class ="org.springframework.web.servlet.view.InternalResourceViewResolver" > <property name ="prefix" value ="/WEB-INF/pages/" > </property > <property name ="suffix" value =".jsp" > </property > </bean > <mvc:annotation-driven /> </beans >
其中internalResourceViewResolver中配置的路径就是Controller类中return自动跳转的对应页面
3.4 普通的类代替servlet java文件夹中创建一个名为controller的包和一个HelloController类(也就是我们俗称的controller层),如果类上方也有@RequestMapping(“/user”)标签,则表示多级目录,那么前端页面需要访问user/hello
能自动对应上前端页面的名称是因为springmvc.xml中视图解析器中写明了路径
3.5 随便写一个html/jsp页面提交请求
这时候我们就可以启动tomcat访问index.jsp了,如无意外你就可以看到控制台打印了aaa,达到跟servlet一样的效果了
4. 静态资源的访问方法 html/css/js/img等属于静态资源,要访问他们,必须设置静态资源不拦截。以下给出两种方法。
4.1 设置servlet-mapping 在web.xml对应位置(servlet-mapping的位置你懂的吧)中添加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <servlet-mapping > <servlet-name > default</servlet-name > <url-pattern > *.css</url-pattern > </servlet-mapping > <servlet-mapping > <servlet-name > default</servlet-name > <url-pattern > *.js</url-pattern > </servlet-mapping > <servlet-mapping > <servlet-name > default</servlet-name > <url-pattern > *.png</url-pattern > </servlet-mapping > <servlet-mapping > <servlet-name > default</servlet-name > <url-pattern > *.jpg</url-pattern > </servlet-mapping > <servlet-mapping > <servlet-name > default</servlet-name > <url-pattern > *.gif</url-pattern > </servlet-mapping > <servlet-mapping > <servlet-name > default</servlet-name > <url-pattern > *.html</url-pattern > </servlet-mapping >
同理,其他格式的自定义
4.2 mvc提供的方式 springmvc提供了一种标签可以设置静态资源不拦截
1 2 3 4 <mvc:resources location ="/css/" mapping ="/css/**" /> <mvc:resources location ="/images/" mapping ="/images/**" /> <mvc:resources location ="/js/" mapping ="/js/**" />
根目录是指webapp目录 ,html同理,加上就好
5. 请求参数绑定变量和实体类 前端的请求数据总会带上参数,我们常常需要将参数封装,springmvc是通过变量名字来自动对应的,省去了原来用request.getParameter()的麻烦。
那么前端提交的name就必须像下面那样写
Controller层
6. 获取原生Servlet的API(request和response) 一般很少用 ,直接给controller的方法添加两个形参:HttpServletRequest request和HttpServletRequest response response就可以使用了
7. 常见的注解 @RequestMapping 上面已经用过了,它还有这么一些属性
@RequestParams(value=“name”) 解决url参数可以和接收的参数名字不匹配的问题
比如前端参数是name
后台是username,对应不上,因此我们可以用这个注解指定url接收名
@RequestBody 同上,不过是对post请求(前端通过表单提交且method=”post”,或者ajax异步时使用post)
后台方法形参还是一个String body,这个body包括:username=哈哈&age=13
@PathVariable(value=”id”) 这个注解为了restful风格而生(一种倡导/root/user/10而不是/root/user?id=10的风格)
Controller层,属性value或者name都一样
前端传值的时候的路径
用法和上面的类似,都是加在字符串形参前面,用处是获得某个请求头的值,如@RequestHeader(value=”Accept”)
@CookieValue 使用方法同上,用于获取Cookie值
@ModelAttribute 写在方法上,也可以写在参数上。 写在方法上时,作用是优先于原来前端请求的对应方法,前端请求的参数会进入该方法的形参,该方法返回值会进入原先请求的方法的形参
有种拦截的味道
如果没有返回值,那么可以在该方法形参添加一个map,方法内用map集合存住返回值,这时可以将@ModelArrtibute写在原先请求的方法的形参参数上,属性就是map的key
@SessionAttributes 同样的,存入session域中
8. 返回给前端的信息 前面说完了接收请求,现在来说一下返回数据,Controller层的方法可以有多种返回值应对不用的响应需求
8.1 页面跳转型 8.1.1 返回值为String类型 return的值为”success”,会经过视图解析器,找到success.jsp
还有一种不太常用的方法,使用request和response 转发和重定向
return "forward:/WEB-INF/pages/success.jsp";
或者是
return "redirect:/index.jsp";
8.1.2 返回值为void类型 则会默认跳转方法上面的RequestMapping的路径.jsp,如果不存在,则会报404错误。或者可以使用request和response 转发和重定向获取servlet的api,如此则自己写要跳转的页面,注意:因为这样不再经过视图解析器,注意路径不能再写success,而是/WEB-INF/pages/success.jsp,如果是response还要注意加上response.getContextPath() 返回值为
8.1.3 返回值为ModelAndView类型 这是一个专门用来处理页面跳转返回的类,其实就是String返回类型+Model类的合体,通过addObject方法存入request域和session域中,通过setViewName方法可以通过视图解析器指定跳转页面
8.2 json型 正常点,这种一般都是对应异步请求
要先放开静态资源(js,图片,css),否则会被拦截,做法是在springmvc.xml中添加
1 2 3 4 <mvc:resources location ="/css/" mapping ="/css/**" /> <mvc:resources location ="/images/" mapping ="/images/**" /> <mvc:resources location ="/js/" mapping ="/js/**" />
@ResponseBody 作用是将返回值以json的格式发送给前端,写在方法返回值类型上
前端ajax请求代码
1 2 3 4 5 6 7 8 9 10 11 12 13 $.ajax({ url: "user/testAjax" , contentType: "application/json;charset=utf-8" , data:'{"username": "hehe", ' + '"password": "123", ' + '"age": "20"}' , dataType: "json" , type: "post" , success:function (data ) { alert(data); alert(data.age); } });
json字符串和JavaBean对象互相转换的过程中,需要以下jackson坐标
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <dependency > <groupId > com.fasterxml.jackson.core</groupId > <artifactId > jackson-databind</artifactId > <version > 2.10.3</version > </dependency > <dependency > <groupId > com.fasterxml.jackson.core</groupId > <artifactId > jackson-core</artifactId > <version > 2.10.3</version > </dependency > <dependency > <groupId > com.fasterxml.jackson.core</groupId > <artifactId > jackson-annotations</artifactId > <version > 2.10.3</version > </dependency >
关于json对象和json字符串和普通字符串传输时造成null值的一些坑,可以看这篇文章