儿童 网站模板,网站打开速度慢优化,设计类网站建设规划书,免费刷赞网站推广qq免费SpringMVC概述
定义 SpringMVC是一种基于Java实现MVC设计模型的轻量级Web框架 MVC设计模型#xff1a;即将应用程序分为三个主要组件#xff1a;模型#xff08;Model#xff09;、视图#xff08;View#xff09;和控制器#xff08;Controller#xff09;。这种分离…SpringMVC概述
定义 SpringMVC是一种基于Java实现MVC设计模型的轻量级Web框架 MVC设计模型即将应用程序分为三个主要组件模型Model、视图View和控制器Controller。这种分离使开发人员可以更容易地管理和维护代码。 它属于SpringFrameWork的后续产品已经融合在Spring Web Flow中它拥有一套完善的注解机制通过注解可以让一个简单的Java类成为处理请求的控制器而无需实现任何接口。同时它还支持RESTful编程风格的请求 SpringMVC的三大组件处理器映射器HandlerMapping、处理器适配器HandlerAdapter、视图解析器ViewResolverSpringMVC就是要求我们编写一个个Controller控制器来处理请求然后将结果转换成JSON数据响应给客户端 SpringMVC快速入门
环境准备相同步骤 Step1 导入Spring坐标 导入Spring基础坐标spring-context 导入Spring提供的监听器ContextLoaderListener的相关坐标spring-web 导入Spring集成Web环境相关坐标servlet、jsp 导入Spring注解相关坐标Annotation 导入与AOP相关的坐标aop、aspectj AOP坐标会在导入spring-context坐标后系统自动导入如图所示 导入事务相关坐标spring-tx 导入数据库相关坐标mysql、数据源坐标druid、cp30 导入Spring集成JUnit相关坐标junit、spring-test 导入Spring集成MyBatis相关坐标mybatis、spring-jdbc、mybatis-spring SpringMVC的相关坐标spring-webmvc 注意必须为必须为5.2.x.RELEASE版本 project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.example/groupIdartifactIdSpringMvcDemo/artifactIdversion1.0-SNAPSHOT/version/parentartifactIdMvcClaDemo/artifactIdpackagingwar/packagingnameMvcClaDemo Maven Webapp/nameurlhttp://maven.apache.org/urldependenciesdependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion3.8.1/versionscopetest/scope/dependency!--Spring基础坐标--!--spring坐标--dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion6.1.6/version/dependency!--Spring自带监听器ContextLoaderListener所需坐标--!--spring-web--dependencygroupIdorg.springframework/groupIdartifactIdspring-web/artifactIdversion5.2.25.RELEASE/version/dependency!--Spring集成Web环境相关坐标--!-- servlet--dependencygroupIdjavax.servlet/groupIdartifactIdjavax.servlet-api/artifactIdversion4.0.1/versionscopeprovided/scope/dependency!--jsp--dependencygroupIdjavax.servlet.jsp/groupIdartifactIdjavax.servlet.jsp-api/artifactIdversion2.3.3/versionscopeprovided/scope/dependency!--Spring注解相关坐标--!--Annotation坐标--dependencygroupIdjavax.annotation/groupIdartifactIdjavax.annotation-api/artifactIdversion1.3.2/version/dependency!--Spring集成AOP相关坐标--!--aspectj坐标--dependencygroupIdorg.aspectj/groupIdartifactIdaspectjweaver/artifactIdversion1.9.22.1/version/dependency!--spring-tx坐标--dependencygroupIdorg.springframework/groupIdartifactIdspring-tx/artifactIdversion6.1.15/version/dependency!--数据库相关坐标--!--mysql坐标--dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.33/version/dependency!--druid坐标--dependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.2.18/version/dependency!--c3p0坐标--dependencygroupIdcom.mchange/groupIdartifactIdc3p0/artifactIdversion0.9.5.5/version/dependency!--Spring集成junit相关坐标--!--junit坐标--dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.13.2/versionscopetest/scope/dependency!--spring-test坐标--dependencygroupIdorg.springframework/groupIdartifactIdspring-test/artifactIdversion6.1.6/versionscopetest/scope/dependency!--MyBatis相关坐标--!--MyBatis坐标--dependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion3.5.16/version/dependency!--mybatis-spring--dependencygroupIdorg.mybatis/groupIdartifactIdmybatis-spring/artifactIdversion3.0.3/version/dependency!--spring-jdbc--dependencygroupIdorg.springframework/groupIdartifactIdspring-jdbc/artifactIdversion6.1.10/version/dependency!--SpringMVC基础坐标--!--spring-webmvc--dependencygroupIdorg.springframework/groupIdartifactIdspring-webmvc/artifactIdversion5.2.25.RELEASE/version/dependency/dependenciesbuildfinalNameMvcClaDemo/finalNameplugins!-- Tomcat插件 --plugingroupIdorg.apache.tomcat.maven/groupIdartifactIdtomcat7-maven-plugin/artifactIdversion2.2/version/plugin/plugins/build
/projectStep2 右键源代码配置文件目录即资源文件resources→New→File创建properties配置文件博主文件名为jdbc.properties该配置文件代码如下 注意 properties配置文件中配置的各个属性前必须添加个id.即id.属性比如属性url就设置为id.url博主设置的为jdbc.url以供Spring配置文件可以使用属性占位符${} 语法引用这些属性 #driverClassName代表数据库驱动后跟驱动全类名在MySQL驱动jar包下的META-INF下的services文件夹下的java.sql.Driver文件内
jdbc.driverClassNamecom.mysql.cj.jdbc.Driver
# 数据库连接URL
jdbc.urljdbc:mysql://localhost:3306/test02?useUnicodetruecharacterEncodingutf-8useSSLfalseserverTimezoneAsia/Shanghai
# 数据库用户名
jdbc.usernameroot
# 数据库密码
jdbc.password123456
# 初始化连接数量---即容器中初始的数据库连接数量
jdbc.initialSize5
# 最大活跃连接数量---容器中初始为5个但若5个用完了此时可以在申请5个数据库连接数量
#也就是说容器中最多存放10个数据库连接
jdbc.maxActive10
# 获取连接时的最大等待时间单位毫秒。---与数据库进行连接时若超过3s仍未连接成功则会报错
jdbc.maxWait3000
#最小空闲连接数量---minIdle5
# 配置检测连接是否有效的SQL可以是一个查询语句如果不指定则默认为SELECT 1---validationQuerySELECT 1
# 是否开启自动提交事务---defaultAutoCommittrueStep3 在web项目核心目录即webapp下创建视图页面success.jsp代码如下 % page contentTypetext/html;charsetUTF-8 languagejava %
htmlheadtitleTitle/title/headbodyh1...Success Running.../h1/body
/htmlSpringMVC XML代码实现 需求客户端发起请求服务端接受请求执行逻辑并进行视图跳转 步骤 导入SpringMVC的相关坐标配置SpringMVC的核心前端控制器DispathcerServlet 它拦截所有传入的请求并将它们分发到适当的控制器Controller进行处理。它可通过配置web.xml文件或Spring Boot的自动配置以注册DispatcherServlet。 编写 web/Controller表现层 的Controller控制器 创建Controller类和视图页面 使用注解Controller将Controller控制器配置到Spring容器中并利用注解RequestMapping(/xxx)来给控制器中的业务方法设置地址请求映射配置SpringMVC的核心文件spring-mvc.xml 在该文件中配置 web/Controller表现层 注解的组件扫描 在web.xml文件中配置SpringMVC的全局初始化参数 注意该全局初始化参数是在配置SpringMVC的核心前端控制器的Servlet标签体内配置的因为SpringMVC的全局初始化参数主要是该核心前端控制器DispatcherServlet使用的 执行访问测试即客户端发起请求测试 注意 SpringMVC快速入门之前要先把Spring相关代码及配置工作完成具体步骤可详见Spring完整知识点汇总中的Spring集成Web环境→Spring配置文件的形式此时不在需要 web/Controller表现层 包下的继承Servlet接口的类因为SpringMVC的本质就是对Servlet的简化处理 Step1 创建业务层service包、持久层dao包、表现层controller包代码分别如下 在dao包下创建UserDao接口代码如下 package at.guigu.dao;public interface UserDao {public void save();
}在service包下创建UserService类代码如下 package at.guigu.service;import at.guigu.dao.UserDao;public class UserService {private UserDao userDao;public void setUserDao(UserDao bookDao) {this.userDao bookDao;}public void save() {System.out.println(BookService save...);userDao.save();}
}在controller包下创建UserController类代码如下 package at.guigu.controller;public class Usercontroller {public String save() {System.out.println(Usercontroller save...);//跳转到指定的视图页面return success.jsp;}
}Step2 使用RequestMapping注解配置Controller控制器对应类中业务方法的映射地址Usercontroller代码更改如下 package at.guigu.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;//将Usercontroller放到Spring容器中
Controller
public class Usercontroller {//设置请求地址映射RequestMapping(/quick)public String save() {System.out.println(Usercontroller save...);return success.jsp;}
}Step3 右键源代码配置文件目录即资源文件resources→New→XML Configuration File→Spring Config文件名为spring-mvc.xml然后配置Spring以及SpringMVC的核心文件applicationContext.xml、spring-mvc.xml代码如下 Step3-1 Spring的核心配置文件代码如下 使用context命名空间加载 jdbc.properties 文件前提需引入context命名空间和约束路径 context命名空间xmlns:contexthttp://www.springframework.org/schema/contextcontext约束路径http://www.springframework.org/schema/context、http://www.springframework.org/schema/context/spring-context.xsd 配置数据源对应的bean配置MyBatis的SqlSessionFactory 配置数据源配置MyBatis核心配置文件注意若有的配置必须通过MyBatis核心配置文件配置时则需要该步配置别名 引入dao包下所有接口对应的SQL映射文件 此时Spring会进行持久层扫描,自动生成该层中对应接口的bean ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd!--使用context命名空间加载 properties 文件--context:property-placeholder locationclasspath:jdbc.properties/!--Druid对应的bean--bean iddataSourceDruid classcom.alibaba.druid.pool.DruidDataSource!--使用属性占位符${}语法引用properties文件中的属性--property namedriverClassName value${jdbc.driverClassName}/property nameurl value${jdbc.url}/property nameusername value${jdbc.username}/property namepassword value${jdbc.password}//bean!--配置MyBatis的SqlSessionFactory--bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBean!--配置数据源--property namedataSource refdataSourceDruid/!--加载MyBatis的核心配置文件property nameconfigLocation valueclasspath:mybatis-config.xml/--!--配置别名--property nametypeAliasesPackage valueat.guigu.pojo//bean!--引入dao包下所有接口对应的SQL映射文件即MyBatis 持久层扫描,会自动生成该层中对应接口的bean--bean classorg.mybatis.spring.mapper.MapperScannerConfigurerproperty namebasePackage valueat.guigu.dao//bean!--配置bookService bean--bean idbookService classat.guigu.service.UserService!--绑定依赖关系--property nameuserDao refuserDao/property/bean/beansStep3-2 SpringMVC的核心配置文件代码如下 配置注解的组件扫描 需要在SpringMVC的配置文件中引入context和mvc的命名空间、约束路径然后使用context命名空间配置组件扫描即可。 命名空间 xmlns:contexthttp://www.springframework.org/schema/context
xmlns:mvchttp://www.springframework.org/schema/mvc约束路径 http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd配置组件扫描代码context:component-scan base-packageat.guigu.controller/context:component-scan base-package给定一个包然后会自动扫描该包下的所有内容以便可以识别使用注解配置的类、字段和方法 注意 其它三层架构包的注解的组件扫描在Spring的配置文件中配置引入mvc的命名空间和约束路径是为了配置mvc的注解驱动其作用可详见 SpringMVC回写数据——返回对象或集合 部分的内容 ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:contexthttp://www.springframework.org/schema/contextxmlns:mvchttp://www.springframework.org/schema/mvcxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd!--mvc的注解驱动--mvc:annotation-driven/!--配置Controller层的注解的组件扫描--context:component-scan base-packageat.guigu.controller/context:component-scan!--等同于context:component-scan base-packageat.guigutype指定要扫描的内容为注解expression指定要扫描的对应注解的全限定名只扫描at.guigu包下有Controller注解的类context:include-filter typeannotation expressionorg.springframework.stereotype.Controller//context:component-scan --
/beansStep4 在web项目核心目录即webapp下的web.xml中进行全局配置。web.xml完整代码如下 配置Spring相关的配置 Spring的全局初始化参数、配置Spring所提供的ContextLoaderListener 监听器、web配置 配置SpringMVC的核心前端控制器DispathcerServlet配置SpringMVC的全局初始化参数该全局初始化参数用于定义SpringMVC的配置文件供监听器使用 !DOCTYPE web-app PUBLIC-//Sun Microsystems, Inc.//DTD Web Application 2.3//ENhttp://java.sun.com/dtd/web-app_2_3.dtd web-appdisplay-nameArchetype Created Web Application/display-name!--配置Spring的全局初始化参数--context-param!--定义参数的名称必须是唯一的--param-namecontextConfigLocation/param-name!--定义参数的值--param-valueclasspath:applicationContext.xml/param-value/context-param!--监听器--!--配置Spring所提供的ContextLoaderListener 监听器--listener!--监听器类的全限定名--listener-classorg.springframework.web.context.ContextLoaderListener/listener-class/listener!--声明Servlet--!--配置SpringMVC的前端控制器的Servlet--servletservlet-nameDispatcherServlet/servlet-nameservlet-classorg.springframework.web.servlet.DispatcherServlet/servlet-class!--配置SpringMVC的全局初始化参数--init-paramparam-namecontextConfigLocation/param-nameparam-valueclasspath:spring-mvc.xml/param-value/init-paramload-on-startup1/load-on-startup/servlet!--将URL模式映射到特定的Servlet上即DispatcherServlet--servlet-mapping!--指定的Servlet的类名--servlet-nameDispatcherServlet/servlet-name!--给指定的Servlet设置url相当于WebServlet(/)--!--代表将所有请求都交给前端控制器处理--url-pattern//url-pattern/servlet-mapping/web-app客户端发起请求测试Tomcat运行该Web项目后输入地址映射的url后会自动跳转到success.jsp页面 完整包结构如下
SpringMVC注解代码实现 Step1 创建业务层service包、持久层dao包、表现层controller包代码分别如下 在dao包下创建UserDao接口代码如下 package at.guigu.dao;
import org.apache.ibatis.annotations.Mapper;Mapper
public interface UserDao {public void save();
}Mapper注解作用 用于标记单个Mapper接口让MyBatis生成它的实现类并注入到Spring容器中。也就是说此时不需要创建持久层的实现类有IOC容器自动创建其唯一标识id为对应接口名首字母大写即userDao 该注解也可以使用MapperScan(at.guigu.dao)来代替不过该注解需写在Spring的核心配置文件中表示 用于扫描指定包中的所有接口将它们自动注册为Spring的Bean并作为Mapper 以上两个注解在做项目时可根据实际情况选择 由于它们需要让MyBatis生成它的实现类并注入到Spring容器中所以必须要有MyBatis的核心配置类否则不会生效 在service包下创建UserService类代码如下 package at.guigu.service;import at.guigu.dao.UserDao;
import org.springframework.stereotype.Service;Service(userService)
public class UserService {private UserDao userDao;public void setUserDao(UserDao bookDao) {this.userDao bookDao;}public void save() {System.out.println(BookService save...);userDao.save();}
}在controller包下创建UserController类代码如下 package at.guigu.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;// 将Usercontroller放到Spring容器中
Controller
public class Usercontroller {// 设置请求地址映射RequestMapping(/quick)public String save() {System.out.println(Usercontroller save...);// 跳转到指定的视图页面return success.jsp;}
}Step2 创建一个与三层架构包同级的config包并在该包下创建拆分配置文件对应的数据源拆分类DataSourceConfiguration代码如下以Druid为例 Step2-1 创建数据源bean package at.guigu.config;import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;import javax.sql.DataSource;// 分配置文件对应的类不用配置Configuration以及ComponentScan注解
// 加载properties配置文件context:property-placeholder locationclasspath:jdbc.properties/
PropertySource(classpath:jdbc.properties)
public class DataSourceConfiguration {Value(${jdbc.driverClassName})private String driverClassName;Value(${jdbc.url})private String url;Value(${jdbc.username})private String username;Value(${jdbc.password})private String password;/*** Druid对应的bean* Spring会将当前方法的返回值以指定的id存储到Spring的IOC容器中* return* throws Exception*/Bean(dataSourceDruid)public DataSource getDruidDataSource() throws Exception{// 创建数据源对象DruidDataSource dataSource new DruidDataSource();// 设置数据源基本连接数据dataSource.setDriverClassName(driverClassName);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;}
}Step3 在config包下创建MyBatis的核心配置类MyBatisConfiguration代码如下 package at.guigu.config;import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;import javax.sql.DataSource;public class MyBatisConfiguration {Beanpublic SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {SqlSessionFactoryBean sqlSessionFactoryBean new SqlSessionFactoryBean();// 相当于设置别名package nameat.guigu.pojo/sqlSessionFactoryBean.setTypeAliasesPackage(at.guigu.pojo);// 相当于配置数据库连接信息sqlSessionFactoryBean.setDataSource(dataSource);return sqlSessionFactoryBean;}// 映射扫描配置类相当于引入dao包下所有接口对应的SQL映射文件package nameat.guigu.dao/Beanpublic MapperScannerConfigurer mapperScannerConfigurer() {MapperScannerConfigurer mapperScannerConfigurer new MapperScannerConfigurer();mapperScannerConfigurer.setBasePackage(at.guigu.dao);return mapperScannerConfigurer;}
}Step4 在config包下创建Spring主配置文件对应的主类SpringConfiguration引入分配置文件对应的拆分类DataSourceConfiguration以及MyBatisConfiguration代码如下 package at.guigu.config;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;// 该注解代表该类是Spring的核心配置类
Configuration
// 配置注解的组件扫描context:component-scan base-packageat.guigu/context:component-scan
ComponentScan(at.guigu)
MapperScan(at.guigu.dao)
// 引入拆分配置文件import resourceapplicationContext-xxx.xml/
Import({DataSourceConfiguration.class, MyBatisConfiguration.class})
public class SpringConfiguration {
}注意 由于在配置注解的组件扫描时属性值为at.gui所以此时Spring会扫描包括controller包下的注解为避免该情况则有两种解决方式 将Spring加载的bean设定扫描范围为精准范围比如ComponentScan(basePackages {at.guigu.dao, at.guigu.service}) 将Spring加载的bean设定扫描范围为at.gui后排除掉controller包内的bean该注解改为如下形式ComponentScan(value at.guigu, excludeFilters ComponentScan.Filter(type FilterType.ANNOTATION, classes Controller.class)) 改进后的Spring核心配置类代码如下 package at.guigu.config;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Controller;// 该注解代表该类是Spring的核心配置类
Configuration
// 配置注解的组件扫描context:component-scan base-packageat.guigu.dao, at.guigu.service/context:component-scan
ComponentScan(value at.guigu,excludeFilters ComponentScan.Filter(type FilterType.ANNOTATION, classes Controller.class))MapperScan(at.guigu.dao)
// 引入拆分配置文件import resourceapplicationContext-xxx.xml/
Import({DataSourceConfiguration.class, MyBatisConfiguration.class})
public class SpringConfiguration {
}Step5 在config包下创建SpringMVC核心配置类SpringMvcConfiguration代码如下 package at.guigu.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;// 该注解代表该类是SpringMVC的核心配置类
Configuration
// 配置注解的组件扫描context:component-scan base-packageat.guigu.controller/context:component-scan
// 加载controller对应的bean
ComponentScan(at.guigu.controller)
// 自动配置SpringMVC的各种配置
EnableWebMvc
public class SpringMvcConfiguration {
}Step6 在web项目核心目录即webapp下的web.xml中进行全局配置。web.xml完整代码如下 配置Spring相关的配置 Spring的全局初始化参数、配置Spring所提供的ContextLoaderListener 监听器、web配置 配置SpringMVC的核心前端控制器DispathcerServlet配置SpringMVC的全局初始化参数该全局初始化参数用于定义SpringMVC的配置类供监听器使用 !DOCTYPE web-app PUBLIC-//Sun Microsystems, Inc.//DTD Web Application 2.3//ENhttp://java.sun.com/dtd/web-app_2_3.dtd web-appdisplay-nameArchetype Created Web Application/display-name!--配置Spring配置类的全局初始化参数--context-paramparam-namecontextClass/param-nameparam-valueorg.springframework.web.context.support.AnnotationConfigWebApplicationContext/param-value/context-paramcontext-param!--定义参数的名称必须是唯一的--param-namecontextConfigLocation/param-name!--定义参数的值--param-valueat.guigu.config.SpringConfiguration/param-value/context-param!--监听器--!--配置Spring所提供的ContextLoaderListener 监听器--listener!--监听器类的全限定名--listener-classorg.springframework.web.context.ContextLoaderListener/listener-class/listener!--配置SpringMVC的前端控制器的Servlet--servletservlet-nameDispatcherServlet/servlet-nameservlet-classorg.springframework.web.servlet.DispatcherServlet/servlet-class!-- 配置 Spring MVC 的核心配置类 --init-paramparam-namecontextClass/param-nameparam-valueorg.springframework.web.context.support.AnnotationConfigWebApplicationContext/param-value/init-paraminit-paramparam-namecontextConfigLocation/param-name!--写入SpringMVC核心配置类的全限定名--param-valueat.guigu.config.SpringMvcConfiguration/param-value/init-paramload-on-startup1/load-on-startup/servlet!--将URL模式映射到特定的Servlet上即DispatcherServlet--servlet-mapping!--指定的Servlet的类名--servlet-nameDispatcherServlet/servlet-name!--给指定的Servlet设置url相当于WebServlet(/)--url-pattern//url-pattern/servlet-mapping
/web-app客户端发起请求测试Tomcat运行该Web项目后输入地址映射的url后会自动跳转到success.jsp页面 完整包结构如下
替代web.xml文件方式一
AbstractDispatcherServletInitializer类中的抽象方法解释WebApplicationContext createServletApplicationContext()创建Servlet容器时来加载SpringMVC对应的bean并放入WebApplicationContext对象范围中作用范围为ServletContext范围即整个web容器即加载SpringMVC的配置String[] getServletMappings()设置SpringMVC对应的请求映射路径当为/时表示拦截所有请求此时任意请求都将转入到SpringMVC中进行处理AbstractDispatcherServletInitializer父类AbstractContextLoaderInitializer中的抽象方法解释WebApplicationContext createRootApplicationContext()用于加载非SpringMVC对应的bean比如加载Spring配置。其使用方法与createServletApplicationContext()相同
为实现完全注解形式可创建一个继承AbstractDispatcherServletInitializer类的子类ServletContainerInitConfiguration来替代web.xml文件从而实现全注解形式的开发
快速入门 此处只进行web.xml配置文件对应的配置类的编写其它步骤可详见SpringMVC注解代码实现 Step1 在config包下创建web.xml配置文件对应的配置类即继承AbstractDispatcherServletInitializer类的子类ServletContainerInitConfiguration并重写其中的三个方法原始代码如下 package at.guigu.config;import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;// 定义一个Servlet容器启动的配置类来加载Spring的配置
public class ServletContainerInitConfiguration extends AbstractDispatcherServletInitializer {// 加载SpringMVC的配置Overrideprotected WebApplicationContext createServletApplicationContext() {return null;}// 设置哪些请求归SpringMVC处理Overrideprotected String[] getServletMappings() {return new String[0];}// 加载非SringMVC的配置比如加载Spring的配置Overrideprotected WebApplicationContext createRootApplicationContext() {return null;}
}Step2 在createServletApplicationContext()方法中加载SpringMVC配置并在getServletMappings()方法中设置SpringMVC对应的请求映射路径代码如下 package at.guigu.config;import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;// 定义一个Servlet容器启动的配置类来加载Spring的配置
public class ServletContainerInitConfiguration extends AbstractDispatcherServletInitializer {// 加载SpringMVC的配置Overrideprotected WebApplicationContext createServletApplicationContext() {AnnotationConfigWebApplicationContext context new AnnotationConfigWebApplicationContext();context.register(ServletContainerInitConfiguration.class);return context;}// 设置哪些请求归SpringMVC处理Overrideprotected String[] getServletMappings() {// 代表将所有请求都交给前端控制器处理return new String[]{/};}// 加载非SringMVC的配置比如加载Spring的配置Overrideprotected WebApplicationContext createRootApplicationContext() {return null;}
}Step3 在createRootApplicationContext()方法中加载Spring配置代码如下 package at.guigu.config;import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;// 定义一个Servlet容器启动的配置类来加载Spring的配置
public class ServletContainerInitConfiguration extends AbstractDispatcherServletInitializer {// 加载SpringMVC的配置Overrideprotected WebApplicationContext createServletApplicationContext() {AnnotationConfigWebApplicationContext context new AnnotationConfigWebApplicationContext();context.register(SpringMvcConfiguration.class);return context;}// 设置哪些请求归SpringMVC处理Overrideprotected String[] getServletMappings() {// 代表将所有请求都交给前端控制器处理return new String[]{/};}// 加载非SringMVC的配置比如加载Spring的配置Overrideprotected WebApplicationContext createRootApplicationContext() {AnnotationConfigWebApplicationContext context new AnnotationConfigWebApplicationContext();context.register(SpringConfiguration.class);return context;}
}Step5 删除web.xml文件
运行截图如下 完整包结构如下 替代web.xml文件方式二
AbstractAnnotationConfigDispatcherServletInitializer类中的抽象方法解释Class?[] getServletConfigClasses()加载SpringMVC的配置Class?[] getRootConfigClasses()加载非SpringMVC对应的bean比如加载Spring配置AbstractAnnotationConfigDispatcherServletInitializer父类AbstractDispatcherServletInitializer中的抽象方法解释String[] getServletMappings()设置SpringMVC对应的请求映射路径当为/时表示拦截所有请求此时任意请求都将转入到SpringMVC中进行处理
快速入门 此处只进行web.xml配置文件对应的配置类的编写其它步骤可详见SpringMVC注解代码实现 Step1 在config包下创建web.xml配置文件对应的配置类即继承AbstractAnnotationConfigDispatcherServletInitializer类的子类ServletContainerInitConfiguration并重写其中的三个方法代码如下 package at.guigu.config;import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;// 定义一个Servlet容器启动的配置类来加载Spring的配置
public class ServletContainerInitConfiguration extends AbstractAnnotationConfigDispatcherServletInitializer {// 加载SpringMVC的配置Overrideprotected Class?[] getServletConfigClasses() {return new Class[]{SpringMvcConfiguration.class};}// 设置哪些请求归SpringMVC处理Overrideprotected String[] getServletMappings() {return new String[]{/};}// 加载非SringMVC的配置比如加载Spring的配置Overrideprotected Class?[] getRootConfigClasses() {return new Class[]{SpringConfiguration.class};}
}Step2 删除web.xml文件
运行截图如下 完整包结构如下 SpringMVC的执行流程 执行流程图解释 用户发送请求到前端控制器DispatcherServlet前端控制器DispatcherServlet收到请求后调用处理器映射器HandlerMapping处理器映射器HandlerMapping找到具体的处理器可通过xml配置、注解进行查找后会生成处理器对象以及处理器拦截器然后将其返回给前端控制器DispatcherServlet前端控制器DispatcherServlet收到后将会调用处理器适配器Handler Adapter处理器适配器HandlerAdapter经过适配会调用具体的处理器Controller即控制器也叫作后端控制器来处理处理器Controller即控制器也叫作后端控制器执行完成后会返回ModelAndView即模型和视图处理器适配器HandlerAdapter会将处理器Controller即控制器也叫作后端控制器返回的ModelAndView即模型和视图返回给前端控制器DispatcherServlet前端控制器DispatcherServlet会将ModelAndView即模型和视图传给视图解析器View Resolver视图解析器ViewResolver解析后会返回给前端控制器DispatcherServlet具体的视图View前端控制器DispatcherServlet会根据模型Model来渲染视图View即将模型数据填充到视图中最终由前端控制器DispatcherServlet将完整的响应页面响应给用户 即首先会通过核心前端控制器DispatcherServlet获取到所有客户端发送的Http请求然后通过处理器映射器HandlerMappingjia那个请求分别发送给对应的控制器进行处理处理完后会返回一个ModelAndView对象包含模型数据和视图。然后前端控制器DispatcherServlet会通过视图解析器将视图解析为实际的视图对象然后将模型数据填充到视图中进行渲染并将结果返回给客户端。
SpringMVC解析
SpringMVC组件解析 DispatcherServlet前端控制器 SpringMVC的核心组件充当前端控制器Front Controller。 它拦截所有传入的请求并将它们分发到适当的控制器进行处理。 配置web.xml文件或Spring Boot的自动配置以注册DispatcherServlet。 Controller处理器、控制器、后端控制器 用于处理用户请求并返回相应的模型和视图。通过注解如Controller和RequestMapping定义RequestMapping用于映射URL到控制器的方法。 Controller
public class MyController {RequestMapping(/hello)public String sayHello(Model model) {model.addAttribute(message, Hello, SpringMVC!);return hello; // 返回视图名称}
}Model模型 用于存储数据和业务逻辑。控制器将数据添加到模型中然后传递给视图进行展示 View视图 负责显示模型中的数据。常见的视图技术包括JSP、Thymeleaf、Freemarker等。视图解析器View Resolver用于解析视图名称并渲染最终的视图。 View Resolver视图解析器 负责将控制器返回的视图名称解析为实际的视图对象。可以配置不同的视图解析器如InternalResourceViewResolver用于JSP、ThymeleafViewResolver用于Thymeleaf等。 // Bean使用在方法上将方法的返回值存储到容器中
Bean
public InternalResourceViewResolver viewResolver() {InternalResourceViewResolver resolver new InternalResourceViewResolver();resolver.setPrefix(/WEB-INF/views/);resolver.setSuffix(.jsp);return resolver;
}Handler Mapping处理器映射器 负责将传入的请求映射到对应的控制器。Spring提供了多种处理器映射如BeanNameUrlHandlerMapping、RequestMappingHandlerMapping等。 Handler Adapter处理器适配器 负责调用控制器中的方法。不同类型的控制器需要不同的处理器适配器如HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter等 Exception Handling异常处理 通过ExceptionHandler注解处理控制器中的异常。还可以配置全局异常处理器如ControllerAdvice。 ControllerAdvice
public class GlobalExceptionHandler {ExceptionHandler(Exception.class)public ModelAndView handleException(Exception ex) {ModelAndView model new ModelAndView(error);model.addObject(message, ex.getMessage());return model;}
}通过以上组件的协同工作SpringMVC可以高效地处理Web请求并实现清晰的代码分离使得Web应用程序更加模块化和易于维护。
SpringMVC注解解析
注解解释RequestMapping用于建立请求URL和处理请求方法之间的对应关系。使用在类上 请求URL的第一级访问目录。此处不写的话就相当于应用的根目录使用在方法上 请求URL的第二级访问目录与类上使用该注解标注的一级目录一起构成虚拟路径EnableWebMvc用于启用 Spring MVC 的一系列配置功能的核心注解。它通常与 Java 配置类结合使用来自动配置 Spring MVC 的各种特性 。ResponseBody设置当前控制器方法相应内容为当前返回值无需解析。可详见SpringMVC回写数据部分内容RequestParam(value, required, defaultValue)用于 获取请求参数 的注解RequestBody将 HTTP 请求的 请求体body中包含的数据传递给请求参数比如JSON数据、XML、表单数据等DateTimeFormat(pattern)设置日期时间的数据格式patter为要设置的日期时间格式的字符串。可详见获取日期类型的代码示例PathVatiable用于Rest风格绑定路劲参数与处理器方法形参间的关系要求路径参数名与形参名一一对应。可详见Rest风格部分示例RestController设置当前控制器类为Restful风格等同于ControllerResponseBodyGetMapping(value)设置当前控制器方法Get请求访问路径以及Restful风格的动作等同于RequestMapping(value, methodRequestMethod.Get)PostMapping(value)设置当前控制器方法Post请求访问路径以及Restful风格的动作等同于RequestMapping(value, methodRequestMethod.Post)PutMapping(value)设置当前控制器方法Put请求访问路径以及Restful风格的动作等同于RequestMapping(value, methodRequestMethod.Put)DeleteMapping(value)设置当前控制器方法Delete请求访问路径以及Restful风格的动作等同于RequestMapping(value, methodRequestMethod.Delete)
RequestMapping属性解释value用于指定请求的URL。与path属性的作用一样method用于指定请求的方式默认为get请求方式params用于指定限制请求参数的条件。它支持简单的表达式要求请求参数的key和value必须与配置的一模一样
EnableWebMvc 可用来自动配置 Spring MVC 的各种特性 比如 类型转换器 它可根据类型自动匹配对应的类型转换器比如时间格式的转换可详见获取日期类型的代码示例 异常处理视图解析器 默认的视图解析器会查找 /WEB-INF/views/ 下的 JSP 文件 静态资源处理验证支持Spring表单标签支持参数解析和绑定跨域支持SpringMVC拦截器支持资源绑定支持mvc的注解驱动mvc:annotation-driven/ 可代替配置处理器适配器 RequestParam与RequestBody的区别 区别 RequestParam用于接收url地址传参表单传参 RequestBody用于接收json数据应用 后期开发中发送json格式数据为主RequestBody应用较广 如果发送非json格式数据选用RequestParam接收请求参数
RequestMapping RequestMapping 在快速入门中该注解应用在方法上并未应用在类上所以URL为http://localhost:8080/quick 若该注解既应用在类上也应用在方法上则URL为http://localhost:8080/xxx/quick代码如下所示 当加在类上时其参数值一般按照不同的功能模块进行分类书写如下代码所示由于是User模块所以设置为RequestMapping(user)URL此时即为http://localhost:8080/user/quick package at.guigu.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;//将Usercontroller放到Spring容器中
Controller
RequestMapping(/user)
public class Usercontroller {//设置请求地址映射RequestMapping(/quick)public String save() {System.out.println(Usercontroller save...);return success.jsp;}
}RequestMapping与返回值的关系 当RequestMapping只应用在类或方法上 返回值为return success.jsp此时系统会自动在Web项目核心目录即webapp下找success.jsp文件返回值为return /success.jsp系统会自动在Web项目核心目录即webapp下找success.jsp文件返回值为return /jsp/success.jsp系统会自动在Web项目核心目录即webapp下的jsp目录下找success.jsp文件 当RequestMapping同时应用在类和方法上 返回值为return success.jsp此时系统会自动在Web项目核心目录即webapp下的user目录下找success.jsp文件 若想让其直接在Web项目核心目录即webapp下找success.jsp文件则将返回值改为return /success.jsp 返回值为return /success.jsp系统会自动在Web项目核心目录即webapp下找success.jsp文件 返回值为return /jsp/success.jsp系统会自动在Web项目核心目录即webapp下的jsp目录下找success.jsp文件 注意 当配置了内部资源视图解析器后此时return success返回的success.jsp文件的地址与RequestMapping应用在哪里无关只与内部资源视图解析器中配置的地址有关以如下代码为例此时只会去找webapp目录下的jsp目录下的success.jsp文件 // 配置视图解析器
Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver new InternalResourceViewResolver();
resolver.setPrefix(/jsp/); // 设置视图文件路径前缀
resolver.setSuffix(.jsp); // 设置视图文件后缀
return resolver;
}value用于指定请求的URL 当RequestMapping注解有多个属性时该属性名称不可省略如RequestMapping(value/xxx, methodRequestMethod.GET)当RequestMapping注解只有这一个属性时该属性名称可省略如RequestMapping(/xxx) method用于指定请求的方式。常用于Rest风格 该属性值利用枚举类RequestMethod来调用如图所示 params用于指定限制请求参数的条件 它支持简单的表达式要求请求参数的key和value必须与配置的一模一样 params{accountName}此时客户端的请求参数中必须有accountName params{money!100}此时客户端的请求参数必须有money且该参数值不能为100 代码示例如下 package at.guigu.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;//将Usercontroller放到Spring容器中
Controller
RequestMapping(/user)
public class Usercontroller {//设置请求地址映射并限定请求参数的条件RequestMapping(value /quick, params {username})public String save() {System.out.println(Usercontroller save...);return success.jsp;}
}Tomcat运行该Web项目后若不加限定的请求参数则会报错如图一所示加上后才会成功运行如图二所示
SpringMVC 配置文件形式
SpringMVC 配置文件形式的组件扫描 在SpringMVC的核心文件spring-mvc.xml中配置组件扫描的步骤如下 mvc命名空间引入 引入mvc命名空间xmlns:mvchttp://www.springframework.org/schema/mvc 引入mvc的约束路径 http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/context/spring-mvc.xsdcontext命名空间引入 引入context命名空间xmlns:contexthttp://www.springframework.org/schema/context 引入context的约束路径 http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd配置组件扫描代码context:component-scan base-packageat.guigu.controller/context:component-scan SpringMVC是基于Spring容器的所以在进行SpringMVC操作时就要利用Controller注解将Controller存储到Spring容器中若要使用Controller注解标注的话就需要用组件扫描代码进行组件扫描 配置组件扫描的代码有两个书写方法 !--配置Controller层的注解的组件扫描方法一--
context:component-scan base-packageat.guigu.controller/context:component-scan!--配置Controller层的注解的组件扫描方法二--
context:component-scan base-packageat.guigu!--type指定要扫描的内容为注解expression指定要扫描的对应注解Controller的全限定名--!--只扫描at.guigu包下有Controller注解的类--context:include-filter typeannotation expressionorg.springframework.stereotype.Controller/
/context:component-scan注意 Spring和SpringMVC注解的组件扫描要各自扫描各自的模块互不干扰。所以在配置注解的组件扫描时 若是Spring的就在Spring的核心配置文件中进行注解的组件扫描若是SpringMVC的就在SpringMVC的核心配置文件中进行注解的组件扫描
SpringMVC配置文件形式的核心配置文件spring-mvc.xml解析 注意 SpringMVC有默认组件配置默认组件都是在DispatherServlet.properties配置文件中配置的该配置文件在External Libraries下如图所示 配置Controller层的注解的组件扫描 方式一context:component-scan base-packageat.guigu.controller/context:component-scan 方式二 context:component-scan base-packageat.guigu!--type指定要扫描的内容为注解expression指定要扫描的对应注解的全限定名--!--只扫描at.guigu包下有Controller注解的类--context:include-filter typeannotation expressionorg.springframework.stereotype.Controller/
/context:component-scan注意配置Controller层的注解的组件扫描时需要引入命名空间可详见SpringMVC组件扫描 额外知识点 Controller包下Usercontroller代码如下 package at.guigu.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;//将Usercontroller放到Spring容器中
Controller
RequestMapping(/user)
public class Usercontroller {//设置请求地址映射RequestMapping(/quick)public String save() {System.out.println(Usercontroller save...);return /success.jsp;}
}Tomcat运行该Web项目后运行截图如下从截图中可看出我们输入完URL回车后显示了success.jsp页面的代码在此过程中URL并没有改变。说明return /success.jsp默认使用的是 请求转发 的技术可详见WebHttpServletRequestResponse 所以return /success.jsp相当于return forward:/success.jsp 若我们将return /success.jsp改为return redirect:/success.jsp则此时运行Web项目后截图如下 从截图中可知此时就变成了使用 重定向 技术可详见WebHttpServletRequestResponse 配置内部资源视图解析器 InternalResourceViewResolver 当返回值为return /jsp/success.jsp时系统会自动在Web项目核心目录即webapp下的jsp目录下找success.jsp文件 我们可以在SpringMVC的核心配置文件中配置内部资源视图解析器来将以上返回值简化为return success 配置步骤如下 !--配置内部资源视图解析器--
bean idviewResolver classorg.springframework.web.servlet.view.InternalResourceViewResolver!--将InternalResourceViewResolver类中的视图名称前缀属性prefix的值设为/jsp/--property nameprefix value/jsp//property!--将InternalResourceViewResolver类中的视图名称后缀属性suffix的值设为.jsp--property namesuffix value.jsp/property
/bean配置完成后Tomcat运行该Web项目输入URL后系统会将返回值return success中的success拿出来然后自动与/jsp/以及.jsp进行拼接拼接为/jsp/success.jsp即return /jsp/success.jsp。然后系统会自动在Web项目核心目录即webapp下的jsp目录下找success.jsp文件并将该jsp文件显示在客户端页面上配置代码截图如下
SpringMVC注解形式
SpringMVC注解形式的组件扫描 在SpringMVC的核心类SpringMvcConfiguration中利用ComponentScan注解来配置组件扫描如下代码所示 package at.guigu.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;// 该注解代表该类是SpringMVC的核心配置类
Configuration
// 配置注解的组件扫描context:component-scan base-packageat.guigu.controller/context:component-scan
// 加载controller对应的bean
ComponentScan(at.guigu.controller)
EnableWebMvc
public class SpringMvcConfiguration {
}需要注意的是在配置Spring核心配置类中的注解组件扫描时ComponentScan属性值为at.gui所以此时Spring会扫描包括controller包下的注解为避免该情况则有两种解决方式 将Spring加载的bean设定扫描范围为精准范围比如ComponentScan(basePackages {at.guigu.dao, at.gui.service}) 将Spring加载的bean设定扫描范围为at.gui后排除掉controller包内的bean该注解改为如下形式ComponentScan(value at.guigu, excludeFilters ComponentScan.Filter(type FilterType.ANNOTATION, classes Controller.class))
SpringMVC注解形式的核心配置类解析
SpringMVC有默认组件配置默认组件都是在DispatherServlet.properties配置文件中配置的该配置文件在External Libraries下如图所示 在入门案例中使用了EnableWebMvc注解来自动配置 SpringMVC 的各种特性若想要修改则可以在SpringMVC的核心配置类中利用Bean注解来配置一个返回值为相应类的对象此处以配置内部资源视图解析器为例 配置内部资源视图解析器 InternalResourceViewResolver 当返回值为return /jsp/success.jsp时系统会自动在Web项目核心目录即webapp下的jsp目录下找success.jsp文件 我们可以在SpringMVC的核心配置文件中配置内部资源视图解析器来将以上返回值简化为return success 解决方式在SpringMVC的核心配置类中配置内部资源视图解析器代码如下 package at.guigu.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;// 该注解代表该类是SpringMVC的核心配置类
Configuration
// 配置注解的组件扫描context:component-scan base-packageat.guigu.controller/context:component-scan
// 加载controller对应的bean
ComponentScan(at.guigu.controller)
// 自动配置 Spring MVC 的各种特性
EnableWebMvc
public class SpringMvcConfiguration {// 配置视图解析器Beanpublic InternalResourceViewResolver viewResolver() {InternalResourceViewResolver resolver new InternalResourceViewResolver();resolver.setPrefix(/jsp/); // 设置视图文件路径前缀resolver.setSuffix(.jsp); // 设置视图文件后缀return resolver;}
}SpringMVC数据响应 该部分示例项目MvcRespXmlDemo及MvcRespClaDemo已上传至Gitee可自行下载 SpringMVC的数据响应方式 方式一页面跳转 直接返回字符串通过ModelAndView对象返回 方式二回写数据 直接返回字符串返回对象或集合 环境准备等工作可详见快速入门
SpringMVC页面跳转
SpringMVC页面跳转——直接返回字符串
在我们之前的示例中均是直接返回字符串的形式比如 return success.jspreturn /success.jspreturn /jsp/success.jsp此处不在对直接返回字符出串的形式做详细解释 注意 若我们配置了内部资源视图解析器此时我们直接返回的字符串会与视图解析器的前后缀拼接到一起后跳转可详见SpringMVC的核心配置文件解析在一下示例中均默认已配置内部资源视图解析器来完成示例操作
SpringMVC页面跳转——通过ModelAndView对象返回 通过ModelAndView对象返回有四种方式代码示例如下 controller包下的UserController类代码如下 package at.guigu.controller;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;//将Usercontroller放到Spring容器中
Controller
RequestMapping(/user)
public class Usercontroller {/*** SpringMVC页面跳转——直接返回字符串* return*/RequestMapping(value /quick1)public String save1() {System.out.println(Usercontroller save...);return success;// 等同于return /user/success.jsp;}/*** SpringMVC页面跳转——返回ModelAndView对象 方式一* return*/RequestMapping(/quick2)public ModelAndView save2() {/*Model模型 用来封装数据View视图 用来展示数据*/ModelAndView mv new ModelAndView();// 设置模型数据mv.addObject(username, zhangsan);// 设置视图名称mv.setViewName(success);return mv;}/*** SpringMVC页面跳转——返回ModelAndView对象 方式二* return*/RequestMapping(/quick3)public ModelAndView save3(ModelAndView mv) {/*Model模型 用来封装数据View视图 用来展示数据*/// 设置模型数据mv.addObject(username, zhangsan);// 设置视图名称mv.setViewName(success);return mv;}/*** SpringMVC页面跳转——返回ModelAndView对象 方式三* return*/RequestMapping(/quick4)public String save4(Model model) {/*Model模型 用来封装数据View视图 用来展示数据*/// 设置模型数据model.addAttribute(username, zhangsan);// 返回jsp视图文件return success;}/*** SpringMVC页面跳转——返回ModelAndView对象 方式四* 方式四不常用了解知道即可* return*/RequestMapping(/quick5)public String save5(HttpServletRequest request) {/*Model模型 用来封装数据View视图 用来展示数据*/// request代替model来设置模型数据request.setAttribute(username, zhangsan);// 返回jsp视图文件return success;}
}success.jsp代码如下 注意jsp文件中使用EL表达式时要在JSP页面顶部%...%标签体内加上isELIgnoredfalse作用防止Tomcat配置禁用EL表达式 % page contentTypetext/html;charsetUTF-8 languagejava isELIgnoredfalse %
htmlheadtitleTitle/title/headbodyh1...Success Running.../h1h2${username}/h2/body
/htmlTomcat运行该Web项目后截图如下所示 注意 public ModelAndView save3(ModelAndView mv)是通过参数传入ModelAndView对象以供使用原理是 SpringMVC会自动根据方法的参数进行相应的注入以该save3为例当SpringMVC检测到其参数为ModelAndView而这个类是SpringMVC所有的此时SpringMVC框架就会自动为其提供一个ModelAndView对象以供该方法使用public String save5(HttpServletRequest request)的原理也是Spring会根据方法的参数进行相应的注入
SpringMVC回写数据
SpringMVC回写数据——直接返回字符串 在Web基础阶段客户端访问服务器端若想直接回写字符串作为响应体返回的话只需要使用response.getWriter(Hello World)方法即可而在Controller中若想直接返回字符串的方式如下 方式一 通过SpringMVC框架注入response对象即参数为response对象然后使用response对象的getWriter().print(Hello World)方法回写数据即可 注意此时不需要视图跳转且业务方法返回值为void 方式二 将需要回写的字符串直接返回但此时需要使用ResponseBody注解告知SpringMVC框架该方法返回的是字符串不是页面跳转即它是直接在http响应体中返回的字符串 ResponseBody注解作用标注该注解的方法的返回值会直接写入 HTTP 响应体中。该注解通常用于 RESTful Web 服务或 AJAX 请求处理以便返回 JSON、XML 或其他格式的数据。 总结代表不进行页面跳转直接回写数据 方式一的代码示例如下 在controller包下重现创建一个示例类UserControllerTwo代码如下 package at.guigu.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** SpringMVC回写数据*/
//将Usercontroller放到Spring容器中
Controller
RequestMapping(/userTwo)
public class UserControllerTwo {/*** SpringMVC回写数据——直接返回字符串方式一* param response* throws IOException*/RequestMapping(value /quick1)public void save(HttpServletResponse response) throws IOException {response.getWriter().print(Hello World!);}
}方式二的代码示例如下 package at.guigu.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** SpringMVC回写数据*/
//将Usercontroller放到Spring容器中
Controller
RequestMapping(/userTwo)
public class UserControllerTwo {/*** SpringMVC回写数据——直接返回字符串方式一* param response* throws IOException*/RequestMapping(value /quick1)public void save(HttpServletResponse response) throws IOException {response.getWriter().print(Hello World!);}/*** SpringMVC回写数据——直接返回字符串方式二* return*/ResponseBodyRequestMapping(value /quick2)public String save2(){return Hello World!;}
}方式二中我们一般会返回指定格式的字符串比如JSON格式代码步骤示例如下以对象转为JSON格式为例 注意将对象转换为JSON格式进行输出时我们需要借助JSON的转换工具将对象转换为JSON格式的字符串然后在返回 Step1 在pom.xml文件中导入坐标jackson-core、jackson-databind、jackson-annotations !--jackson-core--
dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-core/artifactIdversion2.17.1/version
/dependency
!--jackson-databind--
dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-databind/artifactIdversion2.17.1/version
/dependency
!--jackson-annotations--
dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-annotations/artifactIdversion2.17.1/version
/dependencyStep2 创建一个pojo包在该包下创建一个User类代码如下 package at.guigu.pojo;public class User {private String name;private int age;public User() {}public User(String name, int age) {this.name name;this.age age;}public String getName() {return name;}public void setName(String name) {this.name name;}public int getAge() {return age;}public void setAge(int age) {this.age age;}Overridepublic String toString() {return User{ name name \ , age age };}
}Step3 UserControllerTwo类代码如下 package at.guigu.controller;import at.guigu.pojo.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** SpringMVC回写数据*/
//将Usercontroller放到Spring容器中
Controller
RequestMapping(/userTwo)
public class UserControllerTwo {/*** SpringMVC回写数据——直接返回字符串方式一* param response* throws IOException*/RequestMapping(value /quick1)public void save(HttpServletResponse response) throws IOException {response.getWriter().print(Hello World!);}/*** SpringMVC回写数据——直接返回字符串方式二直接返回普通字符串数据* return*/ResponseBodyRequestMapping(value /quick2)public String save2(){return Hello World!;}/*** SpringMVC回写数据——直接返回字符串方式二返回JSON格式响应字符串数据* return* throws JsonProcessingException*/ResponseBodyRequestMapping(value /quick3)public String save3() throws JsonProcessingException {User user new User();user.setName(zhangsan);user.setAge(18);//使用JSON的转换工具将对象转换为JSON格式的字符串然后在返回ObjectMapper mapper new ObjectMapper();String json mapper.writeValueAsString(user);return json;}
}注意我们可以利用RestController注解来代替Controller和ResponseBody这两个注解 原因在类级别使用 RestController 注解就不需要在每个方法上单独使用 ResponseBody 注解。RestController 本质上是 Controller 和 ResponseBody 的组合。 此时UserControllerTwo类中方式二的代码可更改如下 package at.guigu.controller;import at.guigu.pojo.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** SpringMVC回写数据*/
//将Usercontroller放到Spring容器中
RestController
RequestMapping(/userTwo)
public class UserControllerTwo {/*** SpringMVC回写数据——直接返回字符串方式二直接返回普通字符串数据* return*/RequestMapping(value /quick2)public String save2(){return Hello World!;}/*** SpringMVC回写数据——直接返回字符串方式二返回JSON格式响应字符串数据* return* throws JsonProcessingException*/RequestMapping(value /quick3)public String save3() throws JsonProcessingException {User user new User();user.setName(zhangsan);user.setAge(18);//使用JSON的转换工具将对象转换为JSON格式的字符串然后在返回ObjectMapper mapper new ObjectMapper();String json mapper.writeValueAsString(user);return json;}
}SpringMVC回写数据——返回对象或集合 在 SpringMVC回写数据——直接返回字符串 的示例中使用JSON的转换工具将对象转换为JSON格式的字符串然后在返回这种方式每次都需要如下两句代码 ObjectMapper mapper new ObjectMapper();
String json mapper.writeValueAsString(user);这样就造成了代码冗余为避免冗余我们可对其进行优化已便于达到如下目的SpringMVC自动将对象或集合转为JSON格式的字符串 原理找到SpringMVC默认组件配置的配置文件DispatherServlet.properties可详见SpringMVC核心配置文件解析然后找到处理器适配器HandlerAdapter接口下的RequestMappingHandlerAdapter类该类下有一个public void setMessageConverters(ListHttpMessageConverter? messageConverters)方法可用来设置一个JSON转换的转换器 该类的作用处理使用 RequestMapping 注解的控制器方法。它是 HandlerAdapter 接口的一个具体实现负责调用带有 RequestMapping 注解的方法来处理 HTTP 请求。可通过SpringMVC的核心配置文件来更改配置代码及步骤可详见SpringMVC核心配置文件解析 优化步骤如下 Step1 SpringMVC核心配置文件代码如下 ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:contexthttp://www.springframework.org/schema/contextxmlns:mvchttp://www.springframework.org/schema/mvcxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd!--配置Controller层的注解的组件扫描--context:component-scan base-packageat.guigu.controller/context:component-scan!--等同于context:component-scan base-packageat.guigutype指定要扫描的内容为注解expression指定要扫描的对应注解的全限定名只扫描at.guigu包下有Controller注解的类context:include-filter typeannotation expressionorg.springframework.stereotype.Controller//context:component-scan--!--配置内部资源视图解析器--bean idviewResolver classorg.springframework.web.servlet.view.InternalResourceViewResolver!--将InternalResourceViewResolver类中的前缀属性prefix的值设为/jsp/--property nameprefix value/user//property!--将InternalResourceViewResolver类中的前缀属性suffix的值设为.jsp--property namesuffix value.jsp/property/bean!--配置处理器适配器--bean idhandlerAdapter classorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapterproperty namemessageConverterslistbean classorg.springframework.http.converter.json.MappingJackson2HttpMessageConverter//list/property/bean
/beans配置内部资源视图解析器以及处理器适配器都用到了setter方法注入只是说一个是普通数据类型注入一个是集合注入。具体注入方法解释可详见Spring完整知识点汇总一中的依赖注入 Step2 直接返回字符串方式二返回JSON格式响应字符串数据的代码更改如下 package at.guigu.controller;import at.guigu.pojo.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;//将Usercontroller放到Spring容器中
Controller
RequestMapping(/userTwo)
public class UserControllerFour {/*** SpringMVC回写数据——直接返回字符串方式二返回JSON格式响应字符串数据* return* throws JsonProcessingException*/ResponseBodyRequestMapping(value /quick3)public User save3() throws JsonProcessingException {User user new User();user.setName(zhangsan);user.setAge(18);return user;}
}除此之外还可返回集合数据代码如下 package at.guigu.controller;import at.guigu.pojo.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import java.util.ArrayList;
import java.util.List;/*** 将Usercontroller放到Spring容器中* 测试经配置后SpringMVC自动将对象或集合转为JSON格式的字符串*/
Controller
RequestMapping(/userFour)
public class UserControllerFour {/*** SpringMVC回写数据——直接返回字符串方式二返回JSON格式响应字符串数据* return* throws JsonProcessingException*/ResponseBodyRequestMapping(value /quick3)public User save3() throws JsonProcessingException {User user new User();user.setName(zhangsan);user.setAge(18);return user;}/*** SpringMVC回写数据——直接返回字符串方式二返回JSON格式响应集合数据* return* throws JsonProcessingException*/ResponseBodyRequestMapping(value /quick4)public ListUser save4() throws JsonProcessingException {User user1 new User();user1.setName(zhangsan);user1.setAge(15);User user2 new User();user2.setName(lisi);user2.setAge(12);ListUser userList new ArrayListUser();userList.add(user1);userList.add(user2);return userList;}}在SpringMVC核心配置文件中进行处理器适配器的配置还稍显麻烦我们可以在SpringMVC核心配置文件中使用mvc的注解驱动来代替对处理器适配器进行的配置 mvc的注解驱动代码mvc:annotation-driven/ 它能够自动加载处理器映射器RequestMappingHandlerMapping和处理器适配器RequestMappingHandlerAdapter并且它的底层会继承jackson进行对象或集合的JSON格式字符串的转换 此时SpringMVC的核心配置文件代码如下 注意mvc的注解驱动代码需要引入mvc的命名空间以及约束路径可详见Spring快速入门代码实现 ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:contexthttp://www.springframework.org/schema/contextxmlns:mvchttp://www.springframework.org/schema/mvcxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd!--配置Controller层的注解的组件扫描--context:component-scan base-packageat.guigu.controller/context:component-scan!--等同于context:component-scan base-packageat.guigutype指定要扫描的内容为注解expression指定要扫描的对应注解的全限定名只扫描at.guigu包下有Controller注解的类context:include-filter typeannotation expressionorg.springframework.stereotype.Controller//context:component-scan--!--配置内部资源视图解析器--bean idviewResolver classorg.springframework.web.servlet.view.InternalResourceViewResolver!--将InternalResourceViewResolver类中的前缀属性prefix的值设为/jsp/--property nameprefix value/user//property!--将InternalResourceViewResolver类中的前缀属性suffix的值设为.jsp--property namesuffix value.jsp/property/bean!--mvc的注解驱动--mvc:annotation-driven/!--等同于配置处理器适配器--!--bean idhandlerAdapter classorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapterproperty namemessageConverterslistbean classorg.springframework.http.converter.json.MappingJackson2HttpMessageConverter//list/property/bean--
/beansSpringMVC的核心配置文件对应的SpringMVC核心配置类代码如下 package at.guigu.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;// 该注解代表该类是SpringMVC的核心配置类
Configuration
// 配置注解的组件扫描context:component-scan base-packageat.guigu.controller/context:component-scan
// 加载controller对应的bean
ComponentScan(at.guigu.controller)
// 自动配置 Spring MVC 的各种特性,比如mvc的注解驱动mvc:annotation-driven/
EnableWebMvc
public class SpringMvcConfiguration {// 配置视图解析器Beanpublic InternalResourceViewResolver viewResolver() {InternalResourceViewResolver resolver new InternalResourceViewResolver();resolver.setPrefix(/user/); // 设置视图文件路径前缀resolver.setSuffix(.jsp); // 设置视图文件后缀return resolver;}
}