在学习通过实现Servlet接口开发Servlet后,这里做一个小的实战。获取用户登录信息并将登录信息打印到网页。
1、创建登录页面:
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<!-- 这里我们将表单数据提交到MyServlet -->
<form action="ms" method="post">
用户名:<input type="text" name="uname"><br>
密码:<input type="text" name="pwd"><br>
<input type="submit" value="登录"><br>
</form>
</body>
</html>
2、调用Servlet的service方法,处理请求
代码如下:
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
//获取表单提交的数据
String uname = req.getParameter("uname");
String pwd = req.getParameter("pwd");
//将表单数据打印到浏览器
//获取打印流对象
PrintWriter pw = res.getWriter();
pw.println("uname: " + uname);
pw.println("pwd: " + pwd);
}
3.浏览器输入正确的URL,并提交表单:
4.在浏览器中打印表单内容
如此,我们便简单完成了一种前后端的交互(是不是很简单,原凉我html写的很low)。
接下来,我们继续回到Servlet的注册。我们是这样对Servlet进行注册的:
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.test.servlet.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/ms</url-pattern>
</servlet-mapping>
解释下Servlet的注册:
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.test.servlet.MyServlet</servlet-class>
</servlet>
该段代码的意思是将名字为MyServlet的Servlet与某个具体的Servlet实现类建立关系,这样就可以通过名字找到实现类执行其service()方法
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/ms</url-pattern>
</servlet-mapping>
该段代码的意思是将建立名字为MyServlet和URI的映射关系。注册servlet时必需具有<servlet>和<servlet-mapping>,并且他们的<servlet-name>保持相同。为什么要相同?这样我就可以通过浏览器中输入的URL,分离出<url-pattern>,然后根据其找到<servlet-name>,然后根据<servlet-name>找到<servlet-class>,这样我们就可以执行serivce()方法,也就是相同的原因。如果不相同的话,我们怎么能找到service方法呢?
六、<url-pattern>的设置与匹配
(1) 精确路径模式
请求路径必须与的值完全相同才可被当前Servlet处理
(2) 通配符路径模式
该模式中的路径由两部分组成,精确路径部分与通配符部分,请求路径中只有携带了值中指定的精确路径部分才可被当前Servlet处理.
即浏览器中输入的url需保证有/aaa,后面任意
(3) 全路径模式
/* 是真正的全路径模式,可以拦截所有请求,无论是动态资源请求还是静态资源请求,均会被拦截。
该项目下存在以下两个页面:
内容分别为:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h5>这是静态网页</h5>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h5>这是动态网页</h5>
</body>
</html>
当<url-pattern>为/*时,我们访问以下两个网页,发现浏览器都不能打印出内容。
/ 只会拦截静态资源请求,对于动态资源请求时不进行拦截的。
当<url-pattern>为/时,我们访问以下两个网页,发现浏览器只能打印jsp的内容。
(4) 后缀名模式
浏览器若要拦截url,则必须以 .do 结尾
后缀名模式的用法限制:
为设置值时,带斜杠的通配符路径模式与后缀名模式不能同时使用/.do,/xxx/.do等形式。否则,服务器将无法正常启动。
七、匹配原则
(1) 路径优先后缀匹配原则
例如SomeServlet的<url-pattern/>为*.do,OtherServlet的<url-pattern/>为/xxx/*。若用户提交的请求URL为http://localhost:8080/MyServlet/xxx/abc.do,此时服务器发现SomeServlet的*.do与OtherServlet的/xxx/*都可以与用户提交的/xxx/abc.do匹配。那么服务器会按照“路径优先后缀匹配“的原则选择OtherServlet
(二) 精确路径优先匹配原则
例如SomeServlet的<url-pattern/>为/xxx/*,OtherServlet的<url-pattern/>为/xxx/second。若用户提交的请求URLhttp://localhost:8080/MyServlet/xxx/second
,此时服务器发现SomeServlet的/xxx/*与OtherServlet的/xxx/second都可以与用户提交的/xxx/second匹配。那么服务器会按照“精确路径优先匹配原则“的原则选择OtherServlet
(三) 最长路径优先匹配原则
例如someeServlet的<url-pattern/>为/xxx/,OtherServlet的<url-pattern/>为/xxx/ooo/。若用户提交的请求URLhttp://localhost:8080/MyServlet/xxx/ooo,此时服务器发现SomeServlet的/xxx/*与OtherServlet的/xxx/ooo*都可以与用户提交的/xxx/ooo匹配。那么服务器会按照“最长路径优先匹配原则“的原则选择OtherServlet
以上三种匹配模式反映了这样一个现象,即你提供的信息越详细,则更加能确定要找哪一个Servlet。就像我们描述一个人,给出这个人越多的信息,我们越能够清楚这个人是谁。
原本打算进行GenericServlet的学习,但这次只能先对以上内容进行总结喽,且听下次分析。