SpringMVC是Spring框架内置的MVC的实现.SpringMVC就是一个Spring内置的MVC框架.
MVC框架,它解决WEB开发中常见的问题(参数接收、文件上传、表单验证、国际化、等等),而且使用简单,与Spring无缝集成。 支持 RESTful风格的 URL 请求 。
采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性。
MVC模式:(Model-View-Controller):为了解决页面代码和后台代码的分离.
在没有使用SpringMVC之前我们都是使用的Servlet在做Web开发。但是使用Servlet开发在接受请求数据参数,数据共享,页面跳转等操作相对比较复杂。
SpringMVC底层就是的Servlet,SpringMVC就是对Servlet进行更深层次的封装
MVC模式最早开始是在CS 架构上面 20世纪70+年代
下面为原始的mvc模式.
目前web应用中,99%的项目都会使用mvc模式开发.
WEB开发从20世纪90+年代开始,也是使用MVC模式。在最原始的MVC上有一些改进
优秀的框架改变了这种模式,将model更广泛的使用,这样会比原始的mvc好多了.
像现在一些优秀的mvc的框架,如Struts2,springMVC
在客户端提交也使用了模型来请求参数
spring MVC 也实现的相关的功能
创建动态Web项目 |
public class HelloController implements public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { new ModelAndView(); return mv; } |
Servlet中的资源名称,以便浏览器访问,必须以斜杠/开头 "/hello" class="cn.zj.springmvc.HelloController"/> |
<!-- 配置前端控制器 :所有的请求都会经过此控制器,让后通过此控制器分发到各个控制器(总控) Servlet,SpringMVC底层就是使用Servlet编写的 |
注解 | 说明 |
@Component | 通用组件注解(一般配置其他非三层相关的类) |
@Controller | 表现层( |
@Service | 业务逻辑层(服务Service) |
@Resposotory | 数据持久层(DAO) |
<context:component-scan base-package="cn.zj.springmvc"/>
<mvc:annotation-driven/>
@Controller public class public ModelAndView mehtod1() { new ModelAndView(); return mv; } |
SpringMVC流程: 01、用户发送出请求到前端控制器DispatcherServlet。 02、DispatcherServlet收到请求调用HandlerMapping(处理器映射器)。 03、HandlerMapping找到具体的处理器(可查找xml配置或注解配置),生成处理器对象及处理器拦截器(如果有),再一起返回给DispatcherServlet。 04、DispatcherServlet调用HandlerAdapter(处理器适配器)。 05、HandlerAdapter经过适配调用具体的处理器(Handler/Controller)。 06、Controller执行完成返回ModelAndView对象。 07、HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet。 08、DispatcherServlet将ModelAndView传给ViewReslover(视图解析器)。 09、ViewReslover解析后返回具体View(视图)。 10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。 11、DispatcherServlet响应用户。 |
涉及组件分析: 1、前端控制器DispatcherServlet(不需要程序员开发),由框架提供,在web.xml中配置。 作用:接收请求,响应结果,相当于转发器,中央处理器。 2、处理器映射器HandlerMapping(不需要程序员开发),由框架提供。 作用:根据请求的url查找Handler(处理器/Controller),可以通过XML和注解方式来映射。 3、处理器适配器HandlerAdapter(不需要程序员开发),由框架提供。 作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler。 4、处理器Handler(也称之为Controller,需要工程师开发) 注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler。 作用:接受用户请求信息,调用业务方法处理请求,也称之为后端控制器。 5、视图解析器ViewResolver(不需要程序员开发),由框架提供 作用:进行视图解析,把逻辑视图名解析成真正的物理视图。 SpringMVC框架支持多种View视图技术,包括:jstlView、freemarkerView、pdfView等。 6、视图View(需要工程师开发) 作用:把数据展现给用户的页面 View是一个接口,实现类支持不同的View技术(jsp、freemarker、pdf等) |
具体组件的配置相关,请查阅 spring-webmvc-4.3.2.RELEASE.jar 包 下面 /org/springframework/web/servlet/DispatcherServlet.properties 的相关配置 |
HanderMapping 请求映射处理器 |
HandlerAdapter 处理器适配 |
HandlerAdapter 处理器适配: |
ViewResolver 视图解析器 |
我们这样的配置有这样一个问题 |
原因: Tomcat中处理静态资源访问的servlet(default)的映射路径为/. |
<servlet> </servlet>
|
解决方案:需要在SpringMVC的配置文件中添加对静态资源的访问 ----------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------- |
<servlet-mapping> </servlet-mapping> |
@RequestMapping注解主要是设置SpringMVC请求的映射路径
所谓的映射路径,就是匹配请求路径和执行方法关系的路径.
请求路径:http://localhost:8080/springmvc/method1.do
映射路径:@RequestMapping(value="/method1")
@RequestMapping 用于贴在控制器的类上或者方法上面
如果是贴在控制器的类上面,那么在访问这个类的方法之前必须先加上类上的对应的名称
类似于 项目下面的 模块名称
如果贴在方法上面,就是访问此方法的资源名称
@Controller public class RequestController { public void method1() { } |
http://localhost:8080/springmvc/request/method1.do
SpringMVC支持对请求的限制.如果不满足限制的条件,就不让访问执行方法.
这样做,大大提高了执行方法的安全性.
主要的限制有两种:(method)方法限制,参数限制
就是设置请求的method类型.如果发送过来的请求与方法设置的method不一样,就不能访问执行方法.
请求method : GET , POST
"${pageContext.request.contextPath }/login.do" method="get"> "submit" value="登录"> |
@return POST) public String login(){ out.println("-登录-"); return "/login.jsp"; |
前台发送的是GET请求,而方法限制是POST请求,所以请求无法执行方法
方法限制可以配置多个参数
public String login(){ out.println("-登录-"); return "/login.jsp"; |
1.就是请求里面必须包括哪些参数,或不包括哪些哪些.
2.参数包括哪些值,不包括哪些值
限制参数格式:
1.参数必须包括:params={"username","password"}
2.参数不能包括:params={"!userid"}
3参数值必须是指定的值:params={"username=zhangsan"})
4.参数值必须不是指定的值:params={"userid!=123"})
请求:没有后台方法指定的参数
<h4>登录页面</h4> <form action="${pageContext.request.contextPath}/request/method1.do" method="post"> "username"><br> "password" name="pwd"><br> "submit">登录</button> </form> |
后台代码
@return public String login2(){ out.println("-登录-"); return "/login.jsp"; |
如果前台请求没有指定后台要求的参数,会报错.
SpringMVC的方法默认可以注入 JavaWeb开发常用的数据共享对象
HttpServletRequest
HttpServletResponse
HttpSession
获取这些共享对象以后,就可以向之前的Servlet一样,做任何数据共享以及页面跳转操作
/* HttpServletRequest HttpServletResponse @RequestMapping(value = "/method0") public void method0(HttpServletRequest req, TODO } |
SpringMVC里面,所谓的数据绑定就是将请求带过来的表单数据绑定到执行方法的参数变量.
实际开发中,SpringMVC作为表现层框架,肯定会接受前台页面传递过来的参数,SpringMVC提供了丰富的接受参数的方法
SpringMVC可以注入HttpServletRequest对象,直接使用getParameter参数接受
<fieldset> "${pageContext.request.contextPath}/request/method1.do" method="get"> "username"><br> "age"><br> "submit">提交</button> </fieldset> |
@RequestMapping(value="/method1",method=RequestMethod.POST) //资源名称 public void method1(HttpServletRequest req,HttpServletResponse resp,HttpSession session) { out.println(username); out.println(age); } |
在请求方法形参上,声明和表单字段名相同的参数名(可以自动同名匹配,然后进行封装)
<fieldset> "${pageContext.request.contextPath}/request/method2.do" method="post"> "username"><br> "age"><br> "submit">提交</button> </fieldset> |
//方法形参与前台参数同名 @RequestMapping(value="/method2",method=RequestMethod.POST) public ModelAndView method2(String username,String age) { out.println(username); out.println(age); return null; } |
<fieldset> "${pageContext.request.contextPath}/request/method3.do" method="post"> "name"><br> "age"><br> "submit">提交</button> </fieldset> |
// 方法形参与前台参数不同同名 // 解决方案使用 : @RequestParam("前台表单对应的名") @RequestMapping(value = "/method3", method = RequestMethod.POST) public ModelAndView method3(@RequestParam("name") String username, String age) { out.println(username); out.println(age); return null; } |
<fieldset> "${pageContext.request.contextPath}/request/method4.do" method="post"> "name"><br> "age"><br> "checkbox" name="hobbys" value="java">java "checkbox" name="hobbys" value="html">html<br> "submit">提交</button> </fieldset> |
// 接受数组 POST) public ModelAndView method4(String[] hobbys) { out.println(Arrays.toString(hobbys)); return null; |
后台并不能直接接受集合参数,需要将集合设置到对应的JavaBean中,通过JavaBean接受集合参数 |
Pojo对象 |
public class User { private String username; private String password; private String email; private String phone; private String[] hobby; } |
<fieldset> pojo对象对应的属性名相同</legend> "${pageContext.request.contextPath}/request/method5.do" method="get"> "username"><br> "password" name="password"><br> "email"><br> "phone"><br> "checkbox" name="hobby" value="java">java "checkbox" name="hobby" value="C">C "checkbox" name="hobby" value="C++">C++<br/> "submit">提交</button> </fieldset> |
// 对象传参->对象中有集合 POST) public ModelAndView method4(User user) { out.println(user); return null; |
<fieldset> "${pageContext.request.contextPath}/request/method6.do" method="post"> "username"><br> "password"><br> "email"><br> "phone"><br> </fieldset> |
// 接受参数封装成Map集合 POST) public ModelAndView method6(@RequestParam Map<String,Object> map) { out.println("map:"+map); return null; |
REST(英文:Representational State Transfer,简称REST)描述了一个架构样式的网络系统,比如 web 应用程序。它首次出现在 2000 年 Roy Fielding 的博士论文中,他是 HTTP 规范的主要编写者之一。在目前主流的三种Web服务交互方案中,REST相比于SOAP(Simple Object Access protocol,简单对象访问协议)以及XML-RPC更加简单明了,REST都倾向于用更加简单轻量的方法设计和实现。值得注意的是REST并没有一个明确的标准,而更像是一种设计的风格。
RESTful一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
例如:根据商品id查询对应的商品信息(京东网站)
如果按照我们web开发应该是将商品id通过get方法跟在地址后面
普通方式 https://item.jd.com?product_id=100000287117 京东不支持
但是京东不是使用的此种方式,使用的 RESTFUL风格
RESTful风格 : https://item.jd.com/100000287117.html
// RESTful风格 @RequestMapping(value = "/method7/{product_id}") public ModelAndView method7(@PathVariable("product_id") Integer product_id) { out.println(product_id);//1231323123 return null; } |
- 可以让页面伪静态
页面访问感觉像在访问静态html页面,实际上访问时动态页面(伪静态)
2,方便搜索引擎的SEO优化
SpringMVC默认接受的参数是ISO-8859-1编码参数,单字节,不支持中文,Spring提供了一个过滤器可以让开发者自定义请求参数的字符编码
注意:此种方式只对post提交方式有效
如果提交中文参数的提价是get方式
配置 tomcat/conf/server.xml 添加 URIEncoding="UTF-8"
URIEncoding="UTF-8" "20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/> |
建议:以后表单一般使用post,get方式请求尽量不要使用中文作为参数
//返回void类型和共享数据 : 需要共享数据,页面跳转 public void method1(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException { jsp页面要显示数据,就必须使用请求转发 |
/* @RequestMapping("/method2") public ModelAndView method2() { new ModelAndView(); return mv; } |
<!-- 配置SpringMVC的视图解析器: 配置前缀和后缀 --> "org.springframework.web.servlet.view.InternalResourceViewResolver"> "prefix" value="/WEB-INF/response/"/> "suffix" value=".jsp"/> |
Controller方法返回字符串表示逻辑视图名,通过视图解析器解析为物理视图地址。
此时默认的物理视图地址为:视图前缀+返回值+视图后缀
public ModelAndView method2() { new ModelAndView(); return mv; |
注意: 配置完视图解析器以后,必须保证,前缀目录下面必须有对应逻辑视图名称所在的 页面 ,否则可能会报404错误
/* @RequestMapping("/method3") public String method3(Model m) { return "model"; //返回逻辑视图名称 } |
public static final String REDIRECT_URL_PREFIX = "redirect:";
public static final String FORWARD_URL_PREFIX = "forward:";
// 自定义请求转发页面跳转的地址 : forward: 跳转的地址 @RequestMapping("/method4") public String method4(Model m) { return "forward:/WEB-INF/views/index.jsp"; } // 自定义重定向页面跳转的地址 redirect: 跳转的地址 @RequestMapping("/method5") public String method5() { return "redirect:http://www.jd.com"; } |
方法不返回ModelAndView也不返回String类型对应的逻辑视图名称直接返回一个Pojo对象
如果直接返回Pojo对象,项目又配置了视图解析器规则
如果方法中没有返回ModelAndView对象,此时SpringMVC不知道视图在哪里.
此时需要配置视图解析器org.springframework.web.servlet.view.InternalResourceViewResolver.
物理视图路径为:前缀+请求路径(上下文路径+资源名称)+后缀
必须保证视图解析器路径下面必须有 请求路径对应的页面
------------------------------------------------------------------
@ModelAttribute作用如下:
1、设置请求参数绑定到Model对象中并传到视图页面的key名.
2、将方法返回值或请求参数绑定到Model对象中并传到视图页面
@ModelAttribute("userKey")//跳转页面使用el表达式获取的对应的属性名称 public User method6() { new User(); return user; |
在web开发中,前台页面经常会发送ajax请求从后台请求数据,ajax请求给前台的数据一般都是json 数据。
SpringMVC支持自动将对象转换JSON格式的数据响应给客户端
SpringMVC默认使用的是 jackson 作为对象转json的工具
Fast-json Alibaba
Gson google
Json-lib Apache
导入jackson的jar包
案例代码
@Controller public class JsonController { public User getUserJson() { new User(); return user; public List<User> getUserJsonList() { new User(); new ArrayList<>(); return list; } |
10. 小结
1,SpringMVC介绍
2,开发步骤
DispatcherServlet
<mvc:annotation-driven>
3,SpringMVC的请求
4,SpringMVC的相应