servlet part 2
servlet的固定格式:
-
web文件夹(根据项目命名)目录中包含 ——
****.html
对应的html
页面
|____WEB-INF
目录 -
WEB-INF
目录中包含 ——web.xml
|____classes
文件夹
web.xml提供路径与servlet的映射关系,把/hello
这个路径,映射到HelloServlet
这个类上
classes
为项目的class
文件输出由原来
Servlet 需要提供对应的doGet() 与 doPost()方法
doGet()方法
当浏览器使用get方式提交数据的时候,servlet需要提供doGet()方法
哪些是get方式呢?
form默认的提交方式.如果通过一个超链访问某个地址,如果在地址栏直接输入某个地址,ajax指定使用get方式的时候
import java.io.IOException;
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 doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}
doPut()方法
当浏览器使用post方式提交数据的时候,servlet需要提供doPost()方法
哪些是post方式呢?
在form上显示设置 method="post"的时候,ajax指定post方式的时候
import java.io.IOException;
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 {
}
}
service()方法
LoginServlet继承了HttpServlet,同时也继承了一个方法
service(HttpServletRequest , HttpServletResponse )
实际上,在执行doGet()或者doPost()之前,都会先执行service(),由service()方法进行判断,到底该调用doGet()还是doPost()
可以发现,service(), doGet(), doPost() 三种方式的参数列表都是一样的。
所以,有时候也会直接重写service()方法,在其中提供相应的服务,就不用区分到底是get还是post了。
获取中文的参数
login.html
中加上
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
login.html
中的form
form
的method修改为post
- 在servlet进行解码和编码
byte[] bytes= name.getBytes("ISO-8859-1");
name = new String(bytes,"UTF-8");
先根据ISO-8859-1解码,然后用UTF-8编码
这样就可以得到正确的中文参数了
这样需要对每一个提交的数据都进行编码和解码处理,如果觉得麻烦,也可以使用一句话代替:
request.setCharacterEncoding("UTF-8");
并且把这句话放在request.getParameter()
之前
例如:
public class LoginServlet extends HttpServlet {
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
// byte[] bytes = name.getBytes("ISO-8859-1");
// name = new String(bytes, "UTF-8");
String password = request.getParameter("password");
System.out.println("name:" + name);
}
}
返回中文的响应
在Servlet
中,加上
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 {
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = request.getParameter("name");
String password = request.getParameter("password");
String html = null;
if ("admin".equals(name) && "123".equals(password))
html = "<div style='color:green'>登录成功</div>";
else
html = "<div style='color:red'>登录失败</div>";
response.setContentType("text/html; charset=UTF-8");
PrintWriter pw = response.getWriter();
pw.println(html);
}
}
servlet最直白的说就是一个接口,里面有5个抽象方法。 servlet的实现类 GenericServlet 封装了这些方法,GenericServlet 的子类 HttpServlet 又对各种不同请求方式做了判断。最终自定义的 servlet继承HttpServlet 只需要实现一小部分业务逻辑的处理。不要想太复杂,因为Tomcat 将复杂的业务逻辑都封装好了
***
servlet的实例化是由tomcat来做的而不是开发者,例如在loginServlet第一次被访问时,tomcat发现没有它的实例化对象,那么就会用类加载器加载loginServlet的class文件,通过反射调用其无参的构造方法,实例化一个对象出来,这里用到了反射的思想
***
tomcat一启动,就需要执行一些初始化的代码,比如校验数据库的完整性等。
但是Servlet的生命周期是在用户访问浏览器对应的路径开始的。如果没有用户的第一次访问,就无法执行相关代码。
网页跳转
- 首先在web目录下创建所有的html文件,用来准备跳转
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6FSPaKPT-1636042220158)(https://raw.githubusercontent.com/Aaaazdy/picclouding/master/202110241716082.png)]
跳转实现
request.getRequestDispatcher("success.html").forward(request, response);
使用的是request
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = request.getParameter("name");
String password = request.getParameter("password");
if ("admin".equals(name) && "123".equals(password)) {
request.getRequestDispatcher("success.html").forward(request, response);
}
}
}
服务端跳转可以看到浏览器的地址依然是/login 路径,并不会变成success.html
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RhkeRTEn-1636042220162)(https://raw.githubusercontent.com/Aaaazdy/picclouding/master/202110241719497.png)]
/login
路径为web.xml中创建的映射[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qKCumplH-1636042220165)(https://raw.githubusercontent.com/Aaaazdy/picclouding/master/202110241720892.png)]
response.sendRedirect("fail.html");
使用的是responce
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = request.getParameter("name");
String password = request.getParameter("password");
if ("admin".equals(name) && "123".equals(password)) {
request.getRequestDispatcher("success.html").forward(request, response);
}
else{
response.sendRedirect("fail.html");
}
}
}
可以观察到,浏览器地址发生了变化
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-orBdXVx5-1636042220168)(https://raw.githubusercontent.com/Aaaazdy/picclouding/master/202110241727614.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-csy3UDwW-1636042220174)(https://raw.githubusercontent.com/Aaaazdy/picclouding/master/202110241737584.png)]