第3章
Java Web开发
随着网络技术的飞速发展,Web程序应用领域越来越多,涵盖各种社交、电子商务、网上银行等。Java语言具有跨多平台、可移植性高的优点,通过不断优化,使得其非常适合Web应用的开发。本章将介绍Web程序开发过程中应该掌握的各种关键技术,包括开发环境搭建、MySQL数据库技术、Spring和MyBatis框架等内容。通过本章的学习,读者及相关开发者应能掌握Java Web应用的各个关键开发技术。
3.1Java Web开发环境的搭建
开发环境的搭建是Java Web应用开发的基础,包括安装Java开发工具包JDK、Web服务器(Tomcat)、数据库和IDE开发工具(IntelliJ IDEA),下面将介绍在IDE开发工具中如何配置Web服务器,最后介绍简单Web项目的发布及运行。
3.1.1Java Tomcat安装
首先介绍Web服务器(Tomcat)的安装。Tomcat服务器是Apache软件基金会(Apache Software Foundation)的Jakarta项目组的产品,目前Tomcat最新版本为10.0.2,同时它能支持Servlet和JSP规范。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java爱好者的喜爱并得到了软件开发商的认可,成为目前比较流行的Web应用服务器。本节将介绍Tomcat服务器的安装与配置。
本书使用Tomcat 10.0.2版本,读者可自行去Apache官网下载最新版本。下面将介绍Tomcat 10.0.2的具体下载及安装步骤。
官网网址为http://tomcat.apache.org/,其首页如图31所示。
图31Apache官方网站
左侧Download栏有各种版本供下载,单击Tomcat 10超链接,进入Tomcat 10下载页面,如图32所示。在图32中,包含了Tomcat服务器安装文件的不同平台的不同版本。本书以Windows 10 64位系统为例,选择“64bit Windows zip (pgp
, sha512)”超链接进行下载。下载完成后,得到一个zip格式压缩包,将其解压后即可使用。
单击文件夹bin下的startup.bat图标,即可启动Tomcat,如图33所示。单击shutdown.bat图标,即可关闭Tomcat。
图32Tomcat下载链接
图33启动Tomcat
安装完成后,还需进行Tomcat环境变量配置,整个步骤如下: 右击“我的电脑”,单击“属性”命令,选择“高级系统设置”→“环境变量”,如图34所示。
图34Tomcat环境变量配置
在“系统变量”中添加系统变量CATALINA_BASE和CATALINA_HOME; 对应的变量值都是Tomcat的安装路径(本例中为D:\apachetomcat10.0.2),如图35所示。
图35系统变量CATALINA_BASE和CATALINA_HOME设置
此处还需修改Path的变量值。选中Path变量,单击“编辑”按钮,变量名为Path,在变量值的原有值后面填入“;%CATALINA_HOME%\bin; %CATALINA_HOME%\lib”,如图36所示。
图36系统变量Path设置
最后需要验证配置是否成功。选择“开始”→“运行”,输入cmd(或按快捷键Win+R),输入命令: startup,若出现如图37所示信息,则说明环境变量配置成功。
图37Tomcat环境变量配置成功
此外,在网页端输入地址http://localhost:8080/,若打开页面如图38所示,则说明安装Web服务器成功。
图38Tomcat安装验证
3.1.2在IntelliJ IDEA中配置Tomcat
接下来将介绍如何在IDE开发工具中配置Tomcat。进行Java Web开发,可选择常用的IDE开发工具IntelliJ IDEA。IntelliJ IDEA的下载及安装详见本书第1章。需要注意的是,IntelliJ IDEA旗舰版才可以进行Tomcat服务器的配置,而IntelliJ IDEA社区版没有此项功能。
首先启动IntelliJ IDEA,在菜单栏单击Run→Edit Configurations,如图39所示。
在弹出的Configurations对话框中,单击左侧“+”图标,在下拉菜单中选择Tomcat Server→Local,如图310所示。
图39IntelliJ IDEA中Edit Configurations路径
图310IntelliJ IDEA中Tomcat服务器Local路径
在弹出的窗口中,选择Tomcat Server→Unnamed→Server→Application server,并单击Configuration按钮,如图311所示。
图311IntelliJ IDEA中Tomcat服务器Configuration路径
在弹出的窗口中,在Tomcat Home选项框选择本地Tomcat服务器的安装路径,再单击OK按钮,如图312所示。至此,便完成了在IntelliJ IDEA中配置Tomcat服务器。
图312在IntelliJ IDEA中配置Tomcat服务器
3.1.3发布并运行Web项目
在IntelliJ IDEA中完成配置Tomcat服务器后,就可以进行Web应用的开发了。下面将通过发布并运行一个简单的Web实例项目,来介绍IntelliJ IDEA中开发Web应用的具体方法。
首先创建项目,启动IntelliJ IDEA,按照File→New Project→Java Enterprise→Web Application的流程来生成一个新的项目,如图313所示。同时指定项目名称及存放路径,如图314所示。
图313新建IntelliJ IDEA的Web项目
图314Web项目命名及存放路径
新建项目后,在左侧的子文件夹下找到默认生成的JSP文件index.jsp,双击打开后,可以对里面的默认代码进行修改。如图315所示,代码所实现的任务是输出Hello World和Hello Servlet两行字符。
图315创建的JSP文件
此外,检查Web项目设置是否正确。依次选择File→Project Structure→Project Setting,即可打开Web项目设置,如图316所示。
图316Web项目设置
在发布和运行项目前,还需要先配置Web服务器,由于前面已经配置好了Web服务器Tomcat,此处省略具体配置过程。如图317所示,在配置好Web服务器页面,Server标签页下的URL网址为项目发布地址,复制此地址以备之后在浏览器输入。
图317Web项目的发布路径
项目创建完成之后,即可将项目发布到Tomcat并运行项目。在创建项目中,单击Run或者
图标,项目运行完成后,将之前复制的URL地址粘贴到浏览器地址栏,并按下回车键运行即可。项目成功运行效果如图318所示,至此,便完成了一个简单Web项目的开发。
图318Web项目运行效果图
3.2MySQL基础
根据之前介绍的步骤,可以创建Web应用。但一个有价值的Web应用必然需要进行数据的存储和处理。Web应用最常见的数据操作就是对数据进行增删改查。比如一个图书馆管理系统应用,最核心的功能就是对图书和读者数据进行创建、修改、删除和查询,而这些功能都离不开Web服务器背后的数据库系统。数据库系统包含结构化查询语言(SQL)、数据库管理系统(常见的有MySQL、Oracle等)和数据,接下来将对每一部分内容进行详细介绍。
3.2.1SQL基础语法
SQL是用于访问和处理数据库的标准的计算机程序设计语言,是一种高级的非过程化编程语言,允许用户在高层数据结构上工作。它不要求用户指定对数据的存放方法,也不需要用户了解具体的数据存放方式,所以能应用到不同底层结构的数据库管理系统。SQL用户能对数据库进行执行查询,取回数据,插入数据,更新数据,删除记录,创建新数据库,创建新表,创建视图以及设置表、存储过程和视图的权限等操作。
一个数据库通常由一个或多个表组成。如表31所示,一个表都有一个名字标识(library),并且由多行组成,每一行包含带有数据的记录。
表31图书借阅信息表library
Id
FirstName
LastName
Book_ID
Time
1
Ann
Bush
1001
202011
2
Jack
Gate
1002
202012
3
Peter
Hill
1003
202013
对数据库的操作,主要是通过SQL语句来实现。SQL语句主要分为以下几类: 数据定义语言(Data Definition Language,DDL),数据查询语言(Data Query Language,DQL)、数据操作语言(Data Manipulation Language,DML)和数据控制语言(Data Control Language,DCL)。不同于其他编程语言,SQL 不区分字母大小写。此外,SQL通常采用分号来分隔不同的语句。
1. DDL语句
DDL语句主要用于修改、创建和删除数据库对象,常见的DDL语句包括CREATE、ALTER、DROP等。
创建新数据库采用CREATE DATABASE 命令,其语法结构如下。
create database 数据库名
on [primary]
(
<数据文件参数> [,…n][<文件组参数>]
)
[log on]
(
<日志文件参数> [,…n]
)
创建新表采用CREATE TABLE命令,其语法结构如下。
CREATE TABLE 表名称
(
列名称1 数据类型,
列名称2 数据类型,
列名称3 数据类型,
…
)
【例3.1】创建新表CREATE TABLE Persons。
(
PersonID int,
LastName varchar(255),
FirstName varchar(255),
Address varchar(255),
City varchar(255)
);
变更(改变)数据库表采用ALTER TABLE 命令,其语法结构如下。
ALTER TABLE table_name
删除表采用DROP TABLE 命令,其语法结构如下。
DROP COLUMN column_name
索引是对数据库表中一个或多个列的值进行排序的结构,相当于一本书前面的文件夹,能加快数据库的查询速度。
创建索引(搜索键)采用CREATE INDEX命令,其语法结构如下。
CREATE INDEX index_name
ON table_name(column_name)
【例3.2】在Persons表的LastName列上创建一个名为PIndex的索引。
CREATE INDEX PIndex
ON Persons(LastName)
2. DML语句
DML语句主要用来查询和更新数据。常见的DML语句包括SELECT、UPDATE、DELETE和INSERT INTO等。
从数据库表中获取数据采用SELECT 命令,其语法结构如下。
SELECT列名称 FROM 表名称
【例3.3】从表31中选取 LastName 列的数据。
SQL语句:
SELECT LastName FROM Persons
输出结果如表32所示。
更新数据库表中的数据采用UPDATE 命令,其语法结构如下。
表32选取LastName列的数据
LastName
Bush
Gate
Hill
UPDATE表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
【例3.4】将表31中Lastname 是Gate的人对应的Time列更新为202014。
SQL语句:
UPDATE Person SET Time = '2020-1-4' WHERE LastName = ' Gate '
输出结果如表33所示。
表33更新Time后的表
Id
FirstName
LastName
Book_ID
Time
1
Ann
Bush
1001
202011
2
Jack
Gate
1002
202014
3
Peter
Hill
1003
202013
从数据库表中删除数据采用DELETE 命令,其语法结构如下。
DELETE FROM表名称 WHERE 列名称 = 值
【例3.5】删除表31中LastName叫Hill的数据。
SQL语句:
DELETE FROM Person WHERE LastName = 'Hill'
输出结果如表34所示。
表34删除Hill行后的表
Id
FirstName
LastName
Book_ID
Time
1
Ann
Bush
1001
202011
2
Jack
Gate
1002
202012
向数据库表中插入数据采用INSERT INTO命令,其语法结构如下。
INSERT INTO 表名称 VALUES(值1, 值2, …)
【例3.6】将表35中的数据插入表31。
表35新一行数据表
Id
FirstName
LastName
Book_ID
Time
4
Bill
King
1004
202014
SQL语句:
INSERT INTO Persons VALUES('Gates', 'Bill', 'Xuanwumen 10', 'Beijing')
输出结果如表36所示。
表36插入新行数据的表
Id
FirstName
LastName
Book_ID
Time
1
Ann
Bush
1001
202011
2
Jack
Gate
1002
202012
3
Peter
Hill
1003
202013
4
Bill
King
1004
202014
3. DCL语句
DCL语句主要用于控制存取许可、存取权限等,常见的DCL语句包括GRANT、REVOKE语句。
如需将对指定操作对象的指定操作权限授予指定的用户,采用GRANT命令,其语法结构如下。
GRANT<权限>
ON<对象类型 >< 对象名>
TO <用户>
[ WITH GRANT OPTION]
【例3.7】使用 GRANT 语句创建一个新的用户 testUser,密码为 testPwd。用户 testUser 对所有的数据有查询、插入权限,并授予 GRANT 权限。
SQL语句:
GRANT SELECT,INSERT
ON *.*
TO 'testUser'@'localhost'
IDENTIFIED BY 'testPwd'
授予用户的权限可以由数据库管理员或其他授权者用REVOKE语句收回。
其语法结构如下。
REVOKE <权限>
ON<对象类型><对象名>
FROM<用户>[CASCADE|RESTRICT]
【例3.8】使用 REVOKE语句撤销用户 testUser 对所有的数据的查询、插入权限。
SQL语句:
REVOKE SELECT,INSERT
ON *.*
FROM 'testUser'@'localhost'
3.2.2MySQL安装
MySQL是一种关系数据库管理系统,采用标准化的 SQL 语言进行数据库管理,其特点为体积小、速度快,相比较其他数据库管理系统,还具有免费、开源的优点。在 Web 应用方面,MySQL 是目前采用最多的RDBMS(Relational Database Management System,关系数据库管理系统)应用软件。
本节将介绍MySQL的安装及配置步骤。
首先,进入MySQL的官网(https://www.mysql.com/),如图319
所示,进入下载页面。
图319MySQL官网及下载页面
然后,下拉找到MySQL Community (GPL) Downloads超链接,单击,如图320所示。
图320MySQL社区版下载页面
如图321所示,在可选择的下载版本中选择免费的MySQL Community Server版本进行下载。
图321MySQL社区服务器端下载页面
如图322所示,选择“Windows(x86,64bit),ZIP Archive”免安装版进行下载。
图322MySQL的Windows版下载页面
接下来将下载后的压缩包进行解压,解压路径任选,但不能有中文路径。
然后进行MySQL的配置。由于后续部分命令需要root权限,所以用管理员身份打开命令行,如图323所示。
然后通过命令符的方式,跳转到解压后的MySQL的bin文件夹下,如图324所示。
图323用管理员身份打开命令行
图324跳转到MySQL的bin文件夹
图325安装MySQL的服务
通过输入命令: mysqld install,便安装了MySQL的服务,如图325所示。
通过输入命令: mysqld initialize console,进行MySQL的初始化操作,同时会产生一个随机密码,如图326中右下角的矩形框所示,复制保存这个密码,后续修改会用到该密码。
图326MySQL初始化操作
图327开启MySQL服务
通过输入命令: net start mysql,开启MySQL服务,如图327所示。
通过输入命令: mysql u root p,来验证MySQL是否安装成功,密码为之前随机生成的密码。若结果如图328所示,则说明MySQL已经安装成功。
图328登录验证MySQL是否安装成功
如果想把密码修改为“123”,则输入命令“alter user 'root'@'localhost' identified by '123';”,若出现如图329所示结果,则证明修改成功。
图329修改MySQL密码
最后可以采用修改后的密码重新登录验证一次,若出现如图330所示结果,则表明验证成功。
图330验证MySQL新密码是否修改成功
同时为了方便操作,我们也为MySQL设置一个全局变量。如图331所示,依次选择“我的电脑”→“属性”→“高级系统设置”→“环境变量”→“新建”,输入变量名mysql,变量值为MySQL的安装路径。
图331添加MySQL全局变量
然后把新建的MySQL变量添加到Path系统变量中,如图332所示。
图332修改Path变量
3.2.3使用数据库管理工具管理MySQL
前面已经进行了MySQL的安装及配置,但采用命令行方法管理MySQL既不直观也不方便,因此出现了多种数据库管理工具。其中,Navicat作为一个桌面版MySQL数据库管理和开发工具,具备图形化的用户界面,可以让用户使用和管理更为轻松。Navicat支持中文,有免费版本提供。
接下来将介绍使用Navicat来管理MySQL。首先下载安装Navicat,安装完成后再启动Navicat。然后单击软件左上角的“连接”图标,选择MySQL数据库类型,如图333所示。
图333Navicat启动界面
如图334所示,在弹出的新建连接对话框中,选择“常规”标签页,再输入自定义的连接名,作为管理数据库的标记名,主机名填数据库的服务器名称,因为MySQL安装在本地,所以填写localhost,如果是在其他主机或网络服务器则填写对应的IP,接着输入之前配置MySQL时的密码,最后确认连接。
图334Navicat连接设置界面
连接成功后,可以看到左边出现了自定义的连接名,双击打开。可以看到所有的数据库列表,打开其中一个,可以看到表名列表,如图335所示。
图335Navicat中的数据库及表列表
右击“表”选项,选择“新建表”,即可创建新表,创建后在右边会出现编辑列表框,在第一列可输入新表的字段名,还可以修改类型、长度以及主键,如果要添加新的字段,单击“插入字段”即可,如图336所示。
图336在Navicat中新建表的字段
单击“保存”之后,一个新表即被建立,如图337所示。
图337在Navicat中生成的新表
如果想再添加多行信息,单击下方的“+”号,表示增加一行,接着输入信息,可以单击下方的“√”号,或者按Ctrl+S键保存,如图338所示。
图338在Navicat中添加新行
在表名上右击,可以执行设计表、删除表等多项操作。在数据库名上右击,可以执行新建数据库、删除数据库和编辑数据库等多项操作。
此外,也可以使用Navicat书写SQL语句来操作数据库、表和表记录。如图339所示,单击“查询”选项卡,选择“新建查询”,即可弹出输入SQL语句界面。
我们需要实现在person表中再添加一行的功能,如图340所示,输入INSERT into SQL语句,完成后单击“运行”按钮。
图339在Navicat中输入SQL语句
图340在Navicat中输入插入新行SQL语句
如图341所示,信息栏提示代码实现了成功添加一行的操作。
双击person表,单击“刷新”后显示更新后的内容,新的一行被成功添加到表中,如图342所示。
图341SQL语句信息提示栏
图342SQL语句运行后的新表
3.3Spring MVC
Spring的Web框架围绕DispatcherServlet设计。DispatcherServlet的作用是将请求分发到不同的处理器。Spring的Web框架包括可配置的处理器(handler)映射、视图(view)解析、本地化(local)解析、主题(theme)解析以及对文件上传的支持。
Spring Web MVC允许使用任何对象作为命令对象(或表单对象)——不必实现某个特定于框架的接口或从某个基类继承。Spring的数据绑定相当灵活,例如,它认为类型不匹配这样的错误应该是应用级的验证错误,而不是系统错误。所以你不需要为了保证表单内容的正确提交,而重复定义一个和业务对象有相同属性的表单对象来处理简单的无类型字符串或者对字符串进行转换。
Spring Web MVC框架具有如下特点。
清晰的角色划分: 控制器(controller)、验证器(validator)、命令对象(command object)、表单对象(form object)、模型对象(model object)、Servlet分发器(DispatcherServlet)、处理器映射(handler mapping)、视图解析器(view resolver)等。每个角色都可以由一个专门的对象来实现。
强大而直接的配置方式: 将框架类和应用程序类都能作为JavaBean配置,支持跨多个context的引用,例如,在Web控制器中对业务对象和验证器的引用。
可适配、非侵入: 可以根据不同的应用场景,选择合适的控制器子类(simple型、command型、form型、wizard型、multiaction型或者自定义),而不是从单一控制器(比如Action/ActionForm)继承。
可重用的业务代码: 可以使用现有的业务对象作为命令或表单对象,而不需要去扩展某个特定框架的基类。
可定制的绑定(binding)和验证(validation): 比如将类型不匹配作为应用级的验证错误,这可以保存错误的值。再比如本地化的日期和数字绑定等。在其他某些框架中,你只能使用字符串表单对象,需要手动解析它并转换到业务对象。
可定制的handler mapping和view resolution: Spring提供从最简单的URL映射,到复杂的、专用的定制策略。与某些Web MVC框架强制开发人员使用单一特定技术相比,Spring显得更加灵活。
灵活的model转换: 在Spring Web框架中,使用基于Map的键/值对来轻松完成与各种视图技术的集成。
可定制的本地化和主题(theme)解析: 支持在JSP中可选择地使用Spring标签库、支持JSTL、支持Velocity(不需要额外的中间层)等。
简单而强大的JSP标签库(Spring Tag Library): 支持包括诸如数据绑定和主题(theme) 之类的许多功能。它提供在标记方面的最大灵活性。
JSP表单标签库: 在Spring 2.0中引入的表单标签库,使得在JSP中编写表单更加容易。
Spring Bean的生命周期可以被限制在当前的HTTP Request或者HTTP Session中。
与其他Web MVC框架一样,Spring的Web MVC框架是一个请求驱动的Web框架,其设计围绕一个中心的servlet进行,它能将请求分发给控制器,并提供其他功能帮助Web应用开发。然而,Spring的DispatcherServlet所做的不仅仅是这些,它和Spring的IoC容器完全集成在一起,从而允许你使用Spring的其他功能。
DispatcherServlet实际上是一个servlet(它继承了HttpServlet)。与其他servlet一样,DispatcherServlet定义在Web应用的web.xml文件中。DispatcherServlet处理的请求必须在同一个web.xml文件里使用urlmapping定义映射。下面的例子演示了如何配置DispatcherServlet。
example
org.springframework.web.servlet.DispatcherServlet
1
example
*.form
在DispatcherServlet的初始化过程中,框架会在Web应用的WEBINF文件夹下寻找名为[servletname]servlet.xml的配置文件,生成文件中定义的bean。这些bean会覆盖在全局范围(global cope)中定义的同名的bean。下面这个例子展示了在web.xml中DispatcherServlet的配置:
...
golfing
org.springframework.web.servlet.DispatcherServlet
1
golfing
*.do
可以通过两种方式定制Spring的DispatcherServlet: 在web.xml文件中增加添加context参数,或servlet初始化参数。表37是可能用到的参数。
表37DispatcherServlet初始化参数
参数
描述
contextClass
实现WebApplicationContext接口的类,当前的servlet用它来创建上下文。如果没有指定这个参数,那么默认使用XmlWebApplicationContext
contextConfigLocation
传给上下文实例(由contextClass指定)的字符串,用来指定上下文的位置。这个字符串可以被分成多个字符串(使用逗号作为分隔符) 来支持多个上下文(在多上下文的情况下,如果同一个bean被定义两次,后面一个优先)
namespace
WebApplicationContext命名空间。默认值是[servername]servlet
控制器的概念是MVC设计模式的一部分(确切地说,是MVC中的C)。应用程序的行为通常被定义为服务接口,而控制器使得用户可以访问应用所提供的服务。控制器解析用户输入,并将其转换成合理的模型数据,从而可以进一步由视图展示给用户。Spring以一种抽象的方式实现了控制器概念,这样可以支持不同类型的控制器。Spring本身包含表单控制器、命令控制器、向导型控制器等多种多样的控制器。
Spring控制器架构的基础是org.springframework.mvc.Controller接口,其代码如下:
public interface Controller {
/**
* Process the request and return a ModelAndView object which the DispatcherServlet
* will render.
*/
ModelAndView handleRequest(
HttpServletRequest request,
HttpServletResponse response) throws Exception;
}
可以发现,Controller接口仅仅声明了一个方法,它负责处理请求并返回合适的模型和视图。Spring MVC实现的基础就是这3个概念: Model、View以及Controller。虽然Controller接口是完全抽象的,但Spring也提供了许多你可能会用到的控制器。Controller接口仅仅定义了每个控制器都必须提供的基本功能: 处理请求并返回一个模型和一个视图。
为提供一套基础设施,所有的Spring控制器都继承了AbstractController,AbstractController提供了诸如缓存支持和mimetype设置这样的功能。
当从AbstractController继承时,只需要实现handleRequestInternal(HttpServletRequest, HttpServletResponse)抽象方法,该方法将用来实现自定义的逻辑,并返回一个ModelAndView对象。下面这个简单的例子演示了如何从AbstractController继承以及如何在applicationContext.xml中进行配置。
package samples;
public class SampleController extends AbstractController {
public ModelAndView handleRequestInternal(
HttpServletRequest request,
HttpServletResponse response) throws Exception {
ModelAndView mav = new ModelAndView("hello");
mav.addObject("message", "Hello World!");
return mav;
}
}
所有Web应用的MVC框架都有其定位视图的方式。Spring提供了视图解析器供你在浏览器显示模型数据,而不必被束缚在特定的视图技术上。Spring内置了对JSP、Velocity模板和XSLT视图的支持。
ViewResolver和View是Spring的视图处理方式中特别重要的两个接口。ViewResolver提供了从视图名称到实际视图的映射。View处理请求的准备工作,并将该请求提交给某种具体的视图技术。
Spring提供了多种视图解析器,如表38所示。
表38视图解析器
ViewResolver
描述
AbstractCachingViewResolver
抽象视图解析器实现了对视图的缓存。在视图被使用之前,通常需要进行一些准备工作。从它继承的视图解析器将对要解析的视图进行缓存
XmlViewResolver
XmlViewResolver实现ViewResolver,支持XML格式的配置文件。该配置文件必须采用与Spring XML Bean Factory相同的DTD。默认的配置文件是 /WEBINF/views.xml
ResourceBundleViewResolver
ResourceBundleViewResolver实现ViewResolver,在一个ResourceBundle中寻找所需bean的定义。这个bundle通常定义在一个位于classpath中的属性文件中。默认的属性文件是views.properties
UrlBasedViewResolver
UrlBasedViewResolver实现ViewResolver,将视图名直接解析成对应的URL,不需要显式的映射定义。如果视图名和视图资源的名字是一致的,就可使用该解析器,而无须进行映射
InternalResourceViewResolver
作为UrlBasedViewResolver的子类,它支持InternalResourceView(对Servlet和JSP的包装),以及其子类JstlView和TilesView。通过setViewClass方法,可以指定用于该解析器生成视图使用的视图类。更多信息请参考UrlBasedViewResolver的Javadoc
当使用JSP作为视图层技术时,就可以使用UrlBasedViewResolver。这个视图解析器会将视图名解析成URL,并将请求传递给RequestDispatcher来显示视图。
当返回的视图名为test时,这个视图解析器将请求传递给RequestDispatcher,RequestDispatcher再将请求传递给/WEBINF/jsp/test.jsp。
现在对于一些类型的配置数据有一个趋势,就是偏爱注解方式而不是XML文件。为了方便实现,Spring现在(从2.5版本开始)提供了使用注解配置MVC框架下的组件的支持。Spring 2.5为MVC控制器引入了一种基于注解的编程模型,在其中使用诸如@RequestMapping等。通过这种方式实现的控制器不必由特定的基类继承而来,或者实现特定的接口。更进一步地,它们通常并不直接依赖于Servlet或Portlet API,如果需要,它们可以具有访问Servlet或Portlet的功能。
实际开发过程中常利用注解(@RestController、@RequestMapping等)来开发rest接口。接下来将介绍使用Spring 4 @RestController注解实现基于RESTful JSON的 Spring 4 MVC 例子。
首先,通过采用maven来创建项目。然后,修改pom.xml 添加需要的依赖,在其中添加了Jackson library(jacksonmapperasl),用来将响应的数据转换成json 字符串。
4.0.0
com.websystique.springmvc
Spring4MVCHelloWorldRestServiceDemo
war
1.0.0
Spring4MVCHelloWorldRestServiceDemo Maven Webapp
4.3.0.RELEASE
2.7.5
org.springframework
spring-core
${springframework.version}
org.springframework
spring-web
${springframework.version}
org.springframework
spring-webmvc
${springframework.version}
javax.servlet
javax.servlet-api
3.1.0
com.fasterxml.jackson.core
jackson-databind
${jackson.library}
com.fasterxml.jackson.dataformat
jackson-dataformat-xml
${jackson.library}
org.apache.maven.plugins
maven-compiler-plugin
3.2
1.7
1.7
org.apache.maven.plugins
maven-war-plugin
2.4
src/main/webapp
Spring4MVCHelloWorldRestServiceDemo
false
Spring4MVCHelloWorldRestServiceDemo
其次,添加一个Pojo/domain对象,此对象将从控制器返回并被jackson转换为JSON格式。
package com.websystique.springmvc.domain;
public class Message {
String name;
String text;
public Message(String name, String text) {
this.name = name;
this.text = text;
}
public String getName() {
return name;
}
public String getText() {
return text;
}
}
最后,添加控制器,在其中使用了@RestController 注解,表明本类作为一个控制器,返回的是一个domain/pojo对象而不是视图。这就意味着,不再使用视图解析器,响应中不再发送html数据,而是发送domain对象的特定形式。
package com.websystique.springmvc.controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.websystique.springmvc.domain.Message;
@RestController
public class HelloWorldRestController {
@RequestMapping("/")
public String welcome() {//Welcome page, non-rest
return "Welcome to RestTemplate Example.";
}
@RequestMapping("/hello/{player}")
public Message message(@PathVariable String player) {//REST Endpoint.
Message msg = new Message(player, "Hello " + player);
return msg;
}
}
再添加配置类。
package com.websystique.springmvc.configuration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.websystique.springmvc")
public class HelloWorldConfiguration {
}
再添加初始化类。
package com.websystique.springmvc.configuration;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class HelloWorldInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class>[] getRootConfigClasses() {
return new Class[] { HelloWorldConfiguration.class };
}
@Override
protected Class>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
在完成以上配置之后,就可以创建和发布应用了。
此外,常使用注解@RequestMapping映射请求。下面是一个通过使用@RequestMapping注解来实现表单控制器的例子。
@Controller
@RequestMapping("/editPet.do")
@SessionAttributes("pet")
public class EditPetForm {
private final Clinic clinic
@Autowired
public EditPetForm(Clinic clinic) {
this.clinic = clinic;
}
@ModelAttribute("types")
public Collection populatePetTypes() {
return this.clinic.getPetTypes();
}
@RequestMapping(method = RequestMethod.GET)
public String setupForm(@RequestParam("petId") int petId, ModelMap model) {
Pet pet = this.clinic.loadPet(petId);
model.addAttribute("pet", pet);
return "petForm";
}
@RequestMapping(method = RequestMethod.POST)
public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result,
SessionStatus status) {
new PetValidator().validate(pet, result);
if (result.hasErrors()) {
return "petForm";
}
else {
this.clinic.storePet(pet);
status.setComplete();
return "redirect:owner.do?ownerId=" + pet.getOwner().getId();
}
}
}
3.4MyBatis基础
3.4.1初识MyBatis
MyBatis本是Apache的一个开源项目iBatis,2010年这个项目由Apache Software Foundation迁移到了Google code,并且改名为MyBatis。2013年11月迁移到Github。MyBatis 是一款优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射。MyBatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。MyBatis可以通过简单的XML或注解来将原始类型、接口和Java POJO(Plain Old Java Objects,普通老式Java对象)配置和映射为数据库中的记录。
Mybatis具有以下特点:
简单易学。
灵活。
SQL和代码的分离,提高了可维护性。
提供映射标签,支持对象与数据库的ORM字段关系映射。
提供对象关系映射标签,支持对象关系组建维护。
提供XML标签,支持编写动态SQL。
MyBatis源码可以通过Maven工具或GitHub下载。
下面介绍通过GitHub下载。单击GitHub网址(https://github.com/
)。在搜索框中搜索 Mybatis,搜索结果如图343所示,同时单击mybatis3链接。
图343mybatis349下载链接
选择mybatis3.5.6版本进行下载,如图344所示。
图344mybatis3.5.6版本
选择下载mybatis3.5.6.zip压缩包,如图345所示,然后将其解压在IntelliJ IDEA中项目所属文件夹中即可,然后在IntelliJ IDEA中打开所解压的文件。
图345mybatis3.5.6.zip压缩包
3.4.2MyBatis配置
MyBatis的配置文件包含了会深深影响MyBatis行为的设置和属性信息。配置文档的顶层结构包括如下几个部分。
1. 属性
这些属性(properties)可以在外部进行配置,并可以进行动态替换。你既可以在典型的Java属性文件中配置这些属性,也可以在properties元素的子元素中设置。例如:
<%/*实际应用中,password需要加密后再配置到配置文件中*/%>
设置好的属性可以在整个配置文件中用来替换需要动态配置的属性值。比如:
如果一个属性在不止一个地方进行了配置,那么,MyBatis将按照下面的顺序来加载:
首先读取在properties元素体内指定的属性。
然后根据properties元素中的resource属性读取类路径下属性文件,或根据url属性指定的路径读取属性文件,并覆盖之前读取过的同名属性。
最后读取作为方法参数传递的属性,并覆盖之前读取过的同名属性。
因此,通过方法参数传递的属性具有最高优先级,resource/url属性中指定的配置文件次之,最低优先级的则是properties元素中指定的属性。
从MyBatis 3.4.2开始,可以为占位符指定一个默认值。例如:
2. 设置
这是MyBatis中极为重要的调整设置(settings),它们会改变MyBatis的运行时行为。表39描述了设置中各项设置的含义、默认值等。
表39MyBatis设置中各项设置的含义、默认值
设置名
描述
有效值
默认值
cacheEnabled
全局性地开启或关闭所有映射器配置文件中已配置的任何缓存
true | false
true
lazyLoadingEnabled
延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态
true | false
false
aggressiveLazyLoading
开启时,任一方法的调用都会加载该对象的所有延迟加载属性。否则,每个延迟加载属性会按需加载(参考lazyLoadTriggerMethods)
true | false
false
multipleResultSetsEnabled
是否允许单个语句返回多结果集(需要数据库驱动支持)
true | false
true
useColumnLabel
使用列标签代替列名。实际表现依赖于数据库驱动,具体可参考数据库驱动的相关文档,或通过对比测试来观察
true | false
true
useGeneratedKeys
允许JDBC支持自动生成主键,需要数据库驱动支持。如果设置为true,将强制使用自动生成主键。尽管一些数据库驱动不支持此特性,但仍可正常工作(如 Derby)
true | false
False续表
设置名
描述
有效值
默认值
autoMappingBehavior
指定MyBatis应如何自动映射列到字段或属性。NONE 表示关闭自动映射; PARTIAL只会自动映射没有定义嵌套结果映射的字段。FULL会自动映射任何复杂的结果集(无论是否嵌套)
NONE, PARTIAL, FULL
PARTIAL
autoMappingUnknownColumnBehavior
指定发现自动映射目标未知列(或未知属性类型)的行为
NONE, WARNING, FAILING
NONE
defaultExecutorType
配置默认的执行器。SIMPLE就是普通的执行器; REUSE 执行器会重用预处理语句(PreparedStatement); BATCH 执行器不仅重用语句,还会执行批量更新
SIMPLE REUSE BATCH
SIMPLE
defaultStatementTimeout
设置超时时间,它决定数据库驱动等待数据库响应的秒数
任意正整数
未设置
(null)
defaultFetchSize
为驱动的结果集获取数量(fetchSize)设置一个建议值。此参数只可以在查询设置中被覆盖
任意正整数
未设置
(null)
safeRowBoundsEnabled
是否允许在嵌套语句中使用分页(RowBounds)。如果允许使用则设置为false
true | false
False
safeResultHandlerEnabled
是否允许在嵌套语句中使用结果处理器(ResultHandler)。如果允许使用则设置为false
true | false
True
mapUnderscoreToCamelCase
是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN映射到经典Java属性名aColumn
true | false
False
localCacheScope
MyBatis利用本地缓存机制(Local Cache)防止循环引用和加速重复的嵌套查询。默认值为SESSION,会缓存一个会话中执行的所有查询。若设置值为STATEMENT,本地缓存将仅用于执行语句,对相同SqlSession的不同查询将不会进行缓存
SESSION |
STATEMENT
SESSION
一个配置完整的settings元素的示例如下:
3. 类型别名
类型别名(typeAliases)可用于为Java类型设置一个缩写名字。它仅用于XML配置,意在减少冗余的全限定类名书写。例如:
4. 对象工厂
每次MyBatis创建结果对象的新实例时,它都会使用一个对象工厂(objectFactory)实例来完成实例化工作。默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认无参构造方法,要么通过存在的参数映射来调用带有参数的构造方法。如果想覆盖对象工厂的默认行为,那么可以通过创建自己的对象工厂来实现。例如:
// ExampleObjectFactory.java
public class ExampleObjectFactory extends DefaultObjectFactory {
public Object create(Class type) {
return super.create(type);
}
public Object create(Class type, List constructorArgTypes, List