Servlet笔记(1)

Servlet的生命周期如下

1.实例化,Servlet容器创建Servlet创建Servlet实例,这里的容器就是指tomcat
2.初始化,该容器调用init()方法,完成加载servlet所需资源
3.处理请求,如果请求Servlet,则容器调用service方法,业务逻辑放在这里
4.销毁,销毁实例之前调用destroy()方法


Servlet的几个方法如下:

init()
getServletConfig()
service()
getServletInfo()
destory()


Servlet的web。 xml中的一些配置信息的理解

<servlet>
<servlet-name>abc</servlet-name>
<servlet-class>com.jxust.Hello</servlet-class>   //需要注意的问题是这里需要加上包名,在同级目录下的!!
</servlet>


//当访问的是一个servlet的一个项目的时候,会先找到下面的东西
<servlet-mapping>
<servlet-name>abc</servlet-name>   //这里的名字要和<servlet>中的名字相同,因为要根据这个去找对应的类的文件.class,这就是映射的思想
<url-pattern>/abc</url-pattern>    //这里是你在网址栏需要输入的访问路径
</servlet-mapping>


//注意:在url访问的时候,除了需要输入/abc外,还要在前面加上/Hello
因为这是个项目文件夹
http://localhost:8080/hello/aaa
注意:在找到那个需要的类的class文件的时候,tomcat才给它分配实例。




二:

关于URL匹配的问题

1.精确匹配
2.最长路径匹配
3.扩展名匹配


也就是说,/abc和/*会先匹配/abc
/abc/*和/abc/aaa会匹配后者
/abc/ab.do和/abc/*会匹配后者
/*和/ab.do会匹配前者,因为最先满足的精确匹配和最长路径匹配都在拓展名匹配的前面,扩展名的优先级别最低


三:关于返回值为Enumeration的ServletConfig对象的实例方法getInitParameterNames()的问题

先来看完整的源代码
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


response.setContentType("text/html");
PrintWriter out = response.getWriter();
ServletConfig config1 = this.getServletConfig();
Enumeration str_c =config1.getInitParameterNames();
while(str_c.hasMoreElements()){
String name = (String) str_c.nextElement();
String value = config1.getInitParameter(name);
out.write("<br>");
out.write(name+" = "+value);
}


我需要得到的web.xml中的<init-param>中<param-name><param-value>的值
<init-param>
            <param-name>shenmeshenqi</param-name>
            <param-value>123456</param-value>
</init-param>
这个是放在<servlet></servlet>里面的


然后使用上面的代码,这些方法,需要牢记,类似迭代器的编程思想




四:设置在服务器打开的时候就初始化(INIT调用)方法

在web.xml文件里加入<load-on-startup>0</load-on-startup>
0是时间,可以是1,也可以是其它数字


五:http请求格式

1.请求行,只有一行
2.请求头,有多个
3.空行
4.请求体 一般用来传数据的,例如form表单post的提交,如果是get的提交,数据放在了请求行里面


请求头的格式详解:
头标记          值          说明
Accept      text/html,      浏览器可接受的MIME类型,
            application/    也就是可接受的文件类型
            xhtml+xml,*/*


Accept-Charset   iso-8859-1(这个只支持英文,tomcat里面默认是这个)     浏览器可接受的字符集


Accept-Encoding  gzip,deflate    浏览器能够接受的压缩编码方式,gzip和deflate几乎相同


Accept-Language  zh-CN            浏览器指定的语言 


Cache-Control(缓存控制)    no-cache(没做缓存控制)    网页缓存


Connection        Keep-Alive(保持连接)          保持连接,发送数据后不关闭连接


Content-Length       12                   请求消息正文的长度


Cookie             ...                   保存的cookie对象


Referer(就是指来自于那里)        http://....                包含一个URL,用户从该URL代表的页面出发访问当前请求的页面,可以防止非法访问
比方说从当前的页面访问/abc等,这个当前的页面就是Referer


User-Agent              各种浏览器内核                 浏览器类型,可以通过这些来判断客户端浏览器版本


if-Modified-Since:
If-Modified-Since是标准的HTTP请求头标签,
在发送HTTP请求时,把浏览器端缓存页面的最后修改时间一起发到服务器去,
服务器会把这个时间与服务器上实际文件的最后修改时间进行比较。
整个过程可以这样理解:
我先get到了一个html静态页面,服务器返回给你的是200,
这时候会在浏览器中产生一个缓存,并且,服务器返回给你的头标签上有一个
最后的修改时间,当你再次get这个页面的时候,会把最后修改时间也就是if-Modified-Since里的
时间和服务器上html页面的最后修改时间做比较,如果说是相同的,
就直接在本地缓存里面去应用这个html,就不用加载了,服务器会返回304.
假如,我尝试改变这个html的内容,那么最后的修改时间就变了,
和服务器上的时间不一样,这样,就会重新get一个,返回200.
详细参考:http://www.cnblogs.com/zh2000g/archive/2010/03/22/1692002.html




六:关于表单以及表单提交的前后端交互问题

首先,明确一点,我们的写入流的问题
使用PrintWriter out=response.getWriter();
这个一定要牢记,因为这是最普遍的方法。


1.用户名密码的表单前端页面和后台交互
前端页面代码
<form action="hello/testhello" method="POST">
用户名:<input type="text" name="user"/><br>
密码:<input type="password" name="pw"/><br>
<input type="submit" value="注册">
</form>


后台交互代码
PrintWriter out = response.getWriter();
//从request中来取得前端传来的http请求体
Enumeration names= request.getParameterNames();
while(names.hasMoreElements()){
String s = (String)names.nextElement();
String value = request.getparameter(s);
out.write(s +" : "+ value);
}


2.使用单选按钮,多选框,以及下拉列表的问题
前端页面代码
<form action="hello/testhello" method="POST">
用户名:<input type="text" name="user"/><br>
密码:<input type="password" name="pw"/><br>
性别:<input type="radio" name="sex" value="男"/>男
<input type="radio" name="sex" value="女"/>女<br>
爱好:<input type="checkbox" name="behave" value="音乐"/>音乐
<input type="checkbox" name="behave" value="英语"/>英语
<input type="checkbox" name="behave" value="编程"/>编程<br>
所在城市:<select>
<option>北京</option>
<option>上海</option>
<option>广州</option>
</select>


<input type="submit" value="注册">
</form>
注意的问题是:在写单选框的时候,必须使得name的值相同,否则就是两个不同的组了,就可以同时选择两个单选框了。
前端主要是依靠name和value的值来传递给后台,后台根据这些值来进行数据的提出


后台交互代码


Enumeration names = request.getparameterNames();
while(names.hasMoreElements()){
String name=(String)names.nextElement();
String value= request.getParameter(name);//这里如果name里具有多个值的话,比如说,爱好对应的name是behave,但是里面是多选的,有
//可能具有多个值,所以得将它拿出来单独判断
if (!name.equals("behave")){
out.write(name+":"+value);
}
}
String [] checkbox_value = request.getParameterValues("behave");
out.write("爱好是");
for(String s : checkbox_value){
out.write(s);
}




七:得到客户端或者是服务器端的信息的一些方法

//得到客户端信息
String addr = request.getRemoteAddr(); //得到客户端地址
String host = request.getRemoteHost();//得到主机地址
StringBuffer url = request.getRequestURL();//得到请求url,这是完整的url路径
int port = request.getRemotePort();//得到客户端端口


//得到服务器信息
String name = request.getServerName();//得到服务器的名称,一般来说就是域名 
int sPort = request.getServerPort();//得到服务器端口


//其它
String protocol = request.getProtocol();//得到请求的协议
String type = request.getContentType();//得到内容的类型
int length = request.getContentLength();//得到内容的长度




八:请求转发,不同的servlet之间的数据共享

1.什么叫做转发
在一个servlet中将一个请求给了另外一个servlet,这就是请求转发,这可以使得不同的servlet去共享数据信息
但是,需要注意,做了请求转发的servlet是不进行response的,也就是在里面写任何有关于给客户端响应的
代码都会失效,比如说类似out.write()这种。
2.怎样去做转发
在一个继承servlet的类中去写转发代码
request.setAttribute("a","2");//设定属性的值,这里就是类似于map的键值对方式来传数据
request.setAttribute("什么神奇","天才");
RequestDispatcher zhuanfa = request.getRequestDispatcher("/publics");//括号里的
//参数是你的要转发的同一个项目中的(只能同一个项目另外一个servlet的路径,因为我这里是同级的
//所以直接写了/publics
zhuanfa.forward(request,response);//这一步开始正式的转发,千万别漏写


在接收转发的servlet中读取数据
/*while(names.hasMoreElements()){
String name=(String) names.nextElement();
Object value = request.getAttribute(name);
System.out.println(name+" : "+value);
out.println(name+" : "+value+"<br>"+"111");
}*///这种方法会多出一些关于转发的内容来,我们可以是直接用getAttribute(name)来得到值


下面是就精确的方法
Object value = request.getAttribute("a");
out.println(value);






九.http响应格式

1.响应状态行
2.响应头
3.空行
4.响应体:具体响应的内容


状态码
1** :收到请求,没有处理完
2**:成功,响应完毕,常见200.
3**:重定向,请求移到另一个请求中去,常见302
//这里提一点304,304是指内容已经在本地缓存中,且最后一次修改时间
//与服务器上最后一次修改时间相同,就直接从缓存中读取数据,不需要
//在从服务器中去重新加载数据,这样可以节省时间
4**:失败,没有请求的文档等,常见404
5**:内部错误,代码出现异常,常见500//比如所说的空指针异常
//String a =null;
//while(a.equal("add")){}
//上面的代码就会出现空指针异常


十:重定向的具体概念

重定向代码:response.sendredirect("网址")
解释:
1.给客户浏览器响应了一个网址,客户浏览器得到这个网址,再向服务器发送请求,所以发生了两次请求
比如说,我先是给服务器发了一个网址请求,在服务器上对这个网址进行了重定向,也就是写了上面那个代码,
然后会发给浏览器这个重定向的网址,浏览器再向服务器请求这个网址,所以是两次请求。
2.这里的网址是指一个完整的url,如http://www.baidu.com.
如果是在同一web应用中可以不写主机名,如/test/Servlet2,而不必写成http://localhost:8080/test/Servlet2


注意的问题是:
1.重定向和请求转发的具体区别
区别一:重定向是相当于浏览器进行了两次请求的,会得到302状态码,并且,在浏览器中的url地址会发生改变,
而请求转发不会改变在浏览器中的url,并且只进行了一个request请求,返回的会是200状态码。


区别二:重定向的网址能写成一个完整的url,可以是项目外的,也可以是项目内的,但是,如果是项目内的,必须要加上完整的项目servlet路径,
而,请求转发的地址(这里我不再称呼为网址,因为它是写不了完整的网址的),只能是一个项目内的,直接写servlet名就好了。


简要概括就是:
重定向发生两次请求,转发只有一次请求
转发只能在一个web应用内部组件间进行,重定向可以是web应用之外的。




十一:HTTP响应的内容

http响应头
头名称 说明
Location http://www.baidu.com        服务器类型


Content-Type  text/html                  响应类型


Content-Length  0  内容的大小


Expires 0 缓存过期时间,0表示立即过期,不设永不过期


Cache-Control     no-cache              响应消息不缓存,适用http1.0


Pragma            no-cache              响应消息不缓存,适用http1.0


Refresh         5 http://www.baidu.com    过多久自动刷新到url


Content-Disposition   attachment;filename=aaa.zip    下载文件,文件的内容描述




十二:响应的生命周期

1.创建阶段
收到http请求时,web容器创建响应对象后,传入到doGet或doPost方法
2.使用阶段
在Servlet进行http请求处理时,通过响应对象向浏览器响应内容,包括状态码,响应头和
响应体数据
3.销毁阶段
客户端接受响应内容完毕后,web容器销毁响应对象,释放所占的内存




十三:关于Cookie和session

Cookie我就不再提了,具体的有空再写,先讲讲思想吧。
Cookie是浏览器通过文本去存储网站信息的一个手段,整个流程就是,
举个例子,表单提交用户名和密码
第一次登陆的话,提交表单,将用户名和密码传给后台,服务器接收到用户名和密码,首先是检验,
如果正确,就将它实例化成一个Cookie,可以设置SetMaxAge去设置Cookie存活时间,然后将这个Cookie
通过response去传递给浏览器,浏览器接受到,将内容以文本形式进行保存,当再次访问登陆界面的时候,会将
cookie去添加到http请求头里面,传给服务器,服务器可以读到cookie里面的数据,来进行某些操作。




session
session是一种数据共享的技术,只要你的浏览器不关闭,(当然,你也可以使用Cookie去保存它),
那么访问这个网站的写了session的数据就是共享的,
流程是:
先访问一个网站,比方,如果,服务器网站做了session的话,比方说request.getSession();
这段代码很通用,括号里面可以填写true或者是false,真的话就是如果没有要的sessionid就会分配一个内存并且返回一个
sessionid给浏览器,这个sessionid是会被存储在浏览器的内存上的,不会存在浏览器文本里(不像cookie那样),
假就是死都不分配内存给用户浏览器。
浏览器访问服务器会将sessionid也传给服务器,服务器也会通过requset.getSession()去找到内存中对应着该
sessionid的内存空间,所以说这代码很万能。
这里就有个内存空间的释放问题,默认是30分钟释放一次,这实际上就是session的存活时间,我们当然也可以在
代码上设置这个,你可以用你用request.getSession()得到的对象去.set啥玩意的方法,然后自动补全,
session.setMaxInactiveInterval(100);
我还是复制过来了。。。。




关于使用session做登录,我做了个简单流程
1.写了个index.jsp登录前端页面
2.写了个servlet页面loginprocess去处理登录的用户名和密码,如果匹配成功,则分配session,并且将用户名
和密码设置到session里面,然后给浏览器的cookie,浏览器是内存保存的,不会文本保存,然后跳转到main页面,就是
登录成功的页面,如果没法匹配,就返回登录页面。
3.写了个登录成功页面,为了防止被直接通过url访问成功,首先会读取session里面的内容,如果符合我所设置的
条件,则,就让访问,我在这里面,是读取session中的username和password的值,如果与我匹配的成功,就会显示页面,
否则跳转会登录页面。

猜你喜欢

转载自blog.csdn.net/qq_26024867/article/details/80981765
今日推荐