学习笔记是参考的how2j
Servlet service()方法
再看一下上篇笔记中的程序
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet{
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
String name = request.getParameter("name");
String password = request.getParameter("password");
//定义要输出的字符串html
String html = null;
//如果账户名为admin且密码为123456则html为"<div>sucess</div>",否则为"<div>fail</div>"
if(name.equals("admin") && password.equals(("123456"))) {
html = "<div>sucess</div>";
}
else {
html = "<div>fail</div>";
}
//通过response.getWriter().println() 方式发送出去
PrintWriter pw = response.getWriter();
pw.println(html);
//response.getWriter().println();//这种方式也可以
}
}
可以看到,我们使用了doPost()方法,这是因为login.html文档中定义了form的method为post。同样的如果使用了get方式,LoginServlet中需要提供doGet()方法。
![bb2a055fddadf0cf45970212241389af.png](https://i-blog.csdnimg.cn/blog_migrate/be0cb2328f1f37a2dcc825f112a9d2cb.png)
又因为上述程序继承了HttpServlet,所以同时也继承了一个方法service(HttpServletRequest , HttpServletResponse )。
实际上,在执行doPost()或doGet()之前,都会先执行service(),由这个方法判断调用doPost()还是doGet()。
我们也可以直接重写service()方法,其这个方法里面提供相应的服务,就不用区分到底是doPost()还是doGet()了。程序如下
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
String password = request.getParameter("password");
//定义要输出的字符串html
String html = null;
//如果账户名为admin且密码为123456则html为"<div>sucess</div>",否则为"<div>fail</div>"
if(name.equals("admin") && password.equals(("123456"))) {
html = "<div>sucess</div>";
}
else {
html = "<div>fail</div>";
}
//通过response.getWriter().println() 方式发送出去
PrintWriter pw = response.getWriter();
pw.println(html);
//response.getWriter().println();//这种方式也可以
}
}
Servlet的中文问题
前面的所有程序都没有设计到中文的处理,因为可能会造成乱码
获取中文参数
为了获取中文参数,需要在login.html中加上<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">,代码如下
<!DOCTYPR html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录界面</title>
</head>
<body>
<!-- action="login" 标题会提交到login路径,login路径在后续步骤会映射到LoginServlet
method="post" post方式表示提交的密码信息在浏览器地址栏看不到 -->
<form action="login" method="post">
账户:<input type="text" name="name"> <br>
密码:<input type="password" name="password"> <br>
<input type="submit" value="登录">
</form>
</body>
</html>
然后在servlet中对中文进行编码和解码,只需要在request.getParameter()之前加上一句request.setCharacterEncoding("UTF-8");
有种比较复杂的方法是使用
byte[] bytes= name.getBytes("ISO-8859-1");
name = new String(bytes,"UTF-8");
这里使用第一种方便的方法
返回中文的响应
只需要在 response.getWriter();之前加上response.setContentType("text/html; charset=UTF-8");
全部程序如下
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取中文的参数
//request.setCharacterEncoding("UTF-8");//其他编码方式同理,比如修改为GBK
String name = request.getParameter("name");
String password = request.getParameter("password");
String html = null;
if(name.equals("admin") && password.equals(("123456"))) {
html = "<div>登录成功</div>";
}
else {
html = "<div>失败</div>";
}
//返回中文的响应, 注意中间是分号
response.setContentType("text/html; charset=UTF-8");
PrintWriter pw = response.getWriter();
pw.println(html);
}
}
然后重启tomcat,即双击D:tomcat_80binstartup.bat,然后浏览器输入127.0.0.1/login.html,输入正确的账户名和密码,可以看到“登录成功”。
![2e2fbd2b3adb38c39b4c0869f3b056bf.png](https://i-blog.csdnimg.cn/blog_migrate/89093b6ebab29751db871b3f779c168f.png)
Servlet生命周期
一个Servlet的生命周期由 实例化,初始化,提供服务,销毁,被回收 几个步骤组成
![817f455a63f73a20d76a7850443cd2da.png](https://i-blog.csdnimg.cn/blog_migrate/dbb628a43bef17b65d88bc113709e58c.png)
实例化
当用户通过浏览器输入一个路径,这个路径对应的servlet被调用的时候,这个servlet就会被实例化。
可以在前面的类LoginServlet中显示声明构造函数LoginServlet(),然后通过浏览器访问,就可以观察到"LoginServlet 构造方法 被调用",无论访问多少次LoginServlet,构造方法LoginServlet()只会执行一次,因此servlet是单例的。
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet{
public LoginServlet() {
System.out.println("LoginServlet 构造方法 被调用");
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取中文的参数
//request.setCharacterEncoding("UTF-8");//其他编码方式同理,比如修改为GBK
String name = request.getParameter("name");
String password = request.getParameter("password");
String html = null;
if(name.equals("admin") && password.equals(("123456"))) {
html = "<div>登录成功</div>";
}
else {
html = "<div>失败</div>";
}
//返回中文的响应, 注意中间是分号
response.setContentType("text/html; charset=UTF-8");
PrintWriter pw = response.getWriter();
pw.println(html);
}
}
通过浏览器访问,可以在tomcat看到只输出一次"LoginServlet 构造方法 被调用"
初始化
LoginServlet继承了HttpServlet,因此也继承了init(ServletConfig)方法。init是一个实例方法,所以回在构造方法执行后执行,因此也会只执行一次。
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet{
public LoginServlet() {
System.out.println("LoginServlet 构造方法 被调用");
}
public void init(ServletConfig config) throws ServletException {
System.out.println("初始化");
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取中文的参数
//request.setCharacterEncoding("UTF-8");//其他编码方式同理,比如修改为GBK
String name = request.getParameter("name");
String password = request.getParameter("password");
String html = null;
if(name.equals("admin") && password.equals(("123456"))) {
html = "<div>登录成功</div>";
}
else {
html = "<div>失败</div>";
}
//返回中文的响应, 注意中间是分号
response.setContentType("text/html; charset=UTF-8");
PrintWriter pw = response.getWriter();
pw.println(html);
}
}
不论在浏览器输入多少次http://127.0.0.1/login.html,tomcat窗口上只会输出一次结果,如下图。
![7b0f6f393f5799441261d792160eaef2.png](https://i-blog.csdnimg.cn/blog_migrate/99497c384899f42b212c9cad73f025fb.png)
提供服务
接下来就是提供服务,也就是执行service()方法,我们会在service中编写我们的业务代码,在本例中就是判断用户的输入是否正确。
销毁
以下两种情况会调用destroy()销毁
1.该servlet所在的web重新启动,
在server.xml中配置有<Context path="/" docBase="E:projectj2eeweb" debug="0" reloadable="false" />,如果把reloadable="false" 改为reloadable="true"就表示有任何类发生了更新,web应用会自动重启,当web应用自动重启的时候,destroy()方法就会被调用。
2.关闭tomcat的时候会调用destroy()方法,但是过程很快,难以观察到
回收
当一个servlset被destroy(),就满足垃圾回收条件,有可能会被回收。