Lab 2:MVC编程与云平台部署
Lab 2:MVC编程与云平台部署
1. 实验要求
使用MySQL建立图书数据库,包含两张表
Book {ISBN (PK), Title, AuthorID (FK), Publisher, PublishDate, Price}
Author {AuthorID (PK), Name, Age, Country}
输入作者名字,查询作者所著书目;
点击某本书题目时,展示图书详细信息和作者详细信息;
用户点击删除按钮,将对应行的图书从数据表中删除;
- 开发环境配置
- 在Eclipse中配置Struts2
如上图所示,将Struts2中的commons-fileupload-1.3.2.jar , commons-io-2.4.jar , commons-lang3-3.4.jar , commons-logging-1.1.3.jar , freemarker-2.3.23.jar , javassist-3.20.0-GA.jar , log4j-api-2.6.2.jar , log4j-core-2.6.2.jar , ognl-3.1.10.jar , struts2-core-2.5.2.jar
加入到WEB-INF的lib文件夹中
- 在Eclipse中配置MySQL
将下载的mysql-connecter中的 mysql-connector-java-5.1.20-bin.jar 加入到WEB-INF的lib文件夹中,右键build path,在libraries里面添加 mysql-connector-java-5.1.20-bin.jar
- 在Eclipse中配置Tomcat
下载好以后在Libraries上选择Add Library,选择Server Runtime,选择自己下载的tomcat版本。
- 图书SaaS设计
- 3.1.Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns=""
xmlns:xsi=""
xsi:schemaLocation="
.xsd">
<display-name>Lab2_CRUD</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file> //首页
</welcome-file-list>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
- 3.2.Struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
".5.dtd">
<struts>
<constant name="struts.action.extension" value="html,action,do,"/>
<package name="crud" extends="struts-default">
<action name="index">
<result>/index.jsp</result>
</action>
<action name="list" class="top.sonack.crud.action.BookAction" method=“list"> //显示所有书目
<result name="success">/list.jsp</result>
<result name="confirmAuthorSuccess" type="redirect">/confirmAuthor.action</result>
</action>
<action name="listAuthors" class="top.sonack.crud.action.BookAction" method=“listAuthors”>//显示所有作者
<result name="success">/listAuthors.jsp</result>
</action>
<action name="deleteSingleBook" class="top.sonack.crud.action.BookAction" method="deleteBook">
<result name="success" type="redirect">/list.action</result>
</action>
<action name="deleteSelectedBook" class="top.sonack.crud.action.BookAction" method=“deleteBooks”>//删除选中书目
<result name="success" type="redirect">/list.action</result>
</action>
<action name="searchInput">
<result>/search.jsp</result>
</action>
<action name="searchBooks" class="top.sonack.crud.action.BookAction" method=“searchBooks”>//显示书目详细信息
<result name="success">/list.jsp</result>
<result name="noBook">/noBook.jsp</result>
<result name="morethan1">/morethan1authors.jsp</result>
</action>
<action name="searchAuthor" class="top.sonack.crud.action.BookAction" method=“searchAuthor”>//显示作者详细信息
<result name="success">/listAuthor.jsp</result>
</action>
</package>
</struts>
- 3.3.Action类
序号 | Action类名 | 作用 |
1 | deleteBook | 删除一本书 |
2 | deleteBooks | 删除多本书 |
3 | list | 显示所有书目 |
4 | listAuthors | 显示所有作者 |
5 | confirmAuthors | 确定重名作者选择 |
6 | searchBooks | 按作者名搜索书目 |
7 | searchAuthor | 按作者ID搜索作者详细信息 |
- 4.
- 4.
- 4.辅助类
1.AuthorDAO.java 建立action与数据库Author表的链接
2.BookDAO.java 建立action与数据库Book表的链接
3.JdbcUtils.java 链接数据库
- 5.前端Web页面
序号 | 页面名 | 作用 | 页面核心元素(form) | Form对应的action name |
1 | index.jsp | 首页 | 浏览全部图书 | list |
浏览全部作者 | listAuthors | |||
查询指定作者 | searchInput | |||
2 | list.jsp | 展示所有书目 | deleteSelectedBook |
|
3 | listAuthor.jsp | 展示作者详细信息 |
| searchAuthor |
4 | listAuthors.jsp | 展示所有作者 |
| listAuthors |
5 | morethan1authors.jsp | 作者重名 |
| searchBooks |
6 | noBook.jsp | 搜索作者不存在 |
| searchBooks |
7 | search.jsp | 搜索页面 |
| searchInput |
- 6.
- 6.
- 6.各Action/前端页面之间的调用和消息传递关系
- 图书SaaS核心代码
- 4.1.按作者查询
<body>
<h2 id="headline">
<a href="index.jsp">图书管理</a>
</h2>
<ul>
<li><a href="<s:url action='list' />">浏览全部图书</a></li>
<li><a href="<s:url action='listAuthors' />">浏览全部作者</a></li>
<li><a href="<s:url action='searchInput' />">查询指定作者</a></li>
</ul>
<table width="85%" border="1" align="center">
<tr bgcolor="#949494">
<s:iterator value="author">
<thead>
<tr>
<th class="authorID">编号</th>
<th class="name">姓名</th>
<th class="age">年龄</th>
<th class="country">国家</th>
</tr>
</thead>
<tbody>
<tr>
<td><s:property value="authorID" /></td>
<td class="zzm">
<s:property value="name" />
</td>
<td><s:property value="age" /></td>
<td><s:property value="country" /></td>
</tr>
</tbody>
</s:iterator>
</table>
</body>
- 4.2.展示图书详细信息
<body>
<h2 id="headline">
<a href="index.jsp">图书管理</a>
</h2>
<ul>
<li><a href="<s:url action='list' />">浏览全部图书</a></li>
<li><a href="<s:url action='listAuthors' />">浏览全部作者</a></li>
<li><a href="<s:url action='searchInput' />">查询指定作者</a></li>
</ul>
<table width="85%" border="1" align="center">
<tr bgcolor="#949494">
<thead>
<tr>
<th class="xz">选择</th>
<th class="isbn">ISBN号</th>
<th class="sm">书名</th>
<th class="zzbh">作者编号</th>
<th class="cbs">出版社</th>
<th class="cbrq">出版日期</th>
<th class="jg">价格</th>
<th class="cz">操作</th>
</tr>
</thead>
</table>
<s:form action="deleteSelectedBook">
<table width="85%" border="1" align="center">
<tr bgcolor="#949494">
<tbody>
<s:iterator value="books">
<tr>
<td class="xz"><input type="checkbox" name="isbns"
value='<s:property value="isbn" />' class="items" /></td>
<td class="isbn"><s:property value="isbn" /></td>
<td class="sm">
<s:property value="title" />
</td>
<td class="zzbh">
<a class="titlelink" href="<s:url action='searchAuthor'> <s:param name='authorID' value='authorID' /> </s:url>">
<s:property value="authorID" />
</a></td>
<td class="cbs"><s:property value="publisher" /></td>
<td class="cbrq"><s:property value="publishDate" /></td>
<td class="jg">¥<s:property value="price" /></td>
<td class="cz" colspan="2">
<a class="danger"
href="<s:url action='deleteSingleBook'> <s:param name='isbn' value='isbn' /> </s:url>"
onclick="javascript:if(confirm('确定要删除本书吗?')){alert('删除成功!');return true;}return false;">
删除</a></td>
</tr>
</s:iterator>
</tbody>
</table>
<input type="checkbox" name="isbns" value="" id="all" /> <label
for="all">全选/全不选</label>
<input type="submit" value="删除" id="removeAll"
onclick="javascript:if(confirm('确定要删除所选条目吗?')){alert('删除成功!');return true;}return false;" />
</s:form>
</body>
- 4.3.删除图书
public String deleteBook() throws SQLException
{
bookDAO.deleteBook(isbn);
return SUCCESS;
}
public String deleteBooks() throws SQLException
{
if (isbns != null)
bookDAO.deleteBooks(isbns);
return SUCCESS;
}
public void deleteBook(String isbn) throws SQLException
{
String sql = "DELETE FROM " + BOOK_TABLE_NAME + " WHERE isbn = '" + isbn + "'";
System.out.println("删除" + sql);
stmt = JdbcUtils.getStatement();
stmt.executeUpdate(sql);
}
public void deleteBooks(String[] isbns) throws SQLException
{
for(String isbn : isbns)
{
deleteBook(isbn);
}
}
- 4.4.数据库连接与访问
public class JdbcUtils
{
private static Connection connection;
private static Statement statement;
//System.getenv("MYSQL_HOST_S"); 为从库,只读
/* private static final String DATABASE_NAME = "test";
private static final String USERNAME = "root";
private static final String PASSWORD = "1511NvWa";
static
{
String d = "com.mysql.jdbc.Driver";
try
{
Class.forName(d);
}
catch(Exception e)
{
e.printStackTrace();
}
}
*/
public static Connection getConnection() throws SQLException
{
if(connection == null || connection.isClosed())
{
// String url = "jdbc:mysql://pogvyhwsgvsf.rds.sae.sina:10572/" + DATABASE_NAME;
// 本地服务器
// String url = "jdbc:mysql://localhost:3306/test";
// 腾讯云服务器
/*String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8";
try
{
connection = DriverManager.getConnection(url,USERNAME,PASSWORD);
}
catch(Exception e)
{
System.out.println("数据库连接异常!");
e.printStackTrace();
}
}
*/
String driver = "com.mysql.jdbc.Driver";
String username = System.getenv("ACCESSKEY");
String password = System.getenv("SECRETKEY");
//System.getenv("MYSQL_HOST_S"); 为从库,只读
String dbUrl = String.format("jdbc:mysql://%s:%s/%s", System.getenv("MYSQL_HOST"), System.getenv("MYSQL_PORT"), System.getenv("MYSQL_DB"));
try {
Class.forName(driver).newInstance();
connection = DriverManager.getConnection(dbUrl, username, password);
// ...
} catch (Exception e) {
// ...
}
}
return connection;
}
public static Statement getStatement() throws SQLException
{
if(statement == null || statement.isClosed())
statement = JdbcUtils.getConnection().createStatement();
return statement;
}
public static void release(ResultSet res,Statement stmt,Connection conn)
{
if(res != null)
{
try
{
res.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
if(stmt != null)
{
try
{
stmt.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
if(conn != null)
{
try
{
conn.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
public static void release(Object o)
{
try
{
if(o instanceof ResultSet)
{
((ResultSet)o).close();
}else if (o instanceof Statement)
{
((Statement) o).close();
} else if (o instanceof Connection)
{
((Connection) o).close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
- 图书SaaS的云平台部署
- 5.1.所选定的公共云平台
新浪云
- 5.2.部署步骤
1.注册 直接用的自己的新郎账户
2.创建应用:定义二级域名,选择标准版,java
3.配置mysql:点击共享性mysql,点击SQL,输入mysql命令行,创建Author和Book两个表
- 5.3.外在访问结果
给出访问公共云平台上的图书SaaS的屏幕截图结果,要展示出核心功能。截图要带浏览器标题栏和地址栏。
- 小结
对本次实验过程和结果的思考,包括但不限于对以下问题的思考:
- 与在本地环境部署 Web应用相比,在云平台上部署Web应用的难度体现在?你是如何克服这些难点的?
以前在云平台上没部署过,和数据库连接和本地的方式不一样。百度教程一点一点研究。
- 与之前你擅长的桌面程序开发相比,Web开发有什么不一样的地方?
需要考虑界面的完整,以及界面与界面之间的衔接,数据及参数的传递,还有与struts2的action的映射,更为复杂一些。
- 面对全新的技术,你如何做到快速从基础为0到能够用其开发一个简单的原型Web系统?
百度,查每一行报错是因为什么,从一开始jar包的基础问题,到后来数据传递问题,找网上其他项目的源码,分析每一行代码实现了什么,看教程,查每一个function的功能。
- 你是否适应了在短时间内“目标驱动(开发一个具体的系统)”来学习一种新技术?
算是吧,但也是非常让人疲惫的。
- 过去两周,你对Lab2贡献了多少精力和时间?值得吗?如果想骂人,可以在这里骂出来~~ 但如果你觉得有收获,不妨也在这里简单记录下来。
值得倒是值得,但是一整个十一假期都没了,每天在家里窝着敲代码,愁得慌,头发倒是掉了不少,真难受。
- 为了在云端调试这个简单的Web系统,你花了多少钱?
5元