servlet学习笔记一

Servlet
一、基本概念
我们的程序根据是否需要访问网络,可分为网络程序和非网络程序。而
网络程序又分为B/S结构和C/S结构。
什么是C/S?即客户端(Client)/服务器(Server)模式。这种模式的
客户端需要安装一个胖客户端(RCP)的程序,与服务器进行通讯交换数据。比
如:QQ、迅雷、视频播放器等。
优点:
1.C/S架构的界面和操作可以很丰富。
2.安全性能可以很容易保证,实现多层认证也不难。
3.由于只有一层交互,因此响应速度较快。
缺点:
1.适用面窄,通常用于局域网中。
2.用户群固定。由于程序需要安装才可使用,因此不适合面向
一些不可知的用户。
3.维护成本高,发生一次升级,则所有客户端的程序都需要改变。
什么是B/S?即浏览器(Browser)/服务器(Server)模式。一般的网站都
是B/S结构的,比如:Google、Baidu、购物网站、交友网站、网上营业厅等。
优点:
1.客户端无需安装,有Web浏览器即可。
2.可以直接放在广域网上,通过一定的权限控制实现多客户访问的
目的,交互性较强。
3.无需升级多个客户端,升级服务器即可。
缺点:
1.在跨浏览器上,B/S架构不尽如人意。
2.前端表现要达到C/S程序的程度需要花费不少精力。
3.在速度和安全性上需要花费巨大的设计成本.(由于基于HTTP协议的)
这是B/S架构的最大问题。
4.客户端服务器端的交互是请求-响应模式,通常需要刷新页面,
这并不是客户乐意看到的。

Web访问的基本原理:
1.输入网址在浏览器
2.浏览器向服务器端发生请求
3.服务器端接收并处理请求生成处理结果(如HTML)
4.服务器将响应结果发送给浏览器
5.浏览器根据结果在浏览器中进行相应的显示。

HTTP超文本传输协议:
浏览器与服务器间的应用层通信协议,其基于TCP/IP协议之上。
通信过程:
1.建立连接(Socket)
2.发送请求消息
3.发送响应消息
4.关闭连接

静态页面与动态页面:
静态页面:显示内容保持不变
缺点:
不能即时消息,更新困难,不能满足用户多样性需求。
动态页面:
CGI:公用网关接口。服务器端的一个程序。
缺点:
每次请求启动一个系统进程且加载运行一个CGI程序,
开销大。
需重复编写处理网络协议的代码,麻烦,工作量大。
Servlet:改良后的CGI
缺点:
后台处理与前台显示不分离
JSP:
HTML+Servlet
二、环境搭建
1.JDK
2.Browser: chrome、firefox、ie.....
3.Web服务器:
IIS:支持ASP,或通过插件支持PHP
Apache:处理静态页面效率高
Tomcat:轻量级Java Web服务器,支持Servlet/JSP,插件支持PHP
不支持EJB
JBoss:开源的重量级Web服务器,良好支持J2EE各种规范
Weblogic和WebSphere:商业服务器
我们选择的是Tomcat。

主要的目录结构:
1)bin:放置的是启动和关闭tomcat服务器等这些命令,
包括windows和unix下面的俩类命令
2)conf:放置的是tomcat这个软件的配置文件
(1).context.xml
文件中描述了tomcat读取项目中的配置文件(web.xml)的路径
(2).server.xml
可以配置tomcat运行的时候所监听的端口号,以及这个端口号
上面绑定的协议,我们主要关注的是Http协议
(3).tomcat-users.xml:
tomcat为我们提供了一些用户,可以用这些用户登陆到tomcat中
去管理tomcat里面放置的javaWeb项目资源以及tomcat的一些属性
配置,我们还可以自定义一些tomcat用户
(4).web.xml
用来web应用程序配置信息:
比如Welcome页面、servlet、servlet-mapping、
filter、listener、启动加载级别等
3)lib:放置tomcat中的所有Web项目公用的jar包
4)logs:放置tomcat在运行中所产生的日志文件
5)temp:放置tomcat在运行中所临时文件
6)webapps:项目部署目录
7)work:和jsp的编译和运行相关的一个目录
配置环境变量:
CATALINA_HOME
path
eclipse引用
项目部署:
手动部署
WebTest——
|——WEB-INF
|——classes 自定义java类的字节码
|——lib 第三方jar包
|——web.xml
|——自定义目录
自动部署
ware包部署
三、Servlet
Java Web应用程序中的所有请求与响应都是由Servelet来完成的。
0.相关包:
javax.servlet
javax.servlet.http
1.三种创建servlet的方式
1.实现javax.servlet.servlet接口
必须实现5个方法
init(servletconfig config)
service(servletrequest req,servletresponse resp)
destroy()
getservletconfig()
getservletinfo()

2.继承javax.servlet.GenericServlet
提供了servlet接口的基本实现,所以他的子类都必须实现service()方法
3.继承 javax.servlet.http.HttpServlet
扩展了genericservlet并且提供了servlet接口中具体于http的实现,
它更象一个其他所有的servlet都要扩展的类
doGet():
dopost();
三者之间的关系

:

2.配置<servlet>
<servlet>
<servlet-name>定义servlet名字</servlet-name>
<servle-class>servlet类名</servle-class>
</servlet>
3.配置<servlet-mapping>
<servlet-mapping>
<servlet-name>定义servlet名字</servlet-name>
<url-pattern>访问servlet的url<url-pattern>
</servlet-mapping>
4.servlet的任务
1)读取客户端发送过来的显示或隐式的数据,如:表单数据、cookies、媒体类型等
2)处理数据并生成结果。该过程可能需访问数据库或直接计算出对应的相应
3)发送显示或隐式数据给客户端,如:html、image、cookies等
************************
Servlet中的细节问题:
************************
⑴一个已经注册的Servlet可以被多次映射即:
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <!-- servlet的注册名 -->
    <servlet-name>MyServlet1</servlet-name>
    <!-- servlet类的全路径(包名+类名) -->
    <servlet-class>com.hsp.servlet.MyServlet1</servlet-class>
  </servlet>
<!-- 对一个已经注册的servlet的映射 -->
  <servlet-mapping>
   <!-- servelt的注册名 -->
     <servlet-name>MyServlet1</servlet-name>
   <!-- servlet的访问路径 -->
     <url-pattern>/MyServlet1</url-pattern>
  </servlet-mapping>
-------------------------------------------  
  <servlet-mapping>
   <servlet-name>MyServlet1</servlet-name>
  <url-pattern>/hsp</url-pattern>
  </servlet-mapping>


⑵ 当映射一个servlet时候,可以多层 比如 
<url-pattern>/servlet/index.html</url-pattern> 
从这里还可以看出,后缀名是 html 不一定就是 html,可能是假象.

⑶使用通配符在servlet映射到URL中
有两种格式:
第一种格式  *.扩展名  比如 *.do  *.ss
第二种格式  以 / 开头 同时以 /* 结尾  比如  /*   /news/* 
通配符练习题:
l Servlet1 映射到 /abc/* 
l Servlet2 映射到 /* 
l Servlet3 映射到 /abc 
l Servlet4 映射到 *.do 

问题(面试题):
l 当请求URL为“/abc/a.html”,“/abc/*”和“/*”都匹配,哪个servlet响应
Servlet引擎将调用Servlet1。
l 当请求URL为“/abc”时,“/abc/*”和“/abc”都匹配,哪个servlet响应
Servlet引擎将调用Servlet3。
l 当请求URL为“/abc/a.do”时,“/abc/*”和“*.do”都匹配,哪个servlet响应
Servlet引擎将调用Servlet1。
l 当请求URL为“/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应
Servlet引擎将调用Servlet2。
l 当请求URL为“/xxx/yyy/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应
Servlet引擎将调用Servlet2。
 
在匹配的时候,要参考的标准:
(1) 看谁的匹配度高,谁就被选择
(2) *.do 的优先级最低

⑷Servlet单例问题
 
当Servlet被第一次访问后,就被加载到内存,以后该实例对各个请求服务.即在使用中是单例.
因为 Servlet是单例,因此会出现线程安全问题: 比如:
售票系统. 如果不加同步机制,则会出现问题:
所以我们一般遵循这样的原则:
(1) 如果一个变量需要多个用户共享,则应当在访问该变量的时候,加同步机制
synchronized (对象){
//同步代码
}
(2)如果一个变量不需要共享,则直接在 doGet() 或者 doPost()定义.这样不会存在线程安全问题

⑸ HttpServletResponse的再说明:
getWriter()
getOutputStream();
 
区别
1. getWriter() 用于向客户机回送字符数据
2. getOutputStream() 返回的对象,可以回送字符数据,也可以回送字节数据(二进制数据)
OutputStream os=response.getOutputStream();
os.write("hello,world".getBytes());
 
如何选择:
如果我们是回送字符数据,则使用  PrintWriter对象 ,效率高
如果我们是回送字节数据(binary date) ,则只能使用 OutputStream
☞ 这两个流不能同时使用.
比如:
OutputStream os=response.getOutputStream();
os.write("hello,world".getBytes());
PrintWriter out=response.getWriter();
out.println("abc");
就会报错:

java.lang.IllegalStateException: getOutputStream() has already been called for this response
 
这也是不能同时使用printWriter和outputstream的原因。
Web服务器会自动检查并关闭流
从中,我们也可以看出. 为什么我们没有主动关闭流,程序也没有问题的原因.
当然:你主动关闭流,更好.

⑹HttpServletRequest对象的详解
该对象表示浏览器的请求(http请求), 当web 服务器得到该请求后,会把请求信息封装成一个HttpServletRequest 对象
• getRequestURL方法返回客户端发出请求时的完整URL。
• getRequestURI方法返回请求行中的资源名部分。
• getQueryString 方法返回请求行中的参数部分(参数名+值)。
该函数可以获取请求部分的数据 比如
http://localhost/web名?username=abc&pwd=123
String str=request.getQueryString(); 就会得到  username=abc&pwd=123
 
getRemoteAddr方法返回发出请求的客户机的IP地址
getRemoteHost方法返回发出请求的客户机的完整主机名
getRemotePort方法返回客户机所使用的网络端口号
客户机的端口号是随机选择的,web服务器的端口号是一定的
getLocalPort方法返回web服务器所使用的网络端口号
getLocalAddr方法返回WEB服务器的IP地址。
getLocalName方法返回WEB服务器的主机名
u url 和 uri 的区别
比如:
Url=http://localhost:8088/servletPort3/GetinfoServlet 完整的请求
Uri=/servletPort3/GetinfoServlet web应用的名称+资源的名称

原文地址:https://www.cnblogs.com/Ant-soldier/p/5045968.html