Servlet/Filter发布后与其他页面的相对路径
1、Servlet
3个文件
E:\web.workspace\mldndemo\WebContent\ch14\regist.html
E:\web.workspace\mldndemo\WebContent\ch14\regist.jsp
E:\web.workspace\mldndemo\WebContent\WEB-INF\classes\org\lxh\ajaxdemo\CheckServlet.class
虽然CheckServlet.class所在的位置不是E:\web.workspace\mldndemo\WebContent\,但是如果你在web.xml中配置为如下:
<servlet>
<servlet-name>checkServlet</servlet-name>
<servlet-class>
org.lxh.ajaxdemo.CheckServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>checkServlet</servlet-name>
<url-pattern>/CheckServlet</url-pattern>
</servlet-mapping>
那么,根据上面的url-pattern的配置,CheckServlet在虚拟目录中就相当于对应这个url:http://127.0.0.1:8080/mldn/CheckServlet,这是因为,我在server.xml中是这样配置的
<Context path="/mldn" docBase="E:\web.workspace\mldndemo\WebContent" reloadable="true">
也就是说使用http://127.0.0.1:8080/mldn/访问到的是E:\web.workspace\mldndemo\WebContent\这个目录
在你在任何页面访问CheckServlet的时候,都要使用相对路径,具体来说,那么,现在我在regist.html中如果要访问CheckServlet,应该怎么做呢?
因为regist.html的虚拟路径为http://127.0.0.1:8080/mldn/ch14/regist.html
所以,在regist.html中如果要访问CheckServlet,就必须使用如下的URL(当然,param可以根据情况省略):
../CheckServlet?param1=...¶m2=...
具体代码如下:
regist.html
<!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> <script language="javascript"> var xmlHttp ; var flag = false ; function createXMLHttp(){ if(window.XMLHttpRequest){ xmlHttp = new XMLHttpRequest() ; } else { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP") ; } } function checkUserid(userid){ createXMLHttp() ; // 这里的问号[?]就是参数的意思[userid]即参数名 xmlHttp.open("POST","../CheckServlet?userid="+userid) ; xmlHttp.onreadystatechange = checkUseridCallback ; xmlHttp.send(null) ; document.getElementById("msg").innerHTML = "正在验证..." ; } function checkUseridCallback(){ if(xmlHttp.readyState == 4){ if(xmlHttp.status == 200){ var text = xmlHttp.responseText ; if(text == "true"){ // 用户id已经存在了 document.getElementById("msg").innerHTML = "用户ID重复,无法使用!" ; flag = false ; } else { document.getElementById("msg").innerHTML = "此用户ID可以注册!" ; flag = true ; } } } } function checkForm(){ return flag ; } </script> </head> <body> <form action="regist.jsp" method="post" onsubmit="return checkForm()"> 用户ID:<input type="text" name="userid" onblur="checkUserid(this.value)"><span id="msg"></span><br> 姓 名:<input type="text" name="name"><br> 密 码:<input type="password" name="password"><br> <input type="submit" value="注册"> <input type="reset" value="重置"> </form> </body> </html>
CheckServlet.java
package org.lxh.ajaxdemo ; import java.sql.* ; import java.io.* ; import javax.servlet.* ; import javax.servlet.http.* ; public class CheckServlet extends HttpServlet{ public static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; public static final String DBURL = "jdbc:mysql://localhost:3306/mldn" ; public static final String DBUSER = "root" ; public static final String DBPASS = "mysqladmin" ; public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{ this.doPost(request,response) ; } public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{ request.setCharacterEncoding("UTF-8") ; response.setContentType("text/html") ; Connection conn = null ; PreparedStatement pstmt = null ; ResultSet rs = null ; PrintWriter out = response.getWriter() ; String userid = request.getParameter("userid") ; try{ Class.forName(DBDRIVER) ; conn = DriverManager.getConnection(DBURL,DBUSER,DBPASS) ; String sql = "SELECT COUNT(userid) FROM user WHERE userid=?" ; pstmt = conn.prepareStatement(sql) ; pstmt.setString(1,userid) ; rs = pstmt.executeQuery() ; if(rs.next()){ if(rs.getInt(1)>0){ // 用户ID已经存在了 out.print("true") ; } else { out.print("false") ; } } }catch(Exception e){ e.printStackTrace() ; }finally{ try{ conn.close() ; }catch(Exception e){} } } }
regist.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.util.*" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!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> 欢迎光临!<c:out value="${param.name }"/>! </body> </html>
2、Filter
Filter与Servlet不一样,Servlet一般情况下你会在html或者jsp页面中直接引用,这时上面的配置就是有效的,但是filter,是由web-container调用的,你自己不会在html或者jsp页面中直接调用它,所以filter的配置的url-pattern一般是这样:
<url-pattern>/filterdemo/*</url-pattern>
含义就是,对子目录/filterdemo/下的任意页面的引用,都要使用filter进行过滤,web-container发现你的url为上述配置的pattern的情况下,就会调用你的filter进行处理,具体的调用过程你不用操心。
但是,这个时候,如果你要在filter中跳转到/filterdemo/下的某个页面,比如说login.jsp,应该怎么做呢?
对了,根据我们前面说的,Servlet、Filter这些class本身,我们可以认为是放在%web-root%下的(尽管它们的.class文件是放在%web-root%/WEB-INF/classes/中,但到了web-container中,这些serlvet,filter就好像直接被放在了%web-root%对应的虚拟路径下)
所以我们应该这样做,也就是说,filter在引用别的html、jsp页面的时候,与servlet的情况并无区别:
request.getRequestDispatcher("/filterdemo/login.jsp").forward(request,response) ;
例子如下
/WebContent/WEB-INF/web.xml
/WebContent/filterdemo/login.jsp
/WebContent/filterdemo/welcome.jsp
web.xml
<!-- login filter --> <filter> <filter-name>login</filter-name> <filter-class>org.lxh.filterdemo.LoginFilter</filter-class> </filter> <filter-mapping> <filter-name>login</filter-name> <url-pattern>/filterdemo/*</url-pattern> </filter-mapping>
login.jsp
<%@ 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> <form action="login.jsp" method="post"> 用户名:<input type="text" name="uname"><br> 密 码:<input type="password" name="upass"><br> <input type="submit" value="登陆"> <input type="reset" value="重置"> </form> <% // 直接通过一个固定的用户名和密码 String name = request.getParameter("uname") ; String password = request.getParameter("upass") ; if(!(name==null || "".equals(name) || password==null || "".equals(password))){ if("lixinghua".equals(name) && "mldn".equals(password)){ // 如果登陆成功,则设置session属性范围。 session.setAttribute("userid",name) ; response.setHeader("refresh","2;URL=welcome.jsp") ; %> <h3>用户登陆成功,两秒后跳转到欢迎页!</h3> <h3>如果没有跳转,请按<a href="welcome.jsp">这里</a>!</h3> <% } else { %> <h3>错误的用户名或密码!</h3> <% } } %> </body> </html>
welcome.jsp
<%@ 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> <h3>欢迎<%=session.getAttribute("userid")%>光临本系统!</h3> </body> </html>
LoginFilter.java
package org.lxh.filterdemo ; import java.io.* ; import javax.servlet.* ; import javax.servlet.http.* ; public class LoginFilter implements Filter { public void init(FilterConfig config) throws ServletException{ } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException{ // session属于http协议的范畴 HttpServletRequest req = (HttpServletRequest) request ; HttpSession ses = req.getSession() ; if(ses.getAttribute("userid") != null) { // 已经登陆过了,则可以访问 chain.doFilter(request,response) ; } else { request.getRequestDispatcher("/filterdemo/login.jsp").forward(request,response) ; } } public void destroy(){ } }