Spring MVC(一)

1 Spring MVC概述

        我们在之前学习Servlet的时候,认识了在WEB开发中MVC设计模式,其最为经典的设计就是,通过控制器(Controller)分离模型(Model)和视图(View)。在具体的WEB开发中,我们实现最多的功能就是页面的跳转和参数的传递。每次在使用Servlet进行操作的时候,都要手动的控制页面的跳转,开发效率非常低,虽然也可以使用一定的代码封装(BaseServlet),来简化操作,但是参数的传递只能频繁的使用getParameter方法来处理。鉴于以上问题,逐渐出现了一些自动化的MVC框架,其中Spring MVC就是目前非常优秀的MVC框架之一。

        Spring MVC属于Spring Frame Work的后续产品,现已归属为Spring Web Flow里,Spring MVC是对传统的Servlet进行了一系列的封装。Spring MVC 分离了控制器、模型对象、过滤器以及处理程序对象的角色,这种分离让它们更容易进行定制。因此,在使用Spring MVC进行程序设计的时候,往往只需要编写少量的代码,就可以达到Servlet中复杂的实现。

        Spring MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,使用了MVC架构模式的思想,将Web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发。

        既然Spring MVC属于Spring的一部分,当然可以实现Spring到Spring MVC的无缝对接。在开发的时候,我们可以利用Spring的IOC容器来管理SpringMVC中所有的控制器,一个普通的POJO就可以被当做一个控制器来使用。Spring MVC提供了一个强大的中央控制器,我们可以通过该中央控制器轻松的实现页面跳转,同时可以利用Spring的注解,很方便的实现参数的传递。

2 Spring MVC项目环境搭建

        既然Spring MVC是一个MVC框架,在开发的时候同样也需要导入相关的jar包。开发最基本的Spring MVC程序,需要导入的jar包有:

commons-logging-1.2.jar

spring-aop-4.3.9.RELEASE.jar

spring-beans-4.3.9.RELEASE.jar

spring-context-4.3.9.RELEASE.jar

spring-core-4.3.9.RELEASE.jar

spring-expression-4.3.9.RELEASE.jar

spring-web-4.3.9.RELEASE.jar

spring-webmvc-4.3.9.RELEASE.jar

        创建一个web项目,我们暂时把项目名称命名为springmvc,然后拷贝上述jar包到项目的WebRoot/WEB-INF/lib目录中。项目的结构图如图所示。

        上一节说过Spring MVC具有一个中央控制器,我们可以通过Spring MVC的中央控制器来轻松的完成对页面跳转和参数传递的控制。中央控制器如何才能得到利用呢,接下来需要在web.xml添加相应的配置,代码如下。

<servlet><servlet-name>dispatcher</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping>

        其中的<load-on-startup>配置的值为1,在学习Servlet的时候,我们知道,此处的配置意为在服务启动以后,立即加载该Servlet对象,因为Spring MVC中央控制器需要优先启动。其中的<url-pattern>配置的值为/,这样是为了拦截所有的URL请求。

        在Spring MVC中,被中央控制器拦截的请求,全部交由一个统一的处理文件中,这个文件的位置必须在项目的WebRoot/WEB-INF目录下,名字必须是dispatcher-servlet.xml,因为我们在配置中央控制其的时候,指定的servlet-name是dispatcher,所以名字必须以servlet-name配置的名字开头。

        其实,配置文件的名字和位置也是可以更改的,在web.xml文件中配置DispatcherServlet的时候,在其中的<servlet>配置中添加如下内容。

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

        这样一来,我们就可以在项目的src目录下创建配置文件了,文件的名字就可以指定为springmvc.xml。不过,在具体的开发过程中一般都是使用的默认值,也就是在WEB-INF目录下创建配置文件。

        在WEN-INF目录下创建dispatcher-servlet.xml配置文件,并添加如下内容。

<?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:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://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/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd"></beans>

        通过之前Spring的学习,我们可以看到,其中的内容非常类似Spring的配置文件,这也意味着同样可以使用Spring IOC容器来管理对象。但是,在Spring MVC中管理的对象就是所有的控制器。接下来创建一个控制器HelloController,并编写以下代码。

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;@Controller
public class HelloController extends AbstractController {@Overrideprotected ModelAndView handleRequestInternal(HttpServletRequest request,HttpServletResponse response) throws Exception {System.out.println("Hello SpringMVC!!!");return new ModelAndView("/WEB-INF/jsp/hello.jsp");}
}

        创建的控制器类HelloController继承了一个抽象类AbstractController,其实在Spring MVC中,所有的控制器完全可以不用继承任何类,这个在接下来的章节中会重点讲述,在此,先按照这种方式创建。

        其实AbstractController类我们可以当做在创建Servlet的时候继承的HttpServlet。其中的handleRequestInternal方法我们可以当做Servlet中的doGet或者doPost方法,也就是所这个方法肯定会被自动调用。在方法中我们可以看到,传递了两个参数,这正是我们熟悉的HttpServletRequest对象和HttpServletResponse对象,这也就说明了我们编写的这个控制器,其根本也就是一个Servlet。handleRequestInternal方法的返回类型是ModelAndView,返回了一个ModelAndView对象,其中的参数为“/WEB-INF/jsp/hello.jsp”,这正是我们熟悉的页面跳转,也就是返回的页面。此时我们应该在项目的WEB-INF目录下创建一个目录jsp,在其中创建一个hello.jsp文件,在<body>标签中添加相应的代码,具体内容如下。

<body>
<br><h1 align="center">Hello Spring MVC</h1><br><hr>
</body>

        既然创建了一个控制器,这个控制器如何被Spring MVC所管理呢?之前提到过,Spring MVC可以使用Spring IOC容器来管理对象,我们就可以利用在dispatcher-servlet.xml文件中添加配置,代码如下。

<bean id="/hello" class="com.tedu.controller.HelloController" />

        注意:此时配置的id的值为“/hello”,这就是访问HelloController控制器的URL地址。把该项目部署到Tomcat中,启动服务就可以访问了。

        在浏览其中输入地址http://localhost:8080/springmvc/hello 就可以访问项目了,具体的结果如图所示。

3 Spring MVC项目过程分析

        Spring MVC项目执行的大致过程为:通过在浏览器中输入一个地址,首先这个地址请求资源的URL(在本例中就是/hello),会被在web.xml中配置的中央控制器拦截,然后交由dispatcher-servlet.xml文件处理,接下来会在该配置文件中查找id值为“/hello”的<bean>,然后到达指定控制器类,根据handleRequestInternal方法返回对象的参数,寻找到指定的视图页面。大致的执行过程,可以归纳为如图所示。

4 Spring MVC项目改进

        在学习Spring的时候,我们在配置Spring IOC容器来管理对象的时候,推荐使用的是基于注解的操作,Spring MVC又是如何通过注解来操作呢?接下来把刚才的项目通过注解的形式重新改进一下,首先在dispatcher-servlet.xml文件中删除刚才的<bean>配置,并添加如下新的配置,以实现基于注解的操作。

<!-- 打开基于注解的操作 -->
<mvc:annotation-driven />
<!-- 到哪些包下扫描controller -->
<context:component-scan base-package="com.tedu.controller" />

        此时的控制器HelloController就不需要再继承AbstractController类了,控制器HelloController要被Spring IOC容器管理,只需要在类上添加注解@Controller,通过Spring IOC容器来管理控制器,同时请求的地址可以在方法上通过注解@RequestMapping("/hello")来指定,具体的代码如下所示。

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class HelloController {@RequestMapping("/hello")public String hello() {System.out.println("Hello SpringMVC!!!");return "/WEB-INF/jsp/hello.jsp";}
}

        通过以上操作,简化了控制器类的编写,控制器类可以不用继承任何类,也不用实现任何接口,就是一个POJO,却能到达同样的效果。

        在本例中,控制器的操作方法返回的页面地址有点过于复杂,能不能通过简单的操作优化一下呢?接下来在dispatcher-servlet.xml文件添加如下配置。

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!-- 配置前缀和后缀映射 --><property name="prefix" value="/WEB-INF/jsp/"></property><property name="suffix" value=".jsp"></property>
</bean>

        通过配置bean在Spring IOC容器中管理了InternalResourceViewResolver类的对象,用来对控制器类返回的URL地址进行重新编辑。在该类的父类中有一些属性,其中有“prefix”和“suffix”,分别对应返回URL的前缀和后缀。通过<property>标签完成了对前缀和和后缀值的注入,当执行控制器中的方法后,会根据方法的返回值加上前缀和后缀,组成一个完整的URL地址。

        因此方法的返回值就可以简化为“hello”,dispatcher-servlet.xml配置文件会自动为其加上前缀“/WEB-INF/jsp/”和后缀“.jsp”,然后组成完整的返回地址。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/702538.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

conan2 基础入门(04)-指定编译器(gcc为例)

conan2 基础入门(04)-指定编译器(gcc为例) 文章目录 conan2 基础入门(04)-指定编译器(gcc为例)⭐准备生成profile文件预备文件和Code ⭐使用指令预览正确执行结果可能出现的问题 ⭐具体讲解conancmake ENDsettings.yml ⭐准备 生成profile文件 # 生成默认profile文件&#xf…

《一文带你了解》关于ITSS认证-IT服务工程师、IT项目经理

“IT 服务工程师培训”和“IT 服务项目经理培训”为中国电子技术标准化研究院推出的 ITSS 系列培训&#xff0c;通过该培训的人员可系统掌握 IT 运维的知识&#xff0c; 提升项目管理水平&#xff0c;有效满足 GB/T 28827.1 的符合性评估要求。 我要充电学习提升自我&#xff0…

怎么看电脑是固态还是机械硬盘?数据丢失怎么办

在数字化时代&#xff0c;电脑硬盘作为数据存储的核心部件&#xff0c;其类型直接关系到数据读写速度和存储效率。固态硬盘&#xff08;SSD&#xff09;与机械硬盘&#xff08;HDD&#xff09;作为目前市场上主流的两种硬盘类型&#xff0c;各有其优缺点。然而&#xff0c;对于…

Find My OBD|苹果Find My技术与OBD结合,智能防丢,全球定位

OBD是英文On-Board Diagnostics的缩写&#xff0c;中文翻译为“车载自动诊断系统”。这个系统将从发动机的运行状况随时监控汽车是否尾气超标&#xff0c;一旦超标&#xff0c;会马上发出警示。当系统出现故障时&#xff0c;故障(MIL)灯或检查发动机(Check Engine)警告灯亮&…

react18【系列实用教程】react-router-dom —— 路由管理 (2024最新版)

类似 vue-router 安装 npm i react-router-domreact-router 中包含 native 的开发&#xff0c;仅网站开发&#xff0c;使用更轻量的 react-router-dom 即可 路由模式 history 模式需要后端支持&#xff0c;使用 createBrowserRouter 函数实现hash 模式无需后端支持&#xff0c;…

从新手到高手,教你如何改造你的广告思维方式!

想要广告震撼人心又让人长时间记住&#xff1f;答案肯定是“创意”二字。广告创意&#xff0c;说白了就是脑洞大开&#xff0c;想法新颖。那些很流行的广告&#xff0c;都是因为背后的想法特别、新颖。做广告啊&#xff0c;就得不停地思考&#xff0c;创新思维是关键。 广告思…

【python数据预处理系列】使用Pandas的factorize()函数进行类别编码(整数编码)

在Pandas中&#xff0c;factorize()函数主要用于将分类变量转换为整数编码&#xff0c;这对于减少内存使用或准备数据进行某些统计分析非常有用。 它实际上是将列的唯一值映射到从0开始的整数序列上。 假设有一个DataFrame&#xff0c;其中一列包含一些类别值&#xff0c;你希望…

vue 文本中的\n 、<br>换行显示

一、背景&#xff1a; 后端接口返回数据以\n 作为换行符&#xff0c;前端显示时候需要换行显示&#xff1b; demo&#xff1a; <p style"white-space: pre-wrap;">{{ info }}</p>data() {return {info: 1、优化图片\n 2、 优化时间\n}},项目上&#…

百度文心一言 java 支持流式输出,Springboot+ sse的demo

参考&#xff1a;GitHub - mmciel/wenxin-api-java: 百度文心一言Java库&#xff0c;支持问答和对话&#xff0c;支持流式输出和同步输出。提供SpringBoot调用样例。提供拓展能力。 1、依赖 <dependency> <groupId>com.baidu.aip</groupId> <artifactId…

品牌银饰售卖|基于SSM+vue的品牌银饰售卖平台的设计与实现(源码+数据库+文档)

品牌银饰售卖平台 目录 基于SSM&#xff0b;vue的品牌银饰售卖平台的设计与实现 一、前言 二、系统设计 三、系统功能设计 1前台功能模块 2后台功能模块 5.2.1管理员功能模块 5.2.2用户功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题…

ansible——playbook

一、playbook定义 Ansible Playbook是设定自动化任务的一种蓝图&#xff0c;可在无需人工干预或有限干预的前提下执行复杂的IT操作。Ansible Playbook对一组或一类共同构成 Ansible 清单的主机执行。 Ansible Playbook本质上是一些框架&#xff0c;是一些预先编写的代码&#x…

Linux —— 线程控制

Linux —— 线程控制 创建多个线程线程的优缺点优点缺点 pthread_self进程和线程的关系pthread_exit 线程等待pthread_ join线程的返回值线程分离pthread_detach 线程取消pthread_cancel pthread_t 的理解 我们今天接着来学习线程&#xff1a; 创建多个线程 我们可以结合以前…