在上一篇文章《整合 SSM 框架必备基础 - SpringMVC(上)》中, 胖达介绍了关于 SpringMVC 的诞生, 优势以及执行流程等理论知识点, 这篇文章打算在实操中加深一下对 SpringMVC 的认识, 毕竟实践才是学习技术最有效的方法嘛, Let's Go!
一, 首先来创建一个 web 小项目吧
JDK 版本: jdk1.7.0_07
开发环境: Intellij IDEA v2018.03
首先需要在 IDEA 的项目列表页面新建一个 Web 项目, 这里 IDEA 给我们提供了众多的项目模板, 只要选择了相应的模板就可以快速新建一个项目骨架, 在这里, 我们可以首先通过一个 webapp 模板新建 Web 项目, 步骤如下:
1. 创建新项目
2. 通过 Maven 模板选择, 新建项目骨架
3. 为组织和项目新建唯一标志符
4. 选择本地或者默认的 Maven 及其版本
5. 确定项目名称以及项目新建的位置即可
6. 生成的 Web 项目目录
在上述步骤完成后, 点击 Finish, 即可成功利用模板生成了一个简易的 Web 项目骨架, 其生成的项目目录如下图所示:
二, SpringMVC 的配置要经历哪些过程呢?
1. 在 pom.xml 中配置 Maven 依赖
配置 SpringMVC 首先需要添加该框架所需的 Maven 依赖(即 jar 文件), 思考一下 SpringMVC 的运行需要哪些 jar 包的支持呢? 我们需要把这些依赖都添加到 pom.xml 文件中, 才可进行 SpringMVC 项目的构建, 下面我整理了一份, 虽然不是很全但是够用.
添加依赖之前, 首先需要在 pom.xml 中的 properties 标签属性中标记一下 Spring 的版本, 如果像我一样额外引入了 Hibernate, 顺便标记一下 Hibernate 的版本哈, 配置如下:
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <maven.compiler.source>1.7</maven.compiler.source>
- <maven.compiler.target>1.7</maven.compiler.target>
- <spring.version>4.2.6.RELEASE</spring.version>
- <hibernate.version>5.1.0.Final</hibernate.version>
- </properties>
然后在这个文件中添加 dependency 依赖, 依赖文件的配置如下:
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-core</artifactId>
- <version>4.2.5.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>4.2.5.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.data</groupId>
- <artifactId>spring-data-jpa</artifactId>
- <version>1.10.1.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.hibernate</groupId>
- <artifactId>hibernate-entitymanager</artifactId>
- <version>${hibernate.version}</version>
- </dependency>
- <dependency>
- <groupId>org.hibernate</groupId>
- <artifactId>hibernate-c3p0</artifactId>
- <version>${hibernate.version}</version>
- </dependency>
- <dependency>
- <groupId>com.mchange</groupId>
- <artifactId>c3p0</artifactId>
- <version>0.9.5.2</version>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>jstl</artifactId>
- <version>1.2</version>
- </dependency>
- <dependency>
- <groupId>MySQL</groupId>
- <artifactId>MySQL-connector-java</artifactId>
- <version>5.1.39</version>
- </dependency>
另外, 如果你 pom.xml 文件中 build 属性标签中没有关于 maven 编译打包的插件 maven-compiler-plugin 这一项, 你还需要添加一个关于它的配置, 因为没有它你的 Maven 是没办法给你编译项目源代码的, 但是如果有的话你可以自动忽略掉, 配置内容如下:
- <build>
- <finalName>springmvcdemo</finalName>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>1.8</source>
- <target>1.8</target>
- </configuration>
- </plugin>
- </plugins>
- </build>
2.Web.xml 文件的配置
对于一个 Web 项目, Web.xml 是这个项目的整体配置文件, 需要在这个文件中添加相关的一些配置, 例如 DispatcherServlet 配置, 字符集编码设置过滤器, 错误跳转页面等等, 其中 DispatcherServlet 做为框架的入口, 是使用 SpringMVC 必需的配置; encodingFilter 过滤器是为了处理请求中的中文, 防止出现乱码.
配置代码如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <Web-App>
- <display-name>Archetype Created Web Application</display-name>
- <!-- 根目录跳转 - 欢迎页面 -->
- <welcome-file-list>
- <welcome-file>index.jsp</welcome-file>
- </welcome-file-list>
- <!-- 编码过滤器 -->
- <filter>
- <filter-name>encodingFilter</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>forceEncoding</param-name>
- <param-value>true</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>encodingFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
- <!-- 错误页面跳转 -->
- <error-page>
- <!-- 路径不正确 -->
- <error-code>404</error-code>
- <location>/Web-INF/errorpage/404.jsp</location>
- </error-page>
- <error-page>
- <!-- 没有访问权限, 访问被禁止 -->
- <error-code>405</error-code>
- <location>/Web-INF/errorpage/405.jsp</location>
- </error-page>
- <error-page>
- <!-- 内部错误 -->
- <error-code>500</error-code>
- <location>/Web-INF/errorpage/500.jsp</location>
- </error-page>
- <!--SpringMVC 入口配置 -->
- <servlet>
- <servlet-name>spring-mvc</servlet-name>
- <servlet-class>org.springframework.Web.servlet.DispatcherServlet</servlet-class>
- <!-- 此处后面会有说明 -->
- <!--<init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>/WEB-INF/springmvc-servlet.xml</param-value>
- </init-param>-->
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>spring-mvc</servlet-name>
- <url-pattern>/</url-pattern>
- </servlet-mapping>
- </Web-App>
3.SpringMVC 自身 xml 文件配置
SprignMVC 自身也存在一个配置文件, 如果你的项目中不包含这个配置文件, 可以通过 IDEA 自带的方式去生成, 步骤如下图所示:
(1)在 Web-INF 根目录下点击右键
(2)点击 New 在右侧找到 xml Configuration File
(3)点击后找到 Spring Config
(4)为 xml 配置文件命名, 例如: XXX-servlet.xml 即可, 命名时需要注意 SpringMVC 会默认去找 / Web-INF/XXX-servlet.xml 这个 xml, 其中 XXX 是上述 Web.xml 中所配置的 servlet-name 名称, 如果不想用这个作为配置文件的名称, 且不想用 - servlet 为后缀, 就需要在 Web.xml 中配置 contextConfigLocation 来指定文件路径, 例如:
- <!--SpringMVC 入口配置 -->
- <servlet>
- <servlet-name>spring-mvc</servlet-name>
- <servlet-class>org.springframework.Web.servlet.DispatcherServlet</servlet-class>
- <!-- 此处就必须添加了 -->
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>/Web-INF/springmvc-servlet.xml</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>spring-mvc</servlet-name>
- <url-pattern>/</url-pattern>
- </servlet-mapping>
新建了配置文件, IDEA 并不会默认生成所有配置, 我们最终还是看到一个空空的 xml 文件, 需要对其配置进行手动添加, 添加之前首先搞清楚这个配置文件到底能有啥用途呢?
(1)配置自动扫描的包路径, 通过这项配置, 自动扫描某个包下的 Controller 控制器, 方便管理 Bean, 并在请求的时候快速定位 Controller 并访问.
(2)注解映射支持配置即注解开关, 只有配置了这一项, 注解才能有效果.
(3)配置视图解析器, 通过视图解析器可以给请求页面添加前缀和后缀, 而不用每次 SpringMVC 返回视图的时候再去单独指定前缀, 后缀, 例如:
- <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
- <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
- <property name="prefix" value="/WEB-INF/pages/"/>
- <property name="suffix" value=".jsp"/>
- </bean>
(4)配置静态资源文件的访问, 如果 DispatcherServlet 拦截了所有的请求, 同时对. JS,.jpg 的访问也会被拦截, 导致运行时跳转后的页面无法加载静态资源文件, 这时需要对静态资源文件的访问进行配置.
(5)配置上传文件数据解析器, 方便管理上传数据的信息, 包括文件的格式, 最大最小数据量等等, 例如:
- <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
- <property name="maxUploadSize" value="10485760"/>
- <property name="defaultEncoding" value="UTF-8"/>
- </bean>
(6)配置全局异常处理器, 针对异常处理做统一的处理和维护, 并对一些特殊异常做特殊处理, 例如:
- <!-- 全局异常处理器, 实现 HandlerExceptionResolver 接口就是全局异常处理器 -->
- <bean class="com.eurasia.exception.CustomExceptionResolver">
- </bean>
(7)自定义参数类型绑定, SpringMVC 框架可以实现传参到 Controller 请求方法中返回视图和参数的功能, 在 Controller 中可以完成对于参数的处理, 例如你的参数是一个实体类, 其中的某个字段需要转换为 Date, 这时可以通过配置自定义转换器来实现参数转换, 例如:
- <bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper">
- <property name="dateFormat">
- <bean class="java.text.SimpleDateFormat">
- <constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />
- </bean>
- </property>
- </bean>
明确了这些用途, 在来看看文件中应该如何具体的进行配置, 配置内容如下(上述某些用途的配置在当前小项目中没有用到, 所以未提供相关配置):
- <?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"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- 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">
- <!-- 指明 controller 所在包, 并扫描其中的注解 -->
- <context:component-scan base-package="hello"/>
- <!-- 静态资源 (js,image 等) 的访问 -->
- <mvc:default-servlet-handler/>
- <!-- 开启注解 -->
- <mvc:annotation-driven/>
- <!--ViewResolver 视图解析器 -->
- <!-- 用于支持 Servlet,JSP 视图解析 -->
- <bean id="jspViewResolver"
- class="org.springframework.web.servlet.view.UrlBasedViewResolver"
- <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
- <property name="prefix" value="/WEB-INF/pages/"/>
- <property name="suffix" value=".jsp"/>
- </bean>
- </beans>
注意: 如果你生成的配置文件在加入这些标签时报错, 记得检查你的 xmlns:mvc 和 xmlns:context 头信息, 把它们补全即可
4. 创建我们的 Controller 控制器
在 src/main 目录下新建包名, 例如 com.hello 这样, 然后在下面新建一个 java 文件 HiController.java, 这个就是我们新建的第一个 Contrller 控制器, 通过这个控制器, 就可以向前台传递 ModelAndView, 当然你也可以指定 view 路径最终呈现给用户一个展示的界面.
前面我们已经启用了 SpringMVC 提供的注解功能, 那我们在这里就可以直接用注解来注释我们的控制器, 这样才能识别到这个控制器, 代码呈上:
- @Controller
- @RequestMapping("/hello")
- public class HiController {
- /**
- * 测试返回指定的 view 文件名
- * @return
- */
- @RequestMapping("/welcome")
- public String helloWorld() {
- return "welcome";
- }
- /**
- * 测试返回带有数据的 ModelAndView 对象
- * @return
- */
- @RequestMapping("/view")
- public ModelAndView getView() {
- String message = "<br><div style='text-align:center;'>"
- + "<h3 > 我叫胖达, 来自 HiController.java(公众号: Java 知识共享)</h3>";
- return new ModelAndView("welcome", "message", message);
- }
- }
这里 Controller 最终是要向前台的界面返回数据或者调起某个界面的, 所以必须在前台也要指定一个页面, 我在 webapp 下的 Web-INF 中创建了一个 pages 文件夹专门存放前台的页面, 这里暂时先放一个 welcome.jsp 页面, 给大家打个招呼, 页面内容如下:
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <HTML>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>
- Insert title here
- </title>
- </head>
- <body>
- Hi! ${message}
- </body>
- </HTML>
根据前台和后台的这两段代码, 看懂的小伙伴应该知道了我的演示效果, 等我启动起来项目再展示哈.
5. 配置 Tomcat, 启动小项目
我已经迫不及待的要启动我的项目了, IDEA 中配置 tomcat 的步骤其实很简单, 如果你 pom.xml 中引入 maven-tomcat 插件, 可能会更简单, 这里我用传统外部 tomcat 的方式吧.
首先点击右上角的 edit Configurations 按钮:
这样就打开了 run/debug Configurations 窗口, 在这个窗口继续操作如下:
特别注意: 第四个步骤是为了选择本地的 tomcat 路径哈, 直接选择自己的外部 tomcat, 选择根路径即可.
然后还有一步就是需要选择 tomcat 启动的时候需要 Deployment 也就是要发布的应用, 按照下述步骤 1-6 即可:
到此, tomcat 配置成功, 直接点击右上角, 启动我们的小项目即可.
由于前面配置了欢迎界面, 当系统启动成功后我会自动访问 index.jsp 欢迎页面, 并成功展示 HelloWorld 字样, 接下来我们要依次访问一下我们控制器中写的两个方法:
第一个方法
访问路径:
http://localhost:8088/SpringMVCStarter/hello/welcome
访问结果:
结论: 在上面后端的代码中会发现, 我只是指定了一个 view 的路径 welcome, 结果会自动跳转出 welcome.jsp 的原有内容, 说明我们的调用成功了
第二个方法
访问路径:
http://localhost:8088/SpringMVCStarter/hello/view
访问结果:
结论: 与第一个不同的是, 这个方法会跳转同一个界面 welcome.jsp, 但是后台我返回的是 ModelAndView 对象, 这样的话, 后台会将数据和视图经过渲染后一并呈现给用户, 如上图黑色字体为后台传递到前台的数据.
三, SpringMVC 的几种注解
提及 SpringMVC, 不得不顺便啰嗦一下它的注解, 确实非常好用, 常用的几个重要注解如下:
1.Controller
这个可以说是最重要的一个注解了, 主要用于标识是 Controller 处理器类. 表示把我的控制器对象交给 Spring 来创建.
2.RequestMapping
请求映射的注解, 也就是标记请求路径名的重要注解, 就比如我们小项目中的 hello 和 welcome 用法, 当然还有指定其他参数的用法, 例如请求方式是 post 还是 get, 都可以在这个注解中标明.
3.RequestParam
这个注解的功能主要是给参数设置默认值, 或者给参数定义别名, 只要别名和页面传递参数匹配即可传递成功, 例如:
@RequestParam(defaultValue="1",value="myid")
它的配置项主要包含:
(1) value: 参数名字, 即入参的请求参数名字, 如 value="studentid" 表示请求的参数区中的名字为 studentid 的参数的值将传入;
(2) required: 是否必须, 默认是 true, 表示请求中一定要有相应的参数, 否则将报 400 错误码;
(3) defaultValue: 默认值, 表示如果请求中没有同名参数时的默认值
4.Redirect
通过这个注解, Contrller 方法返回结果重定向到一个 url 地址, 例如 redirect:/user/add.do 即可跳转到这个 add.do 指定的相应页面.
5.Forward
利用这个注解, Controller 方法执行后还会继续执行另一个 controller 方法, 例如 return "forward:/user/userlist.do";, 就会去执行其他的 userlist 这个方法
6.RequestBody/ResponseBody
如果要用到 JSON 传递数据, 那这个注解是非常重要的, 其实也是日常开发必须的一个注解.
其中 @RequestBody 注解用于读取 http 请求的内容(字符串), 通过 springmvc 提供的 HttpMessageConverter 接口将读到的内容转换为 JSON,xml 等格式的数据并绑定到 controller 方法的参数上.
@RequestBody 注解实现接收 http 请求的 JSON 数据, 将 JSON 数据转换为 java 对象, 但是 @RequestBody/@ResponseBody 一般要依赖 Jackson 使用.
四, 总结
关于 SpringMVC 的整个访问流程在上篇文章中简单介绍了一下, 这篇文章也通过搭建流程, 创建配置文件的方式做了一个简单的介绍, 假想我们从访问一个 Controller 控制器的 url 出发, 首先通过 Web.xml 中的入口 DispatchServlet 进入了 SpringMVC 这个框架的流程, 再通过框架内的 HandlerMapping,HandlerAdapter 找到我们提前通过注解注入的 Controller 方法, 执行完成后返回带着数据的 ModelAndView 对象, 在通过我们配置的 ViewResolver 给我们 view 路径添加上前缀后缀, 最终做一些数据和视图的渲染工作, 就可以将一个期待的效果页面展现给我们了, 这个过程是不是很清晰? 其实虽然写了那么多, 但是对于 SpringMVC 内部的处理情况还是有一点点疑问, 以后有机会我会带着疑问跟大家一起去撸一遍源码, 或许通过源码才能更加深入的了解到 SpringMVC 这个神奇的框架, 期待 ING!!!
来源: https://www.cnblogs.com/panda001/p/11247569.html