本文仅仅是测试方向学习Servlet的基本知识,并不深入。欢迎大家多多指教
环境的准备、Servlet基本介绍
-
Web应用的执行流程:
(1)浏览器发送请求(一个资源)
(2)Web服务器根据请求进行相应的操作
(3)Web服务器将结果返回给浏览器 -
Servlet:服务器端小程序
运行在服务器上,在服务器端调用、执行,按照Servlet规范编写的Java类。作用:对客户端的请求进行处理、向客户端返回响应。 -
Servlet容器(引擎):Web服务器中专门负责装载、运行Servlet的一个模块。(Servlet程序运行的环境,就是servet容器。
) -
Tomcat是一个开源的Web服务器, 包含:(1)一个Servlet容器 (2)支持通过JNDI技术找到数据源,通过数据源连接数据库。
在已经配置好的Eclipse中需要:(1)在Eclipse中配置Tomcat服务器 (2)在Eclipse中创建动态Web项目
(配置这个环境费了好大的劲,出现报错时,挑选报错信息进行百度查询解决方法)
Servlet的编写和访问过程
-
编写过程:
(1)创建类,实例接口Servlet
(2)实现service()方法
(3)在web.xml进行注册(配置) -
当浏览器发出请求,tamcat实例化了子类Servlet对象;init、destroy(只执行一次);每访问一次service就会执行一次
-
在此我举一个栗子吧:
这是我创建的目录
index.html中的内容:
类中:
xml文件中:
此即是一个小小的例子,并且解释了xml中添加内容的含义,在环境没问题的情况下,可以达到预想的效果。
补充:
<url-pattern>标签的区配方式
(1)如上述例子一样:完整的URL
(2)/目录/*
的方式:以"/目录"作为开头的URL
(3)*.do
:以.do结尾的地址(不一定是do这个单词,例如.action也可以)
Servlet父子类之间的继承关系
- 可以看看源代码
Servlet处理、解析请求以及返回响应的过程
- 浏览器接受请求后,服务器转交请求给Web容器
- Tomcat启动后
Web容器
首先做的工作:
(1)Servlet与URL对应
(2)完成Servlet名称注册
(3)创建Servlet实例
Web容器产生请求对象和响应对象。 - 接收请求
调用Servlet的service()方法,并将请求和响应对象作为参数传入该方法。service方法根据请求方式调用doXXX方法 - 返回响应
在doXXX方法中使用请求对象获取请求信息,响应对象返回响应结果(PrintWriter对象)
- 销毁请求,响应对象
四种传参方式
-
html向Servlet传参
链接(get)、表单(get、post)等
,通过request.getParameter()
得到,
【get请求参数在地址栏,post参数在请求体】如:例一 -
请求转发
,是可以传参的;自始至终只有一次请求URL,页面跳转发生在服务器端
获取响应:request.getRequestDispatcher(" targetURL").forward(request, response);
如:例二 -
请求重定向
:两次请求,不能通过setAttribute传参,页面跳转发生在客户端
如例三
例1:
对上文的html文件修改:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="hell?u_name=admin&u_pwd=123456">欢迎使用!</a>
<form action="hell" method="post">
用户名:<input type="text" name="user_name"/><br>
密码:<input type = "text" name="user_pwd"/><br>
<input type="submit" value="登录"/>
</form>
</body>
</html>
对应的类修改为:
package hebu.couse.xxx;
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 Cours extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
String u_name = req.getParameter("u_name");
String u_pwd = req.getParameter("u_pwd");
resp.getWriter().write(u_name + " " + u_pwd);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
req.setCharacterEncoding("utf-8");//解决中文乱码问题
String u_name = req.getParameter("user_name");
String u_pwd = req.getParameter("user_pwd");
resp.getWriter().write(u_name + "***** " + u_pwd);
}
}
xml文件未修改,效果:
补充:在doPost方法中获得请求的参数
Map<String, String[]> parval = req.getParameterMap();
for (String key : parval.keySet()) {
System.out.println(key + ":" + req.getParameter(key));
}
例二:
两个Servlet文件,LoginServlet负责登录,当检查到登录名为"admin", 密码为"123456"时,向LoginResult获取响应,页面加载出:admin登陆成功!
package hebu.couse.xxx;
import java.io.IOException;
import javax.security.auth.message.callback.PrivateKeyCallback.Request;
import javax.servlet.RequestDispatcher;
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;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
req.setCharacterEncoding("utf-8");//解决中文乱码问题
String name = req.getParameter("user_name");
String password = req.getParameter("user_pwd");
if(name.equals("admin") && password.equals("123456")) {
req.setAttribute("u_name", name);
RequestDispatcher result = req.getRequestDispatcher("result");
result.forward(req, resp);
}
}
}
package hebu.couse.xxx;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class LoginResult
*/
//@WebServlet("/LoginResult")
public class LoginResult extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");//解决中文乱码问题
String uname = (String) request.getAttribute("u_name");
PrintWriter writer = response.getWriter();
writer.write("<h1>" +uname+ "登陆成功!</h1>");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
xml:
html:
例三:
我们仍用例二的例子,在负责登陆的LoginServlet中的doPost方法中,加入登陆失败的跳转到虚拟路径为fali的。
LoginServlet的doPost方法:
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
req.setCharacterEncoding("utf-8");//解决中文乱码问题
String name = req.getParameter("user_name");
String password = req.getParameter("user_pwd");
if(name.equals("admin") && password.equals("123456")) {
//请求转发
req.setAttribute("u_name", name);
RequestDispatcher result = req.getRequestDispatcher("result");
result.forward(req, resp);
}else {
//请求重定向
resp.sendRedirect("fail");
}
}
FailServlet类:
package hebu.couse.xxx;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//@WebServlet("/FailServlet")
public class FailServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");//解决中文乱码问题
String uname = (String) request.getAttribute("u_name");
PrintWriter writer = response.getWriter();
writer.write("<h1>" +uname+ "登陆失败!</h1>");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
发现登陆失败后,并不能显示出名字,解释:
补充:
- HTTP状态码,响应分为五类:
1xx:信息,服务器收到请求,需要请求者继续执行操作;
2xx:成功,操作被成功接收并处理;
3xx:重定向,需要进一步的操作以完成请求;
4xx:客户端错误,请求包含语法错误或无法完成请求
5xx:服务器错误,服务器在处理请求 的过程中发生了错误