Java教程

SpringMVC快速使用——基于XML配置和Servlet3.0

本文主要是介绍SpringMVC快速使用——基于XML配置和Servlet3.0,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

SpringMVC-快速使用

1、官方文档

2、编写pom文件引入jar包

这里使用5.3.8版本Spring框架。基于Servlet API,必须引入servlet-api依赖。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.black</groupId>
  <artifactId>spring-springmvc-xml</artifactId>
  <packaging> war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>spring-springmvc-xml Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <!-- 定义Spring版本 -->
  <properties>
      <spring.verson>5.3.8</spring.verson>
  </properties>
  <dependencies>
    <!-- 引入 Spring Framework jar包 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.verson}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.verson}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.verson}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${spring.verson}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>${spring.verson}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.verson}</version>
    </dependency>
    <!-- 引入 Spring MVC jar包 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.verson}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.verson}</version>
    </dependency>

    <!-- 引入 servlet-api (不希望打到war包中,有可能tomcat容器就已经带有这个包了)-->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
    </dependency>
    <!-- 日志 jar -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jcl</artifactId>
        <version>${spring.verson}</version>
    </dependency>
    
    <!-- 日志:slf4j + logback  -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.31</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
        <version>1.2.3</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
        <scope>compile</scope>
    </dependency>
  </dependencies>
  <build>
    <finalName>spring-springmvc-xml</finalName>
  </build>
</project>

3、编写 web.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">

  <!-- 指定 Root WebApplicationContext xml配置文件 -->
  <!-- 如果不配置 contextConfigLocation这个属性,那么,自动会去加载  WEB-INF/applicationContext.xml  如果没有则报异常-->
  <!-- 如果不需要 WebApplicationContext 继承关系则, contextConfigLocation 的 value 设置为 空 -->
  <!--  (一般上不用WebApplicationContext继承关系) -->
  <!-- context-param  更详实说明看 【11.1 web.xml context-param说明】-->
  <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value></param-value>
  </context-param>

  <!-- 1、定义上下文监听 -->
  <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <!-- 2、定义 dispatcherServlet-->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<!-- 如果不配置 contextConfigLocation 则默认加载 WEB-INF/${servlet-name}-servlet.xml-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-context.xml</param-value>
    </init-param>
    <!-- web应用一启动就初始化这个servlet -->
    <load-on-startup>1</load-on-startup>
  </servlet>
  
  <!-- 3、定义 dispatcherServlet-->
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <!-- 注意:dispatcherServlet必须是“/”, 不能是“/*”;   -->
    <!-- 如果是“/*”,那么当返回modelAndView是个jsp时,它会继续走这个servlet去找“/WEB-INF/.../*.jsp”对应的controller -->
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <display-name>spring-web-application</display-name>
  <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

4、编写 spring-context.xml

位置:/src/main/resource/spring-context.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	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">

  <!-- 定义 handlerMapping(根据url 查找 Controller) -->
  <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
  
  <!-- 定义视图解析器(根据视图名解析为对应的jsp)  -->
  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/"></property>
    <property name="suffix" value=".jsp"></property>    
  </bean>
  <!-- 定义controller  -->
  <bean id="/welcome" class="com.black.app.controller.WelcomeController" />
</beans>

5、编写日志配置

位置:/src/main/resource/logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" >
    <!--0. 日志格式 -->
    <property name="CONSOLE_LOG_PATTERN" 
         value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5p] [%-10.15t] %20.30logger{30}.%M[line:%L]: %m%n}"/> 
    <!-- 时间戳 -->
    <timestamp key="file_name_date" datePattern="yyyyMMdd"/>
    <!--1. 记录日志到文件-->
    <appender name="LogFile" class="ch.qos.logback.core.FileAppender">
        <!-- 日志文件名 -->
        <file>${file_name_date}/log-info-${file_name_date}.log</file>
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
  <!--1. 输出到控制台-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <root>
        <appender-ref ref="LogFile" />
        <appender-ref ref="CONSOLE" />
    </root>
</configuration>

6、编写 Controller

package com.black.app.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class WelcomeController implements Controller {
	private static Logger logger = LoggerFactory.getLogger(WelcomeController.class);
	
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		logger.info("WelcomeController#handleRequest 开始处理...");
		//获取请求参数-姓名
		String name = request.getParameter("name");
		//如果在windows乱码则进行转码
		name = new String(name.getBytes("ISO8859-1"),"UTF-8");
		logger.info("WelcomeController#handleRequest 请求参数:." + name);
		ModelAndView view = new ModelAndView();
		view.addObject("name", name);
		//返回 welcome.jsp
		view.setViewName("welcome");
		logger.info("WelcomeController#handleRequest 处理结束。");
		return view;
	}

}

7、编写 welcome.jsp

位置:/src/main/webapp/WEB-INF/welcome.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<body>
<h2>欢迎【<%= request.getAttribute("name")%>】同学,来到我的 spring-springmvc-xml web应用</h2>
</body>
</html>

8、打包

maven compile package

war包路径:spring-springmvc-xml\target\spring-springmvc-xml.war

9、部署

将spring-springmvc-xml.war部署 apache-tomcat 下。
(1)将 spring-springmvc-xml.war 拷贝到 apache-tomcat-7.0.91\webapps\

(2)编写 apache-tomcat-7.0.91\conf\server.xml

<!-- 设置8180端口 -->
<Connector port="8180" protocol="HTTP/1.1"  connectionTimeout="20000" edirectPort="9000" />
...
<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
<!-- 增加 context标签 -->
<Context docBase="spring-springmvc-xml" path="/" reloadable="true"/>
</Host>
...

(3)启动 apache-tomcat
apache-tomcat-7.0.91\bin\startup.bat

如果闪退,记得将安装目录添加到配置环境变量CATALINA_HOME=E:\work\software\apache-tomcat-7.0.91 :

image

(4)启动后控制台打印:
image
(5)启动后,war包被解压,应用放在webapps/spring-springmvc-xml 下:

image

10、测试

(1)访问首页:http://localhost:8180/spring-springmvc-xml/

image

(2)访问欢迎页:http://localhost:8180/spring-springmvc-xml/welcome?name=小明

image

http://localhost:8180/spring-springmvc-xml/welcome?name=小红

image

11、一些说明

11.1 web.xml context-param说明

context-param 里的 contextConfigLocation 和 init-param 的contextConfigLocation有什么区别?
(1)context-param 里的配置参数是所有的 servlet 实例共享的。
(2)context-param 里的contextConfigLocation 是 Root WebApplicationContext,是可以被很多 DispatcherServlet 实例继承的; init-param 的contextConfigLocation 是 WebApplicationContext ,只能当前 DispatcherServlet 实例拥有的配置,与其他 servlet(不仅仅是DispatcherServlet实例) 不共享。
(3)如果不需要 WebApplicationContext 的继承关系,则 context-param 里的contextConfigLocation 配置是:

  <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value></param-value>
  </context-param>

如果需要 WebApplicationContext 的继承,则 context-param 里的contextConfigLocation 配置是:

  <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:applicationContext.xml</param-value>
  </context-param>

如果需要继承 Root WebApplicationContext 的,则 init-param 里的contextConfigLocation 配置是:

   <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-context.xml</param-value>
    </init-param>

Spring 官方文档中的继承关系:

image

对应 web.xml 示例:

<web-app>
  <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/root-context.xml</param-value>
  </context-param>
  <servlet>
  <servlet-name>app1</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/app1-context.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
  <servlet-name>app1</servlet-name>
  <url-pattern>/app1/*</url-pattern>
  </servlet-mapping>
</web-app>

(4) 如果context-param 不配置 contextConfigLocation 参数, 那么默认会加载 /WEB-INF/applicationContext.xml 文件;
如果文件不存在,则会报错:

2021-07-19 00:42:41.802 [INFO ] [ost-startStop-1] o.s.web.context.ContextLoader.initWebApplicationContext[line:271]: Root WebApplicationContext: initialization started
2021-07-19 00:42:42.081 [DEBUG] [ost-startStop-1] w.c.s.XmlWebApplicationContext.prepareRefresh[line:629]: Refreshing Root WebApplicationContext
2021-07-19 00:42:42.225 [ERROR] [ost-startStop-1] o.s.web.context.ContextLoader.initWebApplicationContext[line:313]: Context initialization failed
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:342)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:224)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:195)
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
	at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:130)
	at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:671)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:553)
	at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:401)
	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:292)
	at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
	at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5157)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5680)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1018)
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:994)
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
	at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1127)
	at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:2021)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
	at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:159)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:333)
	... 25 common frames omitted

(5) 如果 dispatcherServlet init-param 不配置 contextConfigLocation 参数,会自动去加载 “/WEB-INF/${servletname}-servlet.xml” 即/WEB-INF/dispatcherServlet-servlet.xml ;如果文件不存在 那么会报错:

2021-07-19 00:39:47.019 [DEBUG] [ost-startStop-1] w.c.s.XmlWebApplicationContext.prepareRefresh[line:629]: Refreshing WebApplicationContext for namespace 'dispatcherServlet-servlet'
2021-07-19 00:39:47.031 [ERROR] [ost-startStop-1] o.s.w.s.DispatcherServlet.initServletBean[line:534]: Context initialization failed
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/dispatcherServlet-servlet.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/dispatcherServlet-servlet.xml]
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:342)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:224)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:195)
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
	at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:130)
	at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:671)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:553)
	at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:702)
	at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:668)
	at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:716)
	at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:591)
	at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:530)
	at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:170)
	at javax.servlet.GenericServlet.init(GenericServlet.java:158)
	at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1230)
	at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1174)
	at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1066)
	at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5409)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5707)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1018)
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:994)
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
	at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1127)
	at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:2021)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/dispatcherServlet-servlet.xml]
	at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:159)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:333)
	... 32 common frames omitted

11.2 一些特殊的Bean类型

Spring MVC 的9大组件

Bean type 解释
HandlerMapping 映射一个请求到一个Handler(有一堆拦截器);
主要有两个实现:RequestMappingHandlerMapping(支持@RequestMapping注解)和 SimpleUrlHandlerMapping(URL 映射到 一个 Handler)
HandlerAdapter 帮助DispatcherServlet调用handler
HandlerExceptionResolver 解决异常的策略
ViewResolver 根据逻辑视图名解析出真实的视图
LocaleResolver,LocaleContextResolver 解析器 Locale,为了提供国际化视图
ThemeResolver 解析应用能够使用的主题
MultipartResolver 解析multi-part请求
FlashMapManager 重定向时可以将一个请求的属性传给另一个请求
这篇关于SpringMVC快速使用——基于XML配置和Servlet3.0的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!