在IntelliJ IDEA环境下使用Servlet和JSP操作MySQL数据库

之前讲了如何用JDBC操作数据库,这次讲一下怎么用Servlet和JSP操作数据库。

其实还是在用JDBC操作数据库,只是再加了一层包装而已。

工作中经常接触的接口和服务器后台就是这两者的活用。

安装Tomcat

在开始前,我们先需要下载Tomcat。

下载地址

安装好后,在浏览器里可以打开网页http://localhost:8080/

新建JavaWeb项目

在IDEA里新建一个项目,项目类型选择Java Enterprice,如下图红框1。Application Server选择Tomcat,如下图红框2。

然后Additional Libraries and Frameworks选择Web Application,如下图红框3。

在选择Application Server时点击New,会弹出一个窗口。Tomcat Home路径选择Tomcat的安装文件夹。Tomcat base directory路径会自动识别。操作如图所示:

新建好项目后,工程图如下。

然后打开index.jsp,修改title标签里的内容和body标签里的内容,然后运行。你就能在浏览器中浏览JSP里的内容了。

修改配置

简单介绍一下项目运行的配置。

先打开项目的run/debug configurations。在下图红框中可见:

下图红框1表示项目运行后自动打开Chrome浏览器,红框2表示项目使用端口8080。注:之前安装的Tomcat软件也是默认使用8080端口的,所以这里可能会冲突,只要修改一个或者将Tomcat关闭即可。

下图红框中表示应用的环境,也可以理解为路径,像我在红框中写了yes,就可以用localhost:8080/yes/来访问。

使用Servlet操作数据库

直接贴代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package com.bovink.example;
import org.json.JSONArray;
import org.json.JSONObject;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
public class GetCity extends HttpServlet {
@Override
public void init() throws ServletException {
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out = resp.getWriter();
String id = req.getParameter("_id");
String page = req.getParameter("page");
// 根据传递的参数输出数据
if (id != null) {
out.println(getCity(id));
} else if (page != null) {
out.println(getCityArray(Integer.parseInt(page)));
}
}
@Override
public void destroy() {
}
// 根据页面获取数据
public static JSONArray getCityArray(int page) {
int start = 10 * (page - 1);
JSONArray jsonArray = new JSONArray();
try {
Connection connection = getConnection();
Statement statement = connection.createStatement();
// 执行SQL语句
ResultSet resultSet = statement.executeQuery("SELECT * FROM city LIMIT " + start + ",10");
while (resultSet.next()) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("id", resultSet.getString(1));
jsonObject.put("name", resultSet.getString(2));
jsonObject.put("country_code", resultSet.getString(3));
jsonObject.put("district", resultSet.getString(4));
jsonObject.put("population", resultSet.getString(5));
jsonArray.put(jsonObject);
}
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return jsonArray;
}
// 根据id获取城市
public static JSONObject getCity(String id) {
JSONObject jsonObject = new JSONObject();
try {
Connection connection = getConnection();
Statement statement = connection.createStatement();
// 执行SQL语句
ResultSet resultSet = statement.executeQuery("SELECT * FROM city WHERE ID = " + id);
while (resultSet.next()) {
jsonObject.put("id", resultSet.getString(1));
jsonObject.put("name", resultSet.getString(2));
jsonObject.put("country_code", resultSet.getString(3));
jsonObject.put("district", resultSet.getString(4));
jsonObject.put("population", resultSet.getString(5));
}
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return jsonObject;
}
// 获取数据库连接
private static Connection getConnection() throws SQLException, ClassNotFoundException {
Class.forName("com.mysql.jdbc.Driver");
String serverName = "localhost";
String database = "world";
String url = "jdbc:mysql://" + serverName + "/" + database;
String user = "root";
String password = "123456";
return DriverManager.getConnection(url, user, password);
}
}

类中有3个回调类,init和destroy这两个方法用来管理servlet生命周期内的资源。

doGet方法要来处理HTTP GET请求。内部根据请求传递的参数执行具体操作,out打印的内容就是输出的内容。

另外3个方法中,getConnection是一个工具方法,用来获取连接实例。

getCity方法根据传递的id参数获取city表中的数据,并将一系列数据传递给JSONObject返回。

getCityArray根据传递的page参数获取city表中的10条数据,并将数据处理成一个JSONArray返回。

那么如何在web中访问这个类呢?这需要在web文件夹下的web.xml中进行设置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet-mapping>
<servlet-name>GetCity</servlet-name>
<url-pattern>/get_city</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>GetCity</servlet-name>
<servlet-class>com.bovink.example.GetCity</servlet-class>
</servlet>
</web-app>

其中servlet-name只要两者一致就OK,url-pattern使用/加字符串,访问的时候就是在网址后面加上相同内容。

servlet-class即包名加上类名。

除此以外还需要设置依赖库的路径。在web/WEB-INF目录下建立一个lib文件夹(存放依赖的库),然后在Project Structure的Modules的Dependencies中添加该路径,

运行项目后就可以在网页中用,localhost:8080/get_city访问了。

localhost:8080/get_city?_id=1可以访问id为1的city数据。

localhost:8080/get_city?page=1可以访问前10条city数据。

使用Jsp操作数据库

Servlet是一个Java类,所以能够正常的在其中使用Java代码,但JSP不是一个Java类。

JSP是一个网页,准确的说,是能根据客户端请求而动态改变内容的网页。

那么怎么在JSP中使用Java代码呢?

使用JSP独有的标签<%%>即可。

JSP输出数据库内容

index.jsp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<%@ page import="org.json.JSONObject" %>
<%@ page import="java.util.Iterator" %>
<%--
Created by IntelliJ IDEA.
User: bovink
Date: 2016/8/29
Time: 11:22
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Blog Example</title>
<style type="text/css">
p {
color: red;
}
</style>
</head>
<body>
<p>this is from jsp</p>
<%
String id = request.getParameter("_id");
JSONObject jsonObject = com.bovink.example.GetCity.getCity(id);
%>
<table border="1">
<tr id="tr">
<td>country_code</td>
<td>district</td>
<td>name</td>
<td>id</td>
<td>population</td>
</tr>
<tr>
<%
Iterator<?> iterator = jsonObject.keys();
while (iterator.hasNext()) {
%>
<td>
<%
String key = iterator.next().toString();
System.out.println(key);
out.print(jsonObject.getString(key));
%>
</td>
<%
}
%>
</tr>
</table>
</body>
</html>

通过<%%>就能插入Java代码,并且和正常类一样,在JSP中能够使用其他类的静态方法。

<%%>还能将一个循环拆开,中间插入HTML标签,这样使HTML的内容也进入循环中。

JSP自带一些环境变量,如application、out、response、request、session等。

request、response和HttpServlet的doGet方法的参数中的一样,包含客户端请求的参数。

通过request可以获取参数来初始化变量进而获取数据库中的数据。通过out可以直接将字符串打印在网页上。

配合HTML标签,就能够以列表形式展示数据了。

如果懂CSS以及各种CSS模板的话,还能美化一下界面。

通过表单加载JSP

query.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<%@ page import="org.json.JSONObject" %>
<%@ page import="org.json.JSONArray" %>
<%@ page import="java.util.Iterator" %>
<%--
Created by IntelliJ IDEA.
User: bovink
Date: 2016/8/29
Time: 15:08
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>get city data</title>
</head>
<body>
<%
String pageNum = request.getParameter("page");
JSONArray jsonArray = com.bovink.example.GetCity.getCityArray(Integer.parseInt(pageNum));
%>
<table border="1">
<tr>
<td>country_code</td>
<td>district</td>
<td>name</td>
<td>id</td>
<td>population</td>
</tr>
<%
for (int i = 0; i < jsonArray.length(); i++) {
%>
<tr>
<%
JSONObject jsonObject = jsonArray.getJSONObject(i);
Iterator<?> iterator = jsonObject.keys();
while (iterator.hasNext()) {
%>
<td>
<%
out.print(jsonObject.getString(iterator.next().toString()));
%>
</td>
<%
}
%>
</tr>
<%
}
%>
</table>
// action表示这个表单指向的JSP,当点击sumbit后,自动打开网页。
// 请求参数为表单中的标签值。
<form action="query.jsp">
<input type="hidden" id="pageNum" name="page" value="<%
out.print(pageNum);
%>"/>
<input type="submit" value="下一页" onclick="clickBtn()">
<script>
var page = document.getElementById("pageNum");
// 点击submit时响应方法
function clickBtn() {
page.value = parseInt(page.value, 10) + 1 + "";
}
</script>
</form>
</body>
</html>

query.jsp与index.jsp的差别是它可以通过表单<form>加载JSP.

<form>的acntion属性表示这个表单提交后跳转的网页。

<input>的type属性设为hidden表示该标签隐藏不显示,设为submit表示这个标签是提交按钮。

而且表单和网址一样能传递参数,在代码中给input标签的name属性赋值为page,在加载新JSP页面时,就会带上一个key为name,value为input的value的值。

JSP中也能正常使用JavaScript。

和Servlet不一样,JSP更需要懂Web端的知识。