豫ICP备17040950号-2

JSP和servlet概述

文章目录
  1. 1. JSP概述
    1. 1.1. 名词解释
    2. 1.2. Servlet
    3. 1.3. Servlet demo设计
    4. 1.4. 原理分析
    5. 1.5. 优化
      1. 1.5.1. GenericServlet类
      2. 1.5.2. HttpServlet类
    6. 1.6. Servlet进阶
    7. 1.7. 源码分享
    8. 1.8. JSP语法
      1. 1.8.1. 数据定义
      2. 1.8.2. 程序块
      3. 1.8.3. 表达式
      4. 1.8.4. 注释
      5. 1.8.5. 指令
      6. 1.8.6. 动作
      7. 1.8.7. 内置对象
    9. 1.9. 参考文档

JSP概述

名词解释

JSP全名为Java Server Pages,中文名叫java服务器页面,其根本是一个简化的Servlet设计。

JSP文件类似于HTML文件,但又不完全相同,其实JSP是由HTML、Java片段和JSP标记组成的。

Servlet

Java的运行方式是通过Java虚拟机把*.java的文件编译成*.class文件,但JSP文件却是后缀名为.jsp的文件,怎么执行呢?
当*.jsp文件被送到服务器后,先由服务器翻译成Servlet文件,而Servlet文件就是*.java文件,然后*.java文件又被编译成*.class文件,再由Java虚拟机解释执行。

Servlet和Java Applet一样,它们都不是独立的应用程序,都没有main()方法,而是生存在容器中,由容器来管理。编写一个Servlet文件,需要实现javax.servlet.Servlet接口。

Servlet demo设计

新建Dynamic Web Project,命名为servlet。新建包com.voidking.servlet,新建类HelloWorld,实现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
package com.voidking.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class HelloWorld implements Servlet {

@Override
public void destroy() {
// TODO Auto-generated method stub

}

@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}

@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}

@Override
public void init(ServletConfig arg0) throws ServletException {
// TODO Auto-generated method stub

}

@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
// TODO Auto-generated method stub

PrintWriter pw = res.getWriter();
pw.println("HelloWorld");
}

}

在WebContent/WEB-INF下新建web.xml,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
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_2_5.xsd">
<display-name></display-name>
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>com.voidking.servlet.HelloWorld</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/helloWorld</url-pattern>
</servlet-mapping>
</web-app>

发布工程,访问http://localhost:8080/servlet/helloWorld ,即可在界面上看到“HelloWorld”。

原理分析

init():在Servlet实例化之后,Servlet容器会调用init()方法,来初始化该对象。该方法主要是为了让Servlet对象在处理客户请求前可以完成一些初始化工作,例如,建立数据库的连接,获取配置信息等。对于每个Servlet实例,init()方法只能被调用一次。init()方法有一个类型为ServletConfig的参数,Servlet容器通过这个参数向Servlet传递配置信息。Servlet使用该对象从Web应用程序的配置信息中获取初始化参数。另外,在Servlet中,还可以通过ServletConfig对象获取描述Servlet运行环境的ServletContext对象,使用该对象,Servlet可以和它的Servlet容器进行通信。

service():容器调用service()方法来处理客户端的请求。在init()方法正确完成后,service()方法被容器调用。在service()方法中有用于接受客户端请求信息的请求对象(类型为ServletRequest)和用于对客户端进行响应的响应对象(类型为ServletResponse)的参数。Servlet对象通过ServletRequest对象得到客户端的相关信息和请求信息,在对请求进行处理后,调用ServletResponse对象的方法设置响应信息。

destroy():当容器检测到一个Servlet对象应该从服务中被移除时,容器会调用该对象的destroy()方法,来释放Servlet对象所使用的资源,保存数据到持久存储设备中。例如,将内存中的数据保存到数据库中,关闭数据库连接等。在Servlet容器调用destroy()方法前,如果还有其他线程正在service()方法中执行,容器会等待这些线程执行完毕或等待服务器设定的最大时间到达。一旦Servlet对象的destroy()方法被调用,容器不会再把其他的请求发送给该对象。如果需要该Servlet对象再次为客户端服务,容器将会重新生成一个Servlet对象来处理客户端的请求。在destroy()方法调用之后,容器会释放这个Servlet对象,在随后的时间内,该对象会被Java的垃圾收集器回收。

getServletConfig():放回容器调用init()方法时传递给Servlet对象的ServletConfig对象,ServletConfig对象包含了Servlet的初始化参数。

getServletInfo():放回一个String类型的字符串,其中包括关于Servlet的信息,例如,作者、版本和版权。

web.xml文件中包含配置信息。web.xml文件的第一行是对xml文件的生命,接着就是xml的根元素,其属性中声明了版本等信息。
之间配置的是,其中的值“HelloWorld”是为Servlet起的一个名字,这个可以随便起名,只要符合Java的命名规则就行;而的值则是自己写的Servlet类的类名,这个必须配置正确,如果有包,还要在前面加上包名。这个类名不带.java,也不带.class。

之间配置的是,其中的值就是上面刚刚配置的的值;而的值也可以随便起名,但其前面必须加“/”,如上面例子中的“/helloWorld”。

访问地址:http://localhost:8080/servlet/helloWorld ,其中,http://localhost:8080 是服务器URL,而后面的servlet是项目名,最后面的helloWorld是在web.xml中配置的的值。

优化

GenericServlet类

上面的例子中,采用实现Servlet接口的方法,需要实现5个方法。为了简化Servlet的编写,在javax.servlet包中提供了一个抽象的类GenericServlet。它给出了出service()外其他4个方法的简单实现。GenericServlet实现了Servlet接口和ServletConfig接口。
HelloWorld.java可以改写为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.voidking.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class HelloWorld extends GenericServlet {

@Override
public void service(ServletRequest arg0, ServletResponse arg1)
throws ServletException, IOException {
// TODO Auto-generated method stub
PrintWriter pw = arg1.getWriter();
pw.println("HelloWorld");

}

}

HttpServlet类

在大部分网络中,都是客户端通过HTTP协议来访问服务端的资源。为了快速开发应用于HTTP协议的Servlet类,在javax.servlet.http包中提供了一个抽象HttpServlet。它继承了GenericServlet类。

当容器接到一个针对HttpServlet对象请求时,该对象就会调用public的service()方法,首先将参数类型转换为HttpServletRequest和HttpServletResponse,然后调用protected的service()方法将参数传进去。

接着调用HttpServletRequest对象的getMethod()方法获取请求方法名来调用相应的doXxx()方法。所以一个Servlet类在继承HttpServlet时,不用覆盖它的service()方法,只需要覆盖相应的doXxx()方法就行了。通常情况下,都是覆盖其doGet()和doPost()方法。然后在其中的一个方法中调用另一个方法,这样就可以做到合二为一。

HelloWorld.java可以改写为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.voidking.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloWorld extends HttpServlet {
protected void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException,IOException
{
PrintWriter pw = res.getWriter();
pw.println("HelloWorld");
}

protected void doPost(HttpServletRequest req,HttpServletResponse res) throws ServletException,IOException
{
doGet(req, res);
}

}

Servlet进阶

在一个HTML文件中建立一个表单,里面有一个输入框,当客户输入内容后,提交到一个Servlet类,这个Servlet类取出客户输入的信息,并在HTML页面上显示该内容。

右击servlet项目下的WebContent,New,HTML File,命名为index.html,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Servlet进阶</title>
</head>
<body>
<form action="inputServlet" method="post">
请输入你想显示的内容:<input type="text" name="input"/></br>
<input type="submit" value="提交" />
<input type="reset" value="重置" />
</form>
</body>
</html>

在com.voidking.servlet包下新建InputServlet类,继承HttpServlet,内容如下:

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
package com.voidking.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class InputServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

public InputServlet() {
super();
}

protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
// TODO Auto-generated method stub
res.setCharacterEncoding("utf8");
req.setCharacterEncoding("utf8");

String input = req.getParameter("input");

PrintWriter pw = res.getWriter();
pw.println("<html><head><meta charset=\"UTF-8\"><title>");
pw.println("显示输入内容");
pw.println("</title><body>");
pw.println(input);
pw.println("</body></html>");
}

protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(req, res);
}

}

web.xml修改如下:

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
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd">
<display-name></display-name>
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>com.voidking.servlet.HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/helloWorld</url-pattern>
</servlet-mapping>

<servlet>
<servlet-name>InputServlet</servlet-name>
<servlet-class>com.voidking.servlet.InputServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>InputServlet</servlet-name>
<url-pattern>/inputServlet</url-pattern>
</servlet-mapping>
</web-app>

发布工程,访问:http://localhost:8080/servlet/

源码分享

https://github.com/voidking/servlet.git

JSP语法

数据定义

<%! 变量声明 %>,相当于Servlet类里面的变量声明。

程序块

<% 程序块 %>,相当于在Servlet类里面service()函数里。

表达式

<%=Java表达式 %>,相当于Servlet类里面service()函数里,PrintWriter调用println()函数。

注释

<%-- 注释内容[<%=表达式%>]-->,输出注释。
<%-- 注释内容--%>,隐藏注释。

指令

JSP指令用来提供整个JSP页面的相关信息和设定JSP页面的相关属性,如设定网页的编码方式、脚本语言及导入需要用到的包等。语法格式如下:
<%@ 指令名 属性名="属性值"%>

1、page指令
2、include指令
3、taglib指令

动作

1、<jsp:param>
2、<jsp:include>
3、<jsp:useBean>
4、<jsp:setProperty>
5、<jsp:getProperty>
6、<jsp:forward>
7、<jsp:plugin>

内置对象

1、page
2、config
3、out
4、response
5、request
6、session
7、application
8、pageContext
9、exception

参考文档

《Java EE基础实用教程》,郑阿奇主编