创建Maven web项目,目录结构如下:
加入依赖:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<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>
</dependencies>
<build>
<plugins>
<!-- 编码和编译和JDK版本 -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
web.xml:
配置中央调度器、自定义springmvc配置文件的位置
<?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">
<!--
声明、注册spring MVC的核心对象:DispatcherServlet,在tomcat服务启动后,
创建DispatcherServlet对象的实例。
为什么要创建DispatcherServlet对象的实例呢?
因为在创建DispatcherServlet对象过程中,同时会创建SpringMVC容器对象,
读取SpringMVC的配置文件,把这个配置文件中的对象都创建好,当用户发起请求时就可以直接适用对象了
-->
<servlet>
<servlet-name>myweb</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--自定义springmvc配置文件的位置-->
<init-param>
<!--springmvc的配置文件的位置属性-->
<param-name>contextConfigLocation</param-name>
<!--指定自定义文件的位置: 类路径下,名字叫做springmvc.xml-->
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<!--在tomcat启动后,创建servlet对象,load-on-startup表示tomcat启动后创建对象的顺序,
它的值是整数,数值越小,tomcat创建对象的时间越早,大于等于0的整数-->
</servlet>
<!--使用框架的时候 , url-pattern可以使用两种值
1.使用扩展名方式,语法 *.xxxx ,xxxx是自定义的扩展名。 常用的方式 *,do,*,action,*.mvc等等
http://localhost;8080/myweb/some.do
http://localhost:8080/myweb/other.do
2.使用斜杠“/"
-->
<servlet-mapping>
<servlet-name>myweb</servlet-name>
<url-pattern>*.do</url-pattern>
<!--*.do:凡是.do结尾的请求都交给名字叫做myweb的中央调度器处理-->
</servlet-mapping>
</web-app>
<load-on-startup/>介绍:
在<servlet/>中添加<load-on-startup/>的作用是,标记是否在Web 服务器(这里是Tomcat)
启动时会创建这个 Servlet 实例,即是否在 Web 服务器启动时调用执行该 Servlet 的 init()方
法,而不是在真正访问时才创建。
它的值必须是一个整数:
- 当值大于等于0时,表示容器在启动时就加载并初始化这个 servlet,数值越小,该Servlet的优先级就越高,其被创建的也就越早:
- 当值小于0或者没有指定时,则表示该 Servlet 在真正被使用时才会去创建
- 当值相同时,容器会自己选择创建顺序。
tomcat启动,创建容器的过程:
通过load-on-start标签指定的1,创建DispatcherServlet对象,DispatcherServlet它的父类是继承Httpservlet的,它是一个serlvet,在被创建时,会执行 init()方法。
在init()方法中:
- //创建容器,读取配置文件
- WebApplicationContext ctx = new ClassPathXmlApplicationContext("springmvc.xml"):
- //把容器对象放入到servletcontext中
- getServletContext() .setAttribute(key, ctx) ;
springmvc的配置文件介绍:
springMVC配置文件实际上是有命名规则的,<servlet-name>和中央调度器的名字是一样的,中央调度器叫什么,它就叫什么,然后后面加一个-servlet ,并且我们要在 WEB-INF目录下放入这个文件才是正确的,但这种方式并不灵活,一般情况下,我们可以自定义
启动tomcat报错,读取这个文件 /WEB-INF/springmvc-servlet.xml ( /WEB-INF/myweb-servlet,xml),springmvc创建容器对象时,读取的配置文件默认是/WEB-INF/<servlet-name>-servlet.xml:
<init-param>
<!--springmvc的配置文件的位置属性-->
<param-name>contextConfigLocation</param-name>
<!--指定自定义文件的位置: 类路径下,即resources目录下,名字叫做springmvc.xml-->
<param-value>classpath:springmvc.xml</param-value>
</init-param>
组件扫描器:
在springmvc配置文件中,指定注解所在的包及其子包:
<?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.lifang.controller"/>
</beans>
创建控制器(处理器)类:
1) 在类的上面加入@Controller注解,创建处理器/控制器对象,并放入到springmvc容器中
2) 在类中的方法上面加入@RequestMapping注解,用来处理用户请求。
//1、value值一般省略:@Controller(value = "myController"),对象id默认为类名首字母小写myConttoller
//2、能处理请求的都是控制器(处理器): MyController能处理请求,叫做后端控制器(back controller )
@Controller(value = "myController")
public class MyController {
// /表示它是一个根地址
//意思是如果你的请求地址是other.do,由这个方法来处理该请求
@RequestMapping(value = {"/some.do","/second.do"}) // value = "/some.do"
public ModelAndView doSome(){
ModelAndView mv = new ModelAndView();
//添加数据,框架在请求的最后把数据放入到request作用域中:
//等同于: request.setAttribute("msg","欢迎使用Springmvc做web开发");
mv.addObject("msg","欢迎使用Springmvc做web开发");
mv.addObject("fun","执行的是doSome方法");
//指定视图,如果配置了视图解析器,则只需要指定视图的逻辑名称,否则指定视图的完整路径
//request.getRequestDispatcher("/WEB-INF/view/show.jsp")
//request.getRequestDispatcher()是请求转发,前后页面共享一个request; 这个是在服务端运行的,对浏览器来说是透明的。
//response.sendRedirect()是重新定向,前后页面不是一个request。而这个是在浏览器端运行的。
mv.setViewName("/WEB-INF/view/show.jsp");
return mv;
}
}
@RequestMapping注解介绍:
使用RequestMapping 修饰的方法叫做处理器方法或者控制器方法;使用@RequestMapping 修饰的方法可以处理请求的
@RequestMapping:请求映射,作用是把一个请求地址和一个方法绑定在一起,一个请求指定一个方法处理;
属性: 1.value 是一个String[ ],表示请求的uri地址,我们可以把多个请求交给同一个控制器方法处理,但是一个请求只能交给一个控制器方法处理,不能重复
位置 :1.在方法的上面,常用的。
2.在类的上面
ModelAndView介绍:
ModelAndView 是表示处理结果的,所以我们要把视图和数据往这里填充
Index.jsp发起请求
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>第一个springmvc项目</h2>
<p><a href="some.do">发起some.do请求</a></p>
</body>
</html>
show.jsp显示请求的处理结果
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<h3>show.jsp从request作用域中获取数据</h3>
<h3>msg数据:${msg}</h3>
<h3>fun数据:${fun}</h3>
</head>
<body>
</body>
</html>
show.jsp页面不能让用户直接访问:
如果show.jsp页面直接放在webapp根目录下的话,用户可以直接访问:
因为当前请求并没有经过myController处理,所以数据是没有的,导致数据不准确,我们应该控制用户访问首页,不能让用户直接访问这个show.jsp,那如何控制用户行为请问呢:
index.jsp是放在webapp根目录下,这里面的页面用户是有权访问的;show.jsp不能让用户访问:我们把show.jsp放在WEB-INF目录里面,WEB-INF目录下的所有内容对于用户来讲是不可访问的:
这样就保证了这个show.jsp页面不能随意访问,但是又能保证正常情况下我们是能够
转发到show.jsp下的: