我们知道三层架构的思想,并且如果你知道ssh的话,就会更加透彻地理解这个思想,struts2在web层,spring在中间控制,hibernate在dao层与数据库打交道,而前面刚写的mybatis跟hibernate一样,与数据库打交道在dao层的另一个框架,而今天所要讲解的springmvc是在web层的另一个框架。
springmvc全名是spring web mvc,springmvc是spring的一个模块,并且看名字即可知道,springmvc是一个基于mvc设计模式的前端web框架。
mvc:m(model模型)、v(view视图)、c(control控制)
mvc的运用概念图
通过这个来快速了解springmvc大概的开发流程,其实通过上面的mvc分析图,差不多就知道了如何开发了。重点就是三步。
思路已经有了,那么就开始编写吧。
问题描述:使用springmvc来完成前端请求的处理
前面三步只是通过mvc图的分析出最关键的三步,其中实现的时候步骤应该更多,比如spring的配置文件,但关键的重点还是那三个。
1
2
3 springmvc
4 org.springframework.web.servlet.DispatcherServlet
5
6
7 contextConfigLocation
8 classpath:springmvc.xml
9
10
11
12 springmvc
13
18 *.do
19
在config目录下,创建springmvc.xml文件
注意:2.7和2.8一起讲解,因为开发handler类讲解三种方式,所以配置也连在一起讲解,以免分开来,看不清楚
Springmvc开发handler有多种方式,我们只讲解三种:实现HttpRequestHandler接口、实现Controller接口、使用注解开发(掌握)
实现HttpRequestHandler接口
1 package com.wuhao.springmvc.controller;
2
3 import java.io.IOException;
4 import java.util.ArrayList;
5 import java.util.List;
6
7 import javax.servlet.ServletException;
8 import javax.servlet.http.HttpServletRequest;
9 import javax.servlet.http.HttpServletResponse;
10
11 import org.springframework.web.HttpRequestHandler;
12
13 import com.wuhao.springmvc.domain.Items;
14
15 public class ItemController implements HttpRequestHandler {
16
17 @Override
18 public void handleRequest(HttpServletRequest request, HttpServletResponse response)
19 throws ServletException, IOException {
20 //获取商品列表(用静态数据模拟)
21 List itemsList = new ArrayList();
22
23 Items items_1 = new Items();
24 items_1.setName("联想笔记本 HttpRequestHandler");
25 items_1.setPrice(6000f);
26 items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
27
28 Items items_2 = new Items();
29 items_2.setName("苹果手机");
30 items_2.setPrice(5000f);
31 items_2.setDetail("iphone6苹果手机!");
32
33 itemsList.add(items_1);
34 itemsList.add(items_2);
35
36 //把商品数据放到request域中
37 request.setAttribute("itemsList", itemsList);
38 //指定视图
39 request.getRequestDispatcher("/WEB-INF/jsp/items/itemsList.jsp").forward(request, response);
40
41 }
42
43 }
springmvc.xml中配置该处理器
通过localhost:8080/项目名/queryItems01.do 就能够访问到DispatcherSerlvet,该servlet就会帮我们找到你对应的处理器(依据就是通过下面的这行配置,queryItems01对应了一个处理器的class,也就能够找到)
1
2
实现Controller接口
1 package com.wuhao.springmvc.controller;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import javax.servlet.http.HttpServletRequest;
7 import javax.servlet.http.HttpServletResponse;
8
9 import org.springframework.web.servlet.ModelAndView;
10 import org.springframework.web.servlet.mvc.Controller;
11
12 import com.wuhao.springmvc.domain.Items;
13
14 public class ItemController02 implements Controller {
15
16 @Override
17 public ModelAndView handleRequest(HttpServletRequest request,
18 HttpServletResponse response) throws Exception {
19 //获取商品列表(用静态数据模拟)
20 List itemsList = new ArrayList();
21
22 Items items_1 = new Items();
23 items_1.setName("联想笔记本 Controller");
24 items_1.setPrice(6000f);
25 items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
26
27 Items items_2 = new Items();
28 items_2.setName("苹果手机");
29 items_2.setPrice(5000f);
30 items_2.setDetail("iphone6苹果手机!");
31
32 itemsList.add(items_1);
33 itemsList.add(items_2);
34
35 //实现Controller接口的话,就必须使用MoldeAndView对象来将数据装载到对应的jsp视图上,然后返回该对象即可
36 //所以需要两步,将数据给该对象,将指定的视图在交给该对象,最后返回该对象即可。
37 ModelAndView mv = new ModelAndView();
38 //类似于request.setAttribute("itemsList", itemsList);
39 mv.addObject("itemsList", itemsList);
40
41 //指定视图
42 mv.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
43
44 return mv;
45
46 }
47
48 }
配置该handler类
使用注解开发
注解的配置,就是配置一个扫描器,扫描使用了注解的地方
在WEB-INF/jsp/items/下创建jsp:itemsList.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
查询商品列表
测试上面三种采用不同的方式编写的处理类。能够成功访问即成功
前面了解了springmvc的mvc设计模式的运用并且还编写了一个简单的实例,关键点就几个,配置DispatcherServlet,编写处理类以及配置,jsp,就mvc的三个关键点,但是这也是粗略的使用一下springmvc,并不知道其中运行的原理,比如
看图即可
这里会有人会有疑惑,为什么需要处理器适配器,我们都获得了处理类了,直接调用不就行了吗?
不行,因为我们只知道处理类在哪里,并不知道执行处理类中的哪个方法,其实也就是不知道处理类是通过哪种方式创建出来的,实现HttpRequestHandler?还是注解方式,或者是 其他方式,我们不知道,所以需要HandlerAdapter来帮我们确认调用哪个方法。
通过上面的图和分析过程,就能够完美解答上面的三个问题了。理解了图,那么springmvc就会用了。很简单吧,跟struts2差不多,记住原理图即可。
通过图可以看到
就这么点东西,真正需要写的就两个(处理器+视图)和一个配置(前端控制器),就是mvc中的三个重点,在第二小节中就是这样编写的,第三小结就是解释其中的原理。
处理器映射器、处理器适配器、视图解析器这三个是默认配置的,在下面位置中可以查看
DispatchServlet.properties
BeanNameUrlHandlerMapping:映射器
BeanNameUrlHandlerMapping:映射器
在springmvc配置文件中,配置BeanNameUrlHandlerMapping
他的作用是找到在springmvc.xml中配置的url和处理器的bean
HttpRequestHandlerAdapter:适配执行实现了HttpRequestHandler接口的处理类的方法
在springmvc配置文件中,配置HttpRequestHandlerAdapter
它的作用就是适配实现了HttpRequestHandler接口的处理类,也就是找到该处理类对应的方法
如何适配,就是需要看源码了,可以百度一下讲解该适配器的源码。
SimpleControllerHandlerAdapter:适配执行实现了Controller接口的处理类的方法
在springmvc配置文件中,配置
SimpleControllerHandlerAdapter
总结:这就是非注解的组件的配置方式,很简单,注意
注意:
1、注解方式的映射器和适配器在3.1版本前后是不一样的,使用3.1之后的
2、注解方式的处理器映射器和处理器适配器必须配对使用,不能与非注解的处理器映射器和适配器混用(用了注解的就不能在配置非注解的,二选一)
配置方式有两种:
1、使用bean标签配置
2、使用mvc标签(推荐)
其中两个配置的意思是:prefix:前缀 suffix:后缀 。 配置之后在指定视图时,就不用写这前缀和后缀了,直接写关键代码即可。看下图
虽然指定视图只写 items/itemsList 但是会帮我们加上我们配置的前缀和后缀,也就是变为了
/WEB-INF/jsp/items/itemsList.jsp
org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver
等什么时候使用到了在学习把。
requestMapping有三种功能:映射请求url、窄化请求、限制请求方法
也就是写在方法上,上面我们已经用过了这种功能,这里详细讲解一下
@RequestMapping(value="/item,/user")或@RequestMapping("/item”) value是数组,可以将多个url映射到同一个方法上,用逗号隔开即可。如果value中只有一个属性,则可以省去value,就像这样:@RequestMapping(value="/item ")写成@RequestMapping("/item”)
在class上面加上requestmapping注解,可以对url进行分类管理,这样也实现了请求的窄化
加在class上
加在方法上
访问路径为:
http://localhost:8080/xxx/items/queryItems.do
限制访问该方法必须是get或者post方式,相当于对请求进行过滤。
限定GET方法,也就是只能允许get请求方式过来的请求访问
@RequestMapping(method = RequestMethod.GET)
如果post请求方式的过来访问,则报错 HTTP Status 405 - Request method 'POST' not supported
限定post方法。
@RequestMapping(method = RequestMethod.POST)
可以通过response指定响应结果,例如响应json数据如下
get、post都可以@RequestMapping(method={RequestMethod.GET,RequestMethod.POST})
同样有三种:ModelAndView对象、void、String
controller方法中定义ModelAndView对象并返回,对象中可添加model数据、指定view。 然后通过视图解析器对其进行解析。上面用的就是这个。不用再过多地解释了
如果返回值为void的时候,可以在controller方法形参上定义request和response,使用request或response指定响应结果(这里在形参上定义request和response,还没讲到。但是可以这样用,相当于controller方法上默认有这两个形参。加上去就可以使用)
使用request转向页面,如下
request.getRequestDispatcher("页面路径").forward(request, response)
通过response页面重定向
response.sendRedirect("url")
可以通过response指定响应结果,例如响应json数据如下
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json串");
使用一:返回逻辑视图
解释:形参中有Model对象,该对象也是默认形参,只要声明了,就可以拿过来用,该Model对象的作用就是添加属性到request作用域中的,就跟ModelAndView对象添加值到request作用域中一样,只是model对象不能够指定视图。正好其model就是modelAndView的一半,很好理解。 其次,因为没有采用modelAndView对象,所以不能够指定视图,但是可以直接返回视图地址即可,效果是跟使用modelAndView对象一样的。