本文最后编辑于 前,其中的内容可能需要更新。
一、springmvc 概述
1.1 springmvc定义
基于spring的一个框架,实际上就是spring的一个模块,专门是做web开发的,理解为servlet的升级。web开发底层是servlet,框架是在servlet基础上面加入一些功能,让开发更方便。
1.2 spring和springmvc对比
spring:spring是容器,ioc能够管理对象,
使用< bean>,@Component,@Repository,@Service,@Controller 标签
springmvc:能够创建对象,放入到容器中(springmvc容器),spring容器中放的是控制器对象
1.3 springmvc简要流程
我们要做的是 使用 @Controller 创建控制器对象 ,把对象放入到springmvc 容器中,把创建的对象作为控制器使用。这个控制器对象能够接收用户的请求,显示处理结果,就当作是一个servlet使用。
使用 @Controller 注解创建的是一个普通的对象 ,不是servlet,springmvc赋予了控制器对象一些额外的功能。
web开发底层是servlet,springmvc中有一个对象是servlet:DispatcherServlet(中央调度器)
DispatcherServlet:负责接收用户的所有请求,用户把请求给了DispatcherServlet,之后DispatcherServlet把请求转发给我们的Controller对象,最后Controller对象处理请求。
二、开发步骤
2.1、做一个小demo
index.jsp —> DispatcherServlet(中央调度器,类似servlet) —-> 转发,分配给Controller对象(@Controller 注解创建的对象)
开发流程:
- 发起some.do请求
- tomcat (web.xml 从url-pattern知道 *.do 的请求给DispatcherServlet)
- DispatcherServlet(根据spring.xml配置知道some.do,doSome()方法)
- DispatcherServlet把some.do转发给MyController.doSome()方法
- 框架执行doSome()把得到的ModelAndView进行处理,转发到show.jsp
简化流程:
some.do -> DispatcherServlet -> MyController
在pom.xml中引入servlet和springmvc依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency>
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.5.RELEASE</version> </dependency>
|
核心配置文件 web.xml
- (自定义配置文件的位置:在resources目录下创建配置文件,new->XML Configuration File->Spring Config,然后在web.xml下指定自定义配置文件的位置即可)
- 之前servlet-name报错是因为没有设置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 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
| <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">
<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>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping> <servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
|
上面已经指定了中央调度器的位置,那么我们现在就在指定的位置创建springmvc.xml
1 2 3 4 5 6 7 8 9
| <?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" 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">
<context:component-scan base-package="com.laj.controller"/> </beans>
|
声明了Controller后,我们就在com.laj.controller.MyController.java 创建控制类
- 设置映射请求,new ModelAndView(),根据K-V的形式存放数据
- 设置数据返回的视图,setViewName
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
| package com.laj.controller;
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView;
@Controller public class MyController {
@RequestMapping(value = "/some.do") public ModelAndView doSome(){ ModelAndView mv = new ModelAndView(); mv.addObject("msg1","Hello World!"); mv.addObject("msg2","Hello World!!");
mv.setViewName("/show.jsp"); return mv; } @RequestMapping(value = "anny.do") public ModelAndView anny(){ ModelAndView mv = new ModelAndView(); mv.addObject("value1","我是编程天才!"); mv.addObject("value2","是的!");
mv.setViewName("/show.jsp"); return mv; } }
|
上面设置了数据返回的视图后,我们开始创建视图
(由于我们一开始没有创建主页面,现在这里补上index.jsp)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <%-- Created by IntelliJ IDEA. User: 11877 Date: 2021/7/4 Time: 1:17 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <p>第一个MVC的项目</p> <p><a href="some.do">发起一个some.do请求</a></p> <p><a href="anny.do">发起一个anny.do请求</a></p> </body> </html>
|
在主页面中,有两个不同的请求页面, 根据不同的请求页面中,有两个不同的Controller类中的方法返回的值可以获取到。
接下来我们创建超链接里面的视图 数据通过 ${} 的格式进行书写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <%-- Created by IntelliJ IDEA. User: 11877 Date: 2021/7/4 Time: 1:50 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h3>show.jsp从request作用域获取数据</h3><br /> <h4>msg1数据:${msg1}</h4> <h4>msg2数据:${msg2}</h4> <h4>msg2数据:${value1}</h4> <h4>msg2数据:${value2}</h4>
</body> </html>
|
如此一个完整的SpringMVC 的demo就完成啦!
注意:文件的路径图
2.2、防止用户不在网页内请求下直接访问内部网站
解决办法:将视图文件(.jsp)放到WEB-INF下的文件夹下
导致:setViewName请求的网站需要改成**/WEB-INF/view/show.jsp**
如果有多个请求的网站页面,增加前缀的方式将很繁琐
解决办法:在springmvc.xml中声明视图解析器,使用bean注册前缀和后缀
1 2 3 4 5 6 7
| <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/"/>
<property name="suffix" value=".jsp"/> </bean>
|
让MyController中setViewName(“/WEB-INF/view/show.jsp”)—>MyController中setViewName(“show”)
三、注解式开发
3.1@RequestMapping
放在类上面@RequestMapping(“/user”),表示下面的请求都是基于/user/xxx.xx,便于模块化操作
放在方法上@RequestMapping(value=”/xxx.xx”,method = RequestMethod.GET) –>表示get请求方式
RequestMethod.GET、RequestMethod.POST……
如果method不写就不限制
注意:在Controller中设置GET或者POST,在index中也要对应,否则会报 错误405
3.2处理器方法的参数
处理器方法可以包含以下四类参数,这些参数会在系统调用时由系统自动赋值,即程序员可以在方法中直接使用。
HttpServletRequest request, 请求
HttpServletResponse response, 应答
HttpSession session 会话
请求中所携带的请求参数(即用户提交的数据)
1 2 3 4 5 6 7 8 9 10 11 12
| @Controller public class MyController { @RequestMapping(value = "/some.do") public ModelAndView doSome(HttpServletRequest request, HttpServletResponse response, HttpSession session){ ModelAndView mv = new ModelAndView(); mv.addObject("msg","欢迎使用springmvc做web开发" + request.getParameter("name")); mv.addObject("fun","执行的是doSome方法"); mv.setViewName("show"); return mv; }
|
3.3逐个参数接收
设置主页index.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <p>提交参数给Controller</p>
<form action="receive.do" method="post"> 姓名:<input type="text" name="name"><br /> 年龄:<input type="text" name="age"><br /> <input type="submit" value="提交参数"> </form> </body> </html>
|
<注意:1、action后面的域名前面不要加/
2、input后面的参数是对应的事type和name>
业务层:
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Controller public class MyController {
@RequestMapping(value = "/receive.do") public ModelAndView doSome(String name ,String age){ ModelAndView mv = new ModelAndView(); mv.addObject("myname",name); mv.addObject("myage",age); mv.setViewName("show"); return mv; }
}
|
视图层:
1 2 3 4 5 6 7 8 9 10 11
| <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h3>从request作用域获取数据</h3><br /> <h3>name数据:${myname}</h3><br/> <h3>age数据:${myage}</h3> </body> </html>
|
注意:在提交请求参数的时候,get请求方式中文没有乱码;post请求方式中文有乱码,需要使用过滤器处理乱码问题。
使用过滤器处理post中文乱码:characterEncodingFilter 在org. springframework: spring-web: 5.2.5. RELEASE依赖中
所以在web.xml文件中配置:三个参数:encoding、forceRequestEncoding、forceResponseEncoding,通过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 25
| <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>forceRequestEncoding</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>forceResponseEncoding</param-name>
<param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern> </filter-mapping>
|
总结: