Web基础之Servlet深入
一、Servlet生命周期回顾:
Servlet生命周期( Life Cycle):
生命周期:指一个对象从创建到销毁所经历的过程。
生命周期方法:定义在 javax.servlet.Servlet 接口中,包括三个方法:
init(ServletConfig config):当前Servlet对象被WEB服务器创建之后,立即被调用的方法,主要用于初始化web.xml中对该Servlet的配置。
service(ServletRequest req, ServletResponse resp):处理客户端的请求,并输出响应。
destroy(): 当前Servlet对象被WEB服务器销毁之前,将被调用的方法,主要用于释放Servlet对象可能占用的资源。
图解:
二、Http访问流程:
这里的访问流程在前面叙述的很详细了;请看前面的博客;
三、Servlet中的一些对象和问题
四、关于其他匹配的问题:
在WebCont目录下新建一个html文件,我们并没有为这个资源配置路径?那么,该资源是如何访问的呢?
打开我们安装Tomcat目录下config目录,打开web.xml配置文件
其实,不管是html资源还是其他资源,如果没有在当前工程目录的web.xml中没有匹配到路径,则会交给Tomcat中的web.xml处理。在这里,会过滤很多类型的资源,例如,*.html,*.jsp等类型的文件会有相应的Servlet进行处理;如果这里也没有匹配到,则会发送404错误信息;
五、Servlet实战
目录结构:(只需关注LoginServlet,login.html即可)
在WebContent目录下新建一个login.html文件,内容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录界面</title>
</head>
<body>
<div style="text-align: center">欢迎注册华信会员</div>
<!-- 这里利用form表单中的action属性,提交请求路径 -->
<form action="mylogin" method="get">
<div style="text-align: center">
<!-- 当点击确定按钮后,会把form表单中有name属性的表单中的内容提交到Servlet处理 -->
<!-- 这里提交过去的参数有用户名和密码,注意Servtet端获取参数的方法 -->
<span>用户名</span>:<input type="text" name="userName"><br />
<span>密 码:</span><input type="text" name="pwd"><br />
<input type="submit" value="确定"><input type="reset" value="重置">
</div>
</form>
</body>
</html>
在src目录下新建一个LoginServlet.java文件,用于处理点击form表单中确定过来的请求
package com.hx.serverlet;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//直接继承系统的HttpServlet类
public class LoginServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
// 重写构造方法,看一下何时被调用
public LoginServlet() {
System.out.println("do my constcuter......");
}
// 重写系统的init()方法
public void init(ServletConfig config) throws ServletException {
System.out.println("do my config.....");
}
// 重写我们自己的init()方法
public void init() throws ServletException {
System.out.println("do my init.....");
}
//处理form表单提交过来的请求
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 设置响应正文类型,告知客户端是html类型
resp.setContentType("text/html;charset=UTF-8");
// 输出响应正文
resp.getWriter().write("<!DOCTYPE html><html><head><body><p>"+"举杯邀明月,对影成三人!"+"</p></body></head></html>");
}
}
好了,问题来了,LoginServlet怎么知道要处理form表单提交过来的请求呢?回想一下我们前面的例子?我们首先是在web.xml中配置了请求路径,根据请求路径,Tomcat才知道把这个请求交给哪个Servlet处理;例如,我们以前总是写好一个Servlet后要配置一下路径,我们的FirstServlet.java,我们配置的路径是/first,所以,当在浏览器中输入http://localhost/Servlet01/first路径时,会交给FirstServlet处理;
那么,同理,当点击我们form表单的确定按钮后,地址栏中的请求路径应该变为http://localhost/Servlet01/mylogin
看login.html中action属性;所以,我们需要在web.xml中配置一下我们的信息
配置信息如下:
这样,当点击确定按钮后,服务器就知道该将这个请求交给LoginServlet处理了;
好了,现在我们在浏览器中输入http://localhost/Servlet01/login.html,会出现如下界面
(这里需要思考一个问题,login.html资源是哪个Servlet处理的呢?我们并没有给login.html这个路径配置Servlet;其实,我们上面就说了,对于.html,.jsp等静态资源,会交给Tomcat下的web.xml
处理;看上面关于没有匹配的图片;我们也可以配置login.htm这个路径的请求,把这个请求交给另外一个Servlet处理;如果不能理解,你就可以理解为,对这些静态资源是可以直接访问的)
然后,我们点击确定按钮,注意地址栏的路径变化:
我们可以看到,地址栏的路径发生了变化,变成了 http://localhost:8080/Servlet01/mylogin?userName=&pwd=
/mylogin就是form表单中action提交的路径,这个路径会交给LoginServlet处理,因为我们配置文件中说明了;
这里解释下?userName=&pwd=这串路代表什么,这就是我们前面说的,当点击确定后,会提交form表单中所有又name属性的表单中的内容;这里我们没有输入用户名和密码,所以显示为空;
好了,我们改一下LoginServlet中的代码,获取客户端提交过来的参数,并将参数回传给客户端
更改后的LoginServlet代码:
package com.hx.serverlet;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//直接继承系统的HttpServlet类
public class LoginServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
// 重写构造方法,看一下何时被调用
public LoginServlet() {
System.out.println("do my constcuter......");
}
// 重写系统的init()方法
public void init(ServletConfig config) throws ServletException {
System.out.println("do my config.....");
}
// 重写我们自己的init()方法
public void init() throws ServletException {
System.out.println("do my init.....");
}
//处理form表单提交过来的请求
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 设置请求编码,当请求中有中文时会出现乱码
req.setCharacterEncoding("UTF-8");
// 获取请求参数
String username=req.getParameter("userName");
String pwd=req.getParameter("pwd");
// 设置响应正文类型,告知客户端是html类型
resp.setContentType("text/html;charset=UTF-8");
// 输出响应正文
resp.getWriter().write("<!DOCTYPE html><html><head><body><p>"+"举杯邀明月,对影成三人!"+"</p></body></head></html>");
resp.getWriter().write("您输入的用户名是"+username+" "+"您输入的密码是:"+pwd);
}
}
注意,这里获取参数一定要严格匹配,即根据你的html中name属性的值获取;这里的userName,和pwd都是login.html中name属性表单的值;
好了,现在我们再次输入http://localhost/Servlet01/login.html,并在用户和密码文本框输入用户名和密码
点击确定,提交请求,仔细观察地址栏的变化和输入的响应文档
我们获取到了客户端提交过来的参数,而且参数还在地址栏中显示了,马上就会有人问了,这样那我的密码岂不是一下子就泄露出去了;这是GET和POST请求的区别;get请求会在地址栏提交参数,而post请求不会再地址栏中提交参数;我们可以改下GET为POST,再来看一下
由于LoginServlet中,只重写了doGet()方法,所以只能处理GET请求,要想处理POST请求,需要重写doPost()方法
把login.html中method改为POST
把LoginServlet中的doGet改为doPost方法
记得重新启动服务器(因为我们修给了Servlet中的代码)
这次我们再次输入用户民名和密码,就不会再地址栏中显示提交的参数了;
六、总结
对Servlet进行深入的了解;回顾Servlet的生命周期;
重新梳理Http访问的流程;路径匹配的详解;
通过实例,加深了对知识的理解;
共勉!