• 我的SSH之旅 (2) : 第一个SpringMVC程序


    介绍:

    第一个单机程序一般都是HelloWorld, 作为第一个Web应用程序, 当然不能像HelloWorld那样简单了. 但是笔者仍然会带领大家完成一个尽可能简单, 同时能够展现SpringMVC最基本原理的"HelloWorld"程序.

    该演示程序为一个登录程序, 包含一个登录页面以及登录成功的页面. 仅此而已, 不涉及任何与SpringMVC无关的知识.

    笔者使用Maven构建整个应用, 并使用Jetty部署测试. 关于开发环境的搭建见笔者发的上一篇日志

    程序结构:

    简要介绍一下SpringMVC的体系结构(部分文字摘自Spring3.x企业应用开发实战) .

    1. 整个过程始于客户端发出一个HTTP请求, Web应用服务器接收到这个请求, 如果匹配DispatcherServlet的请求映射路径(在web.xml中指定), Web容器将该请求转交给DispatcherServlet处理.

    2. DispatcherServlet接收到这个请求后, 将请求的信息(包括URL, HTTP方法, 请求报文头, 请求参数, Cookie等)及HandlerMapping看成路由控制器, 将Handler看成目标主机. 值得注意的是: SpringMVC中并没有定义一个Handler接口, 实际上任何一个Object都可以成为请求处理器.

    3. 当DispatcherServlet根据HandlerMapping得到对应当前请求的Handler后, 通过HandlerAdapter对Handler进行封装, 再以统一的适配器接口调用Handler. HandlerAdapter是SpringMVC的框架级接口, 顾名思义, HandlerAdapter是一个适配器, 它用统一的接口对各种Handler方法进行调用.

    4. 处理器完成业务逻辑的处理后将返回一个ModelAndView给DispatcherServlet, ModelAndView包含了视图逻辑名和模型数据信息.

    5. ModelAndView中包含的是"逻辑视图名"而非真正的视图对象, DispatcherServlet借由ViewResolver完成逻辑视图名到真实视图对象的解析工作.

    6. 当得到真实的视图对象View后, DispatcherServlet就使用这个View对象对ModelAndView中的模型数据进行视图渲染.

    7. 最终客户端得到的响应消息, 可能是一个普通的HTML页面, 也可能是一个XML或JSON串, 甚至是一张图片或PDF文档等不同的媒体形式.

    以上每一个步骤都包含丰富的知识点, 在本示例程序中会涉及到其最简实现, 希望读者借此获得一个感性认识, 再通过阅读Spring官方文档深刻理解SpringMVC的运行机制.

    mvc

    示例程序:

    1. 创建工程

    打开cmd, 进入一个工作目录, 笔者这里直接进入了Eclipse的workspace

    image

    键入mvn archetype:generate查看所有工程模板

    image

    经过短暂的下载, 一共列出了588个模板, 键入maven-archetype-webapp筛选出和webapp有关的模板

    筛选出了一个模板, 键入1选择该模板

    image

    选择模板的版本, 默认选好了最新版, 直接回车即可

    image

    输入GroupID, ArtifactID后, 键入Y回车, 工程就创建好了

    image

    image

    image

    2. 导入工程到Eclipse

    在Eclipse中, File—>Import—>Existing Maven Projects

    image

    点Browser选中步骤1中创建的工程目录后, 会自动把pom.xml文件找出并选中, 点击Finish即可

    image

    导入后的目录结构如下图所示

    image

    3. 编码

    这个示例程序很简单, 总共需要5个步骤

    1) 编辑pom.xml, 添加所需依赖. 由于目前还不熟悉各个Spring的jar包是用来做什么的, 索性把所有和Spring有关的jar全都添加进来.

    plugins中的两个plugin分别用来使Maven支持JDK1.6和引入Jetty容器

    具体代码如下:

    <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.maven.webapp</groupId>
    	<artifactId>webapp-spring</artifactId>
    	<packaging>war</packaging>
    	<version>1.0-SNAPSHOT</version>
    	<name>webapp-spring Maven Webapp</name>
    	<url>http://maven.apache.org</url>
    	
    	<properties>
    		<java-version>1.6</java-version>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    		<org.springframework.version>3.1.0.RELEASE</org.springframework.version>
    	</properties>
    	
    	<dependencies>
    		<!--
    			Core utilities used by other modules.
    			Define this if you use Spring Utility APIs (org.springframework.core.*/org.springframework.util.*)
    		-->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-core</artifactId>
    			<version>${org.springframework.version}</version>
    		</dependency>
    
    
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-asm</artifactId>
    			<version>${org.springframework.version}</version>
    		</dependency>
    
    
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-expression</artifactId>
    			<version>${org.springframework.version}</version>
    		</dependency>
    
    		<!--
    			Bean Factory and JavaBeans utilities (depends on spring-core)
    			Define this if you use Spring Bean APIs (org.springframework.beans.*)
    		-->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-beans</artifactId>
    			<version>${org.springframework.version}</version>
    		</dependency>
    
    		<!--
    			Aspect Oriented Programming (AOP) Framework (depends on spring-core, spring-beans)
    			Define this if you use Spring AOP APIs (org.springframework.aop.*)
    		-->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-aop</artifactId>
    			<version>${org.springframework.version}</version>
    		</dependency>
    
    		<!--
    			Application Context (depends on spring-core, spring-expression, spring-aop, spring-beans)
    			This is the central artifact for Spring's Dependency Injection Container and is generally always defined
    		-->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-context</artifactId>
    			<version>${org.springframework.version}</version>
    		</dependency>
    
    		<!--
    			Various Application Context utilities, including EhCache, JavaMail, Quartz, and Freemarker integration
    			Define this if you need any of these integrations
    		-->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-context-support</artifactId>
    			<version>${org.springframework.version}</version>
    		</dependency>
    
    		<!--
    			Transaction Management Abstraction (depends on spring-core, spring-beans, spring-aop, spring-context)
    			Define this if you use Spring Transactions or DAO Exception Hierarchy
    			(org.springframework.transaction.*/org.springframework.dao.*)
    		-->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-tx</artifactId>
    			<version>${org.springframework.version}</version>
    		</dependency>
    
    		<!--
    			JDBC Data Access Library (depends on spring-core, spring-beans, spring-context, spring-tx)
    			Define this if you use Spring's JdbcTemplate API (org.springframework.jdbc.*)
    		-->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-jdbc</artifactId>
    			<version>${org.springframework.version}</version>
    		</dependency>
    
    		<!--
    			Object-to-Relation-Mapping (ORM) integration with Hibernate, JPA, and iBatis.
    			(depends on spring-core, spring-beans, spring-context, spring-tx)
    			Define this if you need ORM (org.springframework.orm.*)
    		-->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-orm</artifactId>
    			<version>${org.springframework.version}</version>
    		</dependency>
    
    		<!--
    			Object-to-XML Mapping (OXM) abstraction and integration with JAXB, JiBX, Castor, XStream, and XML Beans.
    			(depends on spring-core, spring-beans, spring-context)
    			Define this if you need OXM (org.springframework.oxm.*)
    		-->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-oxm</artifactId>
    			<version>${org.springframework.version}</version>
    		</dependency>
    
    		<!--
    			Web application development utilities applicable to both Servlet and Portlet Environments
    			(depends on spring-core, spring-beans, spring-context)
    			Define this if you use Spring MVC, or wish to use Struts, JSF, or another web framework with Spring (org.springframework.web.*)
    		-->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-web</artifactId>
    			<version>${org.springframework.version}</version>
    		</dependency>
    
    		<!--
    			Spring MVC for Servlet Environments (depends on spring-core, spring-beans, spring-context, spring-web)
    			Define this if you use Spring MVC with a Servlet Container such as Apache Tomcat (org.springframework.web.servlet.*)
    		-->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-webmvc</artifactId>
    			<version>${org.springframework.version}</version>
    		</dependency>
    
    
    		<!--
    			Support for testing Spring applications with tools such as JUnit and TestNG
    			This artifact is generally always defined with a 'test' scope for the integration testing framework and unit testing stubs
    		-->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-test</artifactId>
    			<version>${org.springframework.version}</version>
    			<scope>test</scope>
    		</dependency>
    	</dependencies>
    	<build>
    		<plugins>
    			<plugin>
    				<artifactId>maven-compiler-plugin</artifactId>
    				<inherited>true</inherited>
    				<configuration>
    					<source>1.6</source>
    					<target>1.6</target>
    					<debug>true</debug>
    				</configuration>
    			</plugin>
    			<plugin>
    				<groupId>org.mortbay.jetty</groupId>
    				<artifactId>jetty-maven-plugin</artifactId>
    			</plugin>
    		</plugins>
    		<finalName>webapp-spring</finalName>
    	</build>
    </project>
    

    2) 配置web.xml, 定义DispatcherServlet (对应前文程序结构1)

    这里主要是定义Servlet, 拦截所有.html后缀的请求, 具体代码如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    		  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    	version="3.0">
    	
    	<servlet>
    		<servlet-name>springmvc</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    
    	<servlet-mapping>
    		<servlet-name>springmvc</servlet-name>
    		<url-pattern>*.html</url-pattern>
    	</servlet-mapping>
    </web-app>

    3) 编写处理请求的控制器(对应前文程序结构234)

    由于Maven结构的工程要求所有代码都放在src/main/java这个文件夹下, 所有右键选中我们的工程, 选择New—>Other—>SourceFolder

    Folder name输入src/main/java

    image

    image

    在src/main/java上右键, New—>Other—>Package建立一个包, 包名为com.myssh.web

    image

    image

    在包com.myssh.web上右键, New—>Other—>Class新建一个类, 类名为LoginController

    image

    这个类就是处理请求的类, 给该类添加@Controller注释, 该类就成为了控制器.

    为类和方法添加@RequestMapping注释, 用于映射请求路径, 例如这里给类添加/user映射, Login方法添加/login.html映射, 在请求时浏览器地址栏中输入http://localhost:8080/user/login.html即调用Login方法处理请求;

    方法入参使用@RequestParam注释标注, 在用Get方式请求时使用http://localhost:8080/user/login.html?userID=Hello形式传入参数到Login方法;

    方法返回值为ModelAndView类型, 该类型封装了视图和数据, 即MVC中的MV;

    返回的视图名为loginSuccess, 数据为userID.

    具体代码如下

    package com.myssh.web;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.servlet.ModelAndView;
    
    @Controller
    @RequestMapping(value = "/user")
    public class LoginController {
    
    	@RequestMapping(value = "/login.html")
    	public ModelAndView Login(@RequestParam("userID") String userID) {
    		ModelAndView mav = new ModelAndView();
    		mav.setViewName("loginSuccess");
    		mav.addObject("userID", userID);
    		return mav;
    	}
    }
    

    4) 编写视图对象, 这里使用jsp页面作为视图

    首先是欢迎页面, 也就是webapp文件夹下的index.jsp.

    在该页面中添加一个输入框和一个登录按钮, 具体代码如下:

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core"%>
    <html>
    <body>
    <h2>Hello World! Maven!</h2>
    <form action="<c:url value="user/login.html"/>">
    <input type="text" name="userID"/>
    <input type="submit" value="submit"/>
    </form>
    </body>
    </html>

    然后创建登录成功页面.

    在WEB-INF下建立一个jsp文件夹用于存放所有jsp页面, 右键选择WEB-INF, New—>Other—>Folder新建文件夹, 文件夹名为jsp

    image

    image

    右键选择jsp文件夹, New—>Other—>JSP File, 新建jsp文件, 文件名为loginSuccess.jsp

    image

    该页面仅包含一行文字, 使用jsp标签绑定名为userID的属性, 具体代码如下:

    <%@ 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=ISO-8859-1">
    <title>Insert title here</title>
    </head>
    <body>
    	<p>Login Success!${userID}</p>
    </body>
    </html>

    5) 配置SpringMVC配置文件, 使控制器, 视图解析器生效

    由于我们在步骤2中配置了一个名为springmvc的servlet, 按照Spring的约定, Spring会自动从WEB-INF目录下读取名为springmvc-servlet.xml的文件使SpringMVC生效.

    于是在WEB-INF目录下新建一个名为springmvc-servlet.xml的xml文件.

    image

    编辑该文件内容如下:

    <?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-3.0.xsd
             http://www.springframework.org/schema/context
             http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    	<context:component-scan base-package="com.myssh.web" />
    	<bean id="jspViewResolver"
    		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    		<property name="prefix" value="/WEB-INF/jsp/" />
    		<property name="suffix" value=".jsp" />
    	</bean>
    </beans>
     

    context:component-scan表示扫描名为com.myssh.web的包, 使注释生效;

    还记得控制器返回值返回的视图名吗? 当时只是设置为loginSuccess这个字符串而已, 那么SpringMVC是如何通过这个字符串找到对应的视图呢, 答案是通过视图解析器(对应前文程序结构6).

    创建一个org.springframework.web.servlet.view.InternalResourceViewResolver类型的bean, 这个bean就是视图解析器.

    设置好前缀和后缀, 视图解析器会使用字符串拼接的方式获取视图的全路径.

    至此, 该演示程序编写完毕, 接着就是部署运行了.

    借助jetty-maven-plugin的便捷, 仅需一行命令就可完成Web应用的构建和部署.

    4. 部署

    打开cmd, 进入工程所在目录

    image

    键入mvn jetty:run

    成功后出现Started Jetty Server

    image

    打开浏览器, 地址栏输入http://localhost:8080/

    会出现如下页面

    在文字输入框内随意输入一个名字

    image

    点击submit

    image

    会转到登录成功页面, 注意地址栏, 请读者思考里边每个字段的具体含义.

    小结

    这篇文章手把手带着大家完成了一个最简单的SpringMVC程序, 但是麻雀虽小五脏俱全. 读者应该从中学会使用Maven创建工程, SpringMVC的处理流程, web.xml的配置方法, SpringMVC配置文件的作用, 处理请求控制器对参数的传递.

    下一篇会完成一个稍复杂的登录程序, 包含了Spring的IoC, AOP, Hibernate事物等.

  • 相关阅读:
    Python 操作 MySQL 的5种方式
    ffiddler抓取手机(app)https包
    Git远程操作详解(clone、remote、fetch、pull、push)
    Mysql学生课程表SQL面试集合
    Python获取list中指定元素的索引
    python找出字典中value最大值的几种方法
    python sort、sorted高级排序技巧
    JMeter之BeanShell常用内置对象
    Docker从容器拷贝文件到宿主机或从宿主机拷贝文件到容器
    编程必备基础知识|计算机组成原理篇(10):输入输出设备
  • 原文地址:https://www.cnblogs.com/talexu/p/2497245.html
Copyright © 2020-2023  润新知