JavaWeb 原理及其相关知识

Web服务器的作用

用于实时接收浏览器的请求,并将相应结果回送给浏览器。

对于静态 html 文件内容的访问请求,Web服务器 可以直接从文件系统中读取文件内容返回给浏览器。

但对于要根据某些条件去动态创建内容的访问请求,Web服务器本身不具备处理这种请求的能力,

而是需要专门的Web服务器程序模块来处理

因此,动态网页内容的创建过程包含两个步骤:首先使用某种编程语言写出相应的动态网页程序;

然后由一个专门的Web服务器程序模块来解释执行该动态网页程序。

引擎是什么?它是怎么和动态网页进行交互的?

专门解释执行某种动态网页的Web服务器程序模块习惯上被称之为引擎,如ASP引擎、JSP引擎、Servlet引擎

引擎以Web服务器的扩张模块的形式提供的。通常由那些提供动态网页解决方案的公司开发的。引擎要与动态网页进行通信,必须要提供一些API(Application Programming Interface编程接口)给动态网页程序使用。

引擎提供的API有哪些作用?

将请求的相关信息传递给动态网页,例如访问者的IP地址和请求消息头。
将动态网页程序产生的结果传递给引擎。

引擎的作用?

只有引擎才会与浏览器直接进行信息交互。动态网页程序不直接与浏览器进行信息交交互,他只与引擎进行信息的交互,动态网页程序需要一个专门的Web服务器程序模块来解释执行(引擎)。

Web容器是什么?

Servlet是一个供其他Java程序(Servlet引擎)调用的Java类,他不能独立运行。

Servlet与Servlet引擎之间的关系就如Applet与Web浏览器之间的关系一样。

Servlet的运行完全由Servlet引擎控制来调度。

Servlet引擎是一种容器程序,他负责管理维护所有的Servlet对象的生命周期。因此也被称之为Web容器或Servlet容器。

Web服务器与Web容器的区别?

Web容器也就是某种引擎,引擎以Web服务器的扩张模块的形式提供的。Web容器是Web服务器的一种能力,是他的一个模块。

什么是Servlet

Servlet技术是Sun公司提供一种实现动态网页的解决方案,它是基于java编程语言的Web服务器端编程技术。

主要用于在Web服务器端获得客户端的访问请求信息和动态生成客户端的响应消息。Servlet技术也是JSP技术的基础。

ServletConfig接口

Servlet引擎将代表Servlet容器的对象和Servlet的配置参数信息一并封装到一个成为ServletConfig对象中

并在初始化Servlet实例对象(通过init(ServletConfig config)方法)时传递给该Servlet。

ServletConfig接口则定义了ServletConfig对象对外提供的方法。

GenericServlet类实现ServletConfig接口目的

虽然可以Servlet.getServletConfig.ServletConfig方法。

为了Servlet程序更方便的访问ServletConfig的各个方法。

GenericServlet与HttpServlet类

GenericServlet是一个实现了Servlet接口的基本特征和功能的基类

HttpServlet是GenericServlet的子类,他提供了处理HTTP协议的基本架构。

如果一个Servlet要充分利用HTTP协议的功能,就应该继承HttpServlet。

所以HttpServlet不仅可以调用内部新定义的方法还可以调用Servlet、GenericServlet、ServletConfig类中定义的方法。

区分回调方法和工具方法

专门用于系统调用的方法被称之为回调方法,也就是会过来被系统调用的方法。

GenericServlet和HttpServlet类中的回调方法是供容器调用的方法,可以在子类中进行覆盖,但是不能在程序代码块中直接调用。

GenericServlet和HttpServlet类中处理有回调方法还有工具方法,编程人员可以在程序代码块中直接调用去完成某种任务。

如GenericServlet中的log方法用于将一条信息记录到日志文件中。

ServletContext类

每一给Web应用程序都是一个独立的Servlet容器,每一个应用程序分别用一个ServletContext对象表示。

ServletContext接口定义了ServletContext对象对外提供的方法,Servlet程序通过这些方法与Servlet容器进行通信。

Servlet引擎为每一个W恶补、应用程序都创建一个对应的ServletContext对象。

ServletContext对象被包含在ServletConfig对象中。

关于server.xml和web.xml

在server.xml文件和web.xml文件中都可以为某个Web应用程序设置若干个初始化参数。

比如,如果一个Web应用程序中的多个Servlet程序都要输出当前站点的公司名称,

而这个Web应用程序可能会交给多个公司使用,那么我们可以把公司名称作为初始化参数进行设置,

那么只需要在web.xml文件中修改公司名称,所有的Servlet程序输出的公司名称就会随之更改。

如果要在server.xml文件中为某个web应用程序设置初始化信息,

需要在该web应用程序所对应的<Context>元素增加<Parameter>子元素。

ServletContext记录日志

ServletContext接口中定义了两个重载的log方法类记录日志。

GenericServlet类中也定义了两个log方法。他们分别调用ServletContext对象中对应的log方法。

log方法记录日志文件名称和存储路径因web服务器而定,

Tomcat中的日志文件的存储路径和server.xml文件中进行设置。

<Logger className="" directory="" prefix="" suffix="" timestamp="true">.

获取虚拟路径所映射的本地路径:

ServletContext接口中定义了一个getRealPath()方法,用于返回某个虚拟路径所映射的本地文件系统路径。

如果传递给getRealPath方法的路径字符串以"/"作为起始字符,这个“/”代表的是当前Web应用程序的根目录,

要返回Web应用程序的根目录所映射的本地文件路径系统,

传递给getRealPath()方法的路径字符传中可以只有一个“/”字符,也可以是一个空字符串。

HttpServletResponse对象

如果一个网页查看源文件的中文没有乱码,而显示是乱码,可能是因为浏览器显示网页的字符编码有问题。

Java程序的字符文本在内存中是以unicode编码的形式存在的

ServletResponse对象的getWriter方法返回的PrintWriter对象默认使用ISO8859-1字符编码进行unicode字符串到字节数组的转换。

然而ISO8859-1字符集里又没有中文字符,Unicode编码的中文被被转换成无效的字符编码后输出给客户端。

可以使用 setCharacterEncoding、setContentType和setLocale 等方法指定 ServletResponse.getWriter 对象所使用的字符编码。

response控制定时刷新

让浏览器定时刷新网页或跳转到其他页面。HTTP协议中定义了一个Refresh头字段。

response.setHeader("Refresh", "2;URL=/zhangxiaoxiangbook1/index.jsp");
response.setHeader("Refresh", "2");

禁止浏览器缓存当前文档内容

有三个HTTP响应头字段都可以禁止浏览器缓存当前页面。
response.setDateHeader("Expires",0);
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragam","no-cache");

不是所有的浏览器都能完全支持这三个响应头。最好是同时使用。

使用<meta>标签模拟响应消息头。

利用HTTP消息的响应头字段,可以让浏览器完成各种有用的功能,例如不想让浏览器缓存一个内容经常要被更新的静态HTML页面,那么可以在他的<head></head>标签之间增加如下三条语句:


    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">


然而,如果在网页正文增加如下语句:<meta http-equiv="Refresh" content="0;url=http://www.baidu.com">

当浏览器打开这个网页文档之后,将立即跳转到 www.baidu.com 站点的首页。

<meta>标签的一个最常见的作用就是用来设置当前网页的字符编码。当我们访问中文网站的静态的页面时候,

只要查看他的源文件基本上都包含如下<meta>语句:<meta http-equiv="content-type" content="text/html; charset=UTF-8">

他会暗示浏览器用什么编码显示网页。每个静态中文HTML页面的开始出都应该增加一条<meta>语句来设置页面的字符集编码,已经成为设计HTML页面的指导性原则和验收标准。

 

ServletResponse输出方法

ServletResponse是Servlet程序和Servlet引擎进行通信的接口,Servlet程序通过ServletResponse对象将响应正文传递给Servlet引擎,再由Servlet引擎将响应正文输出到客户端。

如果两个模块之间要传输大量的数据。最好是以输入或者输出流来作为两个模块传递数据的接口方式。

response.getOutputStream 方法返回的字节输出流对象类型为ServletOutputStream,ServletOutputStream是OutputStream的子类,它可以直接输出字节数组中的二进制数据。如果Servlet要输出二进制格式的响应正文,就应该使用此方法。

response.getWriter 方法将Servlet引擎的数据缓冲区包装成PrintWriter类型的字符输出流对象后返回。PrintWriter对象可以直接输出字符文本内容,所以他专用来输出内容全为文本字符的网页文档。

以上2个方法不能同时使用。

最好在使用PrintWriter或ServletOutputStream对象之前调用HTTP的响应头信息的方法,特别要注意设置MIME类型的Content-Type头字段。

最后要注意的是,Servlet的service方法结束后,Servlet 引擎将检测getWriter或getOutputStream方法的输出流对象是否已经调用close方法,如果没有调用,service引擎会自动关闭。最好还是开发人员自己关闭,以便尽快的释放相关资源。

Servlet程序中可以多次调用HttpServletResponse对象的getWriter方法吗?如可以是否是同一个对象?

可以,是同一个对象。ServletOutputStream也是一样。

PrintWriter.print方法和PrintWriter.println方法有什么区别?

在html显示的时候没有什么区别。只是查看源文件的时候,有如果是PrintWriter.println他会自动换行,以便员阅读和理解。

输出缓冲区

Servlet程序输出的HTTP消息的响应正文不是直接发送到客户端,而是首先被写到了Servlet引擎提供一种输出缓冲区中。

这个缓冲区被填满或者Servlet程序已经写入了所有响应内容,缓冲区中的内容才会被Servlet引擎发送到客户端。

使用缓冲区那些好处?

Servlet引擎就可以将响应状态行、各响应头和响应正文严格按照HTTP消息的位置顺序进行调整后再输出到客户端,

特别是可以自动对Context-Length头字段进行设置和调整,如果不使用输出缓冲区,

Servlet请亲无法在向客户端输出响应正文之前知道响应正文的大小,也就不能自动设置Context-Length头字段。

如果在提交响应到客户端时,输出缓冲区载入的内容只是全部响应的一部分,

那么Servlet引擎将无法再计算Context-Length头字段,

他将使用HTTP1.1的chunked编码方式(通过设置Transfer-Encoding头字段来指定)传输响应内容,

这样就不用设置Context-Length头字段了。

ServletResponse定义了若干输出缓冲区有关的方法:

  1.  setBufferSize() 用于设置期望的输出缓冲区大小,Servlet引擎实际使用的缓冲区不一定等于该值,但不会小于他。
  2. getBufferzsize()用于返回Servlet引擎实际使用的缓冲区大小。
  3. flushBuffer()用于将缓冲区的内容强制输出到客户端,
  4. reset()用于清空输出缓冲区中的内容,以及设置的响应状态码和各个响应头。如果当前响应已经向客户端输出过部分内容,将会抛出异常。要注意区别flushBuffer(),flushBuffer()将缓冲区的内容提前交给客户端后腾出缓冲区空间,reset()是将缓冲区的内容作废后腾出缓冲区空间。
  5. inCommitted()判断是否已经提交部分响应内容到客户端,如果已经提交返回true,反之false。

 

JSP的基本语法

JSP表达式(expression)

JSP表达式(expression)提供了将一个java变量或表达式的计算结果到客户端的简化方式,

jsp表达式中的变量或表达式后面不能有分号(;),jsp表达式被翻译成Servlet程序中的一条out.print(...)语句。

如<%=new java.util.Date()%>翻译成Servlet程序中的一条out.print(new java.util.Date())语句

JSP脚本(scriptlet)

JSP脚本(scriptlet)是嵌套在<%和%>之间的一条或多条java程序代码。

在jsp脚本片段中,可以实现定义变量、执行基本的程序运算、调用其他java类等普通java程序所能实现的功能。

在jsp脚本片段中必须符合java语法要求的程序代码。在一个jsp页面中可以有多个脚本片段。

注意:单个脚本片段中的java语句可以不是完整的,但是多个脚本组合后的结果必须是完整的java语句吗,例如条件语句或循环控制语句。

因为所有的脚本片段中的java代码将原封不动的搬进由jsp页面所翻译成的Servlet的_jspService方法中。

JSP声明(declaration)

JSP页面最终会编译成Servlet程序。在脚本片段声明的变量是局部变量。

如果在脚本中定义方法,也会被搬进_jspService()中,这样就会变成方法里嵌套方法的错误。

而jsp声明就是解决这样的错误,他将代码封装子在<%!和%>中,他写的代码将插在_jspService()之外。

jsp声明只能定义静态代码块,方法和变量的定义.由于jsp内置对象的作用范围只限于Servlet的_jspService()方法内。

jsp指定(directive):

page、include、taglib.

out对象

如果out.println语句位于response.getWriter().println语句前,但是输出的内容却位于后者输出的内容之后

这是因为out.println语句只是把内容写入到out对象的缓冲区中,知道整个jsp页面结束时,

out对象才把他的缓冲区里的内容真正写到Servlet引擎提供的缓冲区中,

而response.getWriter().println语句则是直接把内容写到Servlet引擎提供的缓冲区中。

注意:在如下jsp中
<%    

ServletOutputStream sos=response.getOutputStream();
sos.println("dddddd");
%>

如果在此jsp中的最开始的“<%”前面或者最后的“%>”后面输入了任意字符,例如在最后的“%>”后面输入了一个回车键,用浏览器中显示,就会报异常。

因为位于jsp脚本元素之外的任何字符文本,在jsp页面所翻译成的Servlet源文件中都要被转换成以这些字符文本作为参数的out.write语句输出到客户端,

即使在jsp脚本元素之外输入的是一个回车符,它也将被转换成一条out.write("\r\t");语句。

由于只要向out对象中写入了内容,它就会在jsp页面结束时调用ServletResponse.getWriter方法,

这就与程序中调用的response.getOutputStream方法发生了冲突。

<%
    RequestDispatch rd = application.getRequestDispatch("test.html");
    rd.forword(request,response);
%>

如果在此jsp中的最开始的“<%”前面或者最后的“%>”后面输入了任意字符,例如在最后的“%>”后面输入了一个回车键,用浏览器中显示,就会报异常。

因为客户端对静态HTML文件和图片的访问请求都是由Tomcat的缺省Servlet开处理,缺省的Servlet首先检查是否已经调用过当前HttpServletResponse对象的getWriter对象,

如果调用,则使用getWriter方法返回的PrintWriter对象输出HTML文件中内容,否则,缺省的Servlet调用getOutputStream方法返回的servOutputStream对象来将静态HTML文件中的内容按按字节流的形式原封不动地输出到客户端。

上面的jsp文件将请求转发给test.html页面时,还没有真正调用过ServletResponse.getWriter方法,缺省的Servlet将调用ServletResponse.getOutputStream方法,

缺省的Servlet处理完之后,程序又回到jsp页面中继续执行,因为jsp页面随后又向out对象中写入了内容(回车符造成的“\r\t”)

所以jsp页面结束时又将调用ServletResponse.getWriter方法,这就造成冲突。

如果在jsp页面的jsp脚本片段中的第一句前面增加如下一条语句:response.getWriter();

pageContext对象

pageContext对象是javax.servlet.jsp.PageContext类的实例对象,

pageContext对象封装了当前jsp页面的运行信息,他提供了返回jsp页面的其他隐式对象的方法。

获得其他隐式对象:

  • getException方法返回exception隐式对象;
  • getPage方法返回page隐式对象;
  • getRequest方法返回request隐式对象;
  • getResponse方法返回response隐式对象;
  • getServletConfig方法返回config隐式对象;
  • getServletContext方法返回application隐式对象;
  • getSession方法返回session隐式对象;
  • getOut方法返回out隐式对象;

JSP标签

<jsp:include>标签用于把一个资源的输出内容插入进当前jsp页面的输出内容之中。
<jsp:forword>标签用于把转发给另一个资源。page用来指定请求转发到的资源相对路径。
<jsp:param>标签用于当使用<jsp:include>、<jsp:forword>
标签引入或将请求转发给的资源是一个能动态执行的程序时,例如Servlet和jsp页面,那么还可以使用<jsp:param>标签想这个程序传递参数信息。如:
<jsp:include page ="">
    <jsp:param name="" value=""/>
</jsp:include>

脚本元素标签:jsp2.0规范定义了一些标签页面中的脚本片段、jsp声明和jsp表达式,以便这些脚本元素可以采用XML的语法编写:
  ·<%%>可以代替为<jsp:scriptlet></jsp:scriptlet>
  ·<%!%>可以代替为<jsp:declaration></jsp:declaration>
  ·<%=%>可以代替为<jsp:expression></jsp:expression>

指定标签:jsp2.0规范定义了<jsp:directive.directiveType>来代替<% @ directive...%>以便采用XML格式来定义jsp指定。如:
<%@ page import=""%>可代替为<jsp:directive.page import=""/>

JSP中文乱码问题

当jsp引擎要确定某个jsp文件的字符集编码时,首先在web应用程序的部署描述符中查找是否有于jsp文件匹配的<page-encoding>元素设置。如果没有找到则往下找:
page指定的pageEncoding属性--->page指定的contextType属性中查找字符集编码--->使用ISO-8859-1。
   在web.xml文件中输入如下代码:
<jsp-config>
    <jsp-property-group>
        <url-pattern>/jsp/*</url-pattern>
        <page-encoding>GB2312</page-encoding>
    </jsp-property-group>
</jsp-config>

需要注意的是:web.xml文件中没有声明它所遵循的Servlet规范版本,Tomcat默认它遵循Servlet2.3规范,而jsp-cofig、jsp-proprty-group和page-encoding等元素是在Servlet2.4规范的部署描述文件中新定义的元素,所以上面配置的<jsp-config>元素及其中的内容不会生效。需要声明web.xml文件遵循Servlet2.4规范(可以在文档复制)。

处理get方式提交乱发问题

①String name = request.getParameter("name");
可以使用new String(name.getBytes("ISO-8859-1"),"gbk");

②在Tomcat的server.xml文件中修改,为get方式获取数据添加URIEncoding参数指定utf-8(默认为iso-8859-1):
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8433" URIEcoding="utf-8"/>
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chiclaim

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值