经过一段时间的学习,大致对JSP有了一定的了解,为了加深一些印象,就写了这一个总结,小弟是初学者,这篇东西肯定错误不少,如果哪位高手有兴趣浏览一遍的话,希望能指出其中的错误,我好改正,谢谢了!
1.web技术
因为网络速度越来越快,机器配置越来越好,网页已经不再是单调的将固定的资料显示给用户,而是能和用户交互,用户能通过网页将资料存储在服务器上,而网页也能因时因地因人,在一定条件下,发生动态的变化,我们把这种网页叫动态网页。
网页是放在服务器上的,用户要访问网页得使用一个浏览器比如微软的Internet Explorer,在浏览器中输入域名(DOMAIN),然后浏览器通过DNS等一些中转站,最后找到该网站的IP地址(当然也可以直接输入IP),接着浏览器向服务器发送请求(request),服务器接到请求后,对于静态网页则直接返回这个静态文件如HTML文件(响应response),如果是动态网页则交由Container或解释器编译执行,最后将执行后生成的文件响应给客户端,客户端收到文件后将其解释并显示。
大致过程如下
Client--requestàserverà[Containerà[convert to Servlet(转译)àCompilerà]executeà] server—responseàClient
我们把这种程序,叫做基于服务器Server/客户端Client(C/S)的Web应用程序
竟然是一台机器(C)与另一台机器(S)进行通信、传输,那么肯定少不了一种协议,现在使用的是一种叫HTTP(HyperText Transport Protocol 超文本传输协议)的协议.它的默认端口是:80端口,因为80是默认端口,所以我们使用HTTP时可以不显示指定端口,比如http://csdn.net/而不用http://csdn.net:80/,当然后者也是有效的。
HTTP是一种无状态协议,也就是说,发送请求后,就与服务器建立链接,并将请求发送给服务器,但在响应完毕后立即就断开了。
客户端发送给服务器的请求是一串文本信息,它们包含一些信息如下:
请求行:包括请求方法(GET/POST)(在头文件中,提交方法必须为大写),统一资源标识符URI,HTTP的版本
头信息:包含了客户端的浏览器,操作系统,还有一些其他信息。最后接上一个空行表示请求信息结束
而服务器发送响应结构如下:
状态行:包括HTTP的版本,状态码(200=成功,404=找不到页面)
头文件:包括服务器软件(Server),最后日期(Last-modifid),内容长度(Content-length),内容类型(Content-type)如text/plain(未格式化的文本文档)text/html(以格式化的文档)等信息
空行后接内容。
前面介绍了两种请求方法,GET和POST,它们有什么区别呢?
GET方法提交:使用此方法提交,将会把参数追加在地址中,如:http://mydomain.com/index.jsp?page=1,在这里page表示参数名,1表示此参数的值,此参数将会放在请求中,程序可以取到它,当然,用户也可以看到它,所以它是不安全的,所以在用户登录等需要对数据保密的地方,用它肯定不合适,并且不适合很大的数据。
POST方法:使用此方法提交,不会在domain后面追加任何数据,它将秘密的把数据发给服务端,它是安全的,并且适合传输大量的数据,但它也有一些弊端,比如用户无法获取提交后的地址。应在应用中灵活的选择合适的方法。
2.java web
标题中的JSP说的有些笼统,准确的说应该是基于JAVA 的WEB应用程序,一个java web应用程序应当包括:Servlet 、 JSP页面 、 JAVABEAN 等组成,还有 HTML 、图像等补助。
Java Web应用程序制定了一个固定的目录结构,其结构如下(请严格遵守大小写):
Root(应用程序跟目录,名字自定)
|..存放网页文件,JSP文件或其他一些文件
|../WEB-INF/
|..存放标签描述文件
|..web.xml 此文件是java web应用程序的配置文件
| ../classes/ 存放类文件
|../lib 放库文件(此文件夹以及下面的不是必须要求的)
|../tags 放标签文件
程序完成后,可以将上面的文件夹打成一个.war包进行发布。
Servlet
Servlet被翻译成小服务器应用程序,它是在服务器上通过Container(容器)执行的java程序,它将用户的请求做处理后按照程序返回响应,而我们就是要用它来制作java web应用程序。它已经出现了很长一段时间了,并且先于J2EE出现。
编写Servlet程序可以使用几乎所有的JAVA API,所以它的强大是毋庸置疑的,Servlet初始化后,将驻留在内存当中,只需要创建其实例一次,每次得到请求时无需重新加载所以它拥有极好的效率,而且连JSP都是基于此技术架构的。
我们可以把Servlet看成是用java写的CGI,并且它比CGI更快更强大,因为CGI对每个请求都开启一个实例,而Servlet是所有请求共用一个Servlet实例.
编写一个Servlet我们需要使用到的类和接口(部分):
类:
HttpServlet:我们几乎所有的Servlet都继承至此类,通过实现它的方法来实现我们的Servlet程序。
接口:
HttpServletRequest:请求接口,用户发送请求后,容器将此对象以参数的方式传递个给此Servlet的service()方法
以下列出此接口的常用方法:
String getParameter(String paramName)
获取一个请求中的参数,这些参数来自用户表单中提交过来的东西或通过地址追加的参数,如前面说的: http://mydomain.com/index.jsp?page=1,如果paramName填写的是”page”的话,将得到” 1” ,这个字符串.
Enumeration getParameterNames()
它返回一个Enumeration对象,这个对象里面存放了本次提交中所有的参数名字
void setAttribute(String attributeName,Object value)
将一个属性对象设置到此提交对象的指定位置,如果此Servlet还有提交操作的话,将会把此属性一起传到下一个程序或页面,如果没有提交关系则自动回收,注意:如果中间的提交关系中断则会将它回收。
Object getAttribute(String attributeName)
根据指定属性名字取得此对象中的属性
void removeAttribute(String attributeName)
删除此对象中的指定属性
HttpServletResponse:响应接口,用户发送请求后,容器将此对象作为参数传递给service()方法,Servlet的编写者通过此对象来设置响应的内容,设置完毕后容器将此对象转换为响应信息发送给客户端
以下给出此类的常用方法:
java.io.PrintWriter getWriter()
获得一个PrintWriter对象,用于输出内容。(这些内容将会显示在用户的浏览器上)
void sendRedirect(String location)
转向location指定的地址
HttpServletRequest 和 HttpServletResponse 都有一个setCharacterEncoding(String encoding ) 通过将参数encoding设置为”gbk”来达到中文编码的目的(如果你的程序显示出来的结果是乱码,请用这个方法现设置编码)
ServletConfig:执行Servlet时,容器会将此接口的实例作为参数传递给此Servlet的init()方法,在Servlet的属性中有一份,可以通过此接口的getServletConfig()方法来获得,通过它可以得到初始化参数(在web.xml中配置的),Servlet上下文,Servlet的名字。
java.lang.String getInitParameter(java.lang.String name)
java.util.Enumeration getInitParameterNames()
从名字上就可以看出,第一个是根据初始化参数的名字获得初始化参数,第二个是获得所有初始化参数的名字。
ServletContext:Servlet上下文,整个Servlet只有一份它的实例,它的生命周期是整个Servlet的存活期,通过它的一些方法可以与服务器交互,读文件或者是编写日志,当然我们最常用它来存放一些对象,以便这个Servlet甚至整个容器中所有的用户共享这些数据。
java.lang.Object getAttribute(java.lang.String name)
和前面一样,取得此对象的属性
java.util.Enumeration getAttributeNames()
取得所有属性的名字
void setAttribute(java.lang.String name, java.lang.Object object)
设置一个属性对象
void removeAttribute(java.lang.String name)
删除一个属性
void log(java.lang.String msg)
写一条日志到容器
ServletContext getContext(java.lang.String uripath)
根据uripath取得容器中其他Servlet上下文
RequestDispatcher:协作类:协作类用来于其他页面或程序结合,通过它可以进行转发和包含操作。
void forward(ServletRequest request, ServletResponse response)
void include(ServletRequest request, ServletResponse response)
从名字上就可以看出,第一个是带着request和response跳转到指定页面,第二个是将指定内容包含进来,附一段代码:
request.getRequestDispatcher("index.jsp").forward(request, response);跳转到index.jsp
request.getRequestDispatcher("index.jsp").include(request, response);将index.jsp包含进来
若想研究上面类的详细信息,可以在J2EE 1.3.1A PI帮助文档找到
HttpServlet类详细介绍
竟然我们要编写的Servlet要继承自HttpServlet类,自然要对其进行全面的了解,下面我们来通过此类来解析java Servlet的开发。
首先说一说Servlet的生命周期。
用户发出请求àContainer实例化用户访问的Servletà由容器调用service()方法并进行响应à释放使用中的资源à从内存中释放此Servlet
了解了这个生命周期后,看看在这个周期中执行的方法以便我们了解如何制作Servlet:
构造方法:
在帮助文档中我们可以看到他的构造方法中写着这样一句话:Does nothing, because this is an abstract class.所以我们无法直接实例华它,它只能被容器实例化。
它一共有21个功能方法,然而我们并不要用到这么多,我们只需要使用其中很少的几个方法,所以我在这里不必把它们如数家珍一样,只介绍几个重要的方法:
void doGet(HttpServletRequest req,HttpServletResponse resp)
如果请求采用GET方法提交,将调用这个方法,一般我们的程序主要就是在这里或下面的doPost()方法中执行了。
void doPost(HttpServletRequest req,HttpServletResponse resp)
当提交方法为POST时调用
void init(ServletConfig config)
Servlet实例化后,立即调用此方法,并传入一个config对象
void destroy()
Servlet即将销毁时调用这个方法,一般用它来释放使用过的资源
其实我们常用(这里的用是指重写,而不是调用)的也就这四个方法,甚至在大多数情况我们根本就只需要使用前面两个。
再介绍几个,虽然它们不是最常用的:
void doPut (HttpServletRequest req,HttpServletResponse resp)
客户传输文件时调用此方法
void doDelete (HttpServletRequest req,HttpServletResponse resp)
它允许客户端发送请求来删除服务器上的文件或web页面
void doOptions (HttpServletRequest req,HttpServletResponse resp)
处理Options调用,返回Servlet不支持什么方法
void doTrace (HttpServletRequest req,HttpServletResponse resp)
处理Trace请求,主要用来调试它不可以被覆盖
void doHead (HttpServletRequest req,HttpServletResponse resp)
它用于处理客户端的Head请求(客户端只需要响应的头时),并返回一个响应对象,一般用它来检查链接或取得MIME、长度等信息
……
等等,前面老说service()这个方法,它到底是什么?这里怎么没有?其实我们使用HttpServlet一般不直接调用service()这个方法,而是重写doGet()、doPost()..这些doXXX()方法,我们可以把它们看成service()方法。
前面介绍了Servlet的生命周期,下面看看方法的执行过程:
init()àservice()àdestroy()
web.xml 文件
在我们的程序中,它是我们程序的配置文件,这个文件是至关重要的,因为容器是通过它,来找到我们的Servlet、Servlet初始化参数、以及后面要介绍的Filter等,所以我们每编写一个Servlet都要在此文件中做一些配置、映射。
从扩展名可以得知此文件是一个xml格式的文件,它的结构如下:(这里只是配置Servlet,它还有很多的配置项,这些配置标签都是小写,不能是大写)
<?xml version=” 1.0” encoding=”UTF -8” ?>
<web-app>
<servlet>
<servlet-name>(Servlet名字比如:)Hello</servlet-name>
<servlet-class>(类地址)my.Hello</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>(Servlet名字比如:)Hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
通过上面的设置,我们可以通过下面这个地址访问我们的servlet
http://localhost:80/Root/hello
其中Root表示我们工程的根目录,而hello是通过<url-pattern></url-pattern>设置的映射地址