用继承GenericServlet创建Servlet
这种方法创建servlet之后我们要注意一个init的方法细节:
适配器模式的一个知识点:适配器中的init(ServletConfig config)中帮我们把它当中的config对象赋值且调用 一个空参的init()。我们以后应该覆盖空参的init()。因为如果覆盖了这个带参数的,那么就无法实现为它的config对象赋值,由此导致其中使用config对象的方法会出错。在GenericServlet私有化一个config变量,然后在init(ServletConfig config)中做了一个 this.config = config 。这里是赋值语句,如果我们覆盖了这个方法,那么GenericServlet私有的config变量就是null。其实这种方法(调用 一个空参的init()且 该参数方法中什么也没做 )也程序员之间的一种交流方式,告诉我们要覆盖空参的方法,这样它在帮我们做完事情会调用们的覆盖方法。
我们要覆盖的是这个空参的init方法。如果覆盖了带参数的init方法,会导致下面使用config的地方出错。空参的init方法是留给我们覆盖的,方便。
用继承HttpServlet创建Servlet
在用extends HttpServlet方式创建servlet时,如果我们什么方法都不覆盖,那么会运行HttpServlet里面写好的service方法—调用了它的doget、dopost方法分别写了我们在网页所看到的404/405错误页面信息。
采用继承HttpServlet的方式写servlet,doGet和doPost这两个方法通过都要覆盖,否则如果doGet方法没覆盖,有get请求时就会出现405错误,不覆盖doPost方法同理。这是HttpServlet中自己写的。具体的可以自己去看api的底层代码
服务器启动后,资源路径的加载方式
学习一下服务器下的资源路径加载方式(因为我们的资源已经从MyEclipse中发布到Tomcat服务器中了,所以跟原来纯Java项目不一样了)利用当前类找到它的类加载器,然后通过该类加载器再去获得资源路径。如下所示:
SAXReader sax = new SAXReader();
path = Dom4jFactory.class.getClassLoader().getResource("users.xml").getPath();
dom = sax.read(new FileInputStream(path));
小项目-用户注册(采用dom4j来做,功能包括注册、查看所有、删除)
这里主要是采用dom4j+xpath技术来做的。
因为所有超链接都是以get方式请求的,我这里借用这点,用来区分功能。这里get是用来查看所有用户,而post则是用来注册用户 的
因为我们要删除,所以要拿到id才好去删除,我们把id用get请求方式将这个带有id属性的url整体发到del这个jsp文件中去,这样,我们在del.jsp文件中就能拿到这个id。部分代码如下:
String id = e.attributeValue("id");
String del = " <a href='/servletDemo_jun/del?id="+id+"'>删除</a>";
out.print("用户名:"+e.attributeValue("name")+",密码:"+e.attributeValue("pwd")+del+"<br/>");
返回上一个页面
用 out.print("<a href='javascript:history.go(-1);'>返回</a>");
来做。
重复的用户名不能注册
因为我用超链接的方式来删除的,所以都是get请求方式。我在del.jsp中就只覆盖了doget方法。
用dom4j+xpah看拿到的这个Node是否为null,如果存在那么说明此用户存在,这次注册操作失败。如果为null则说明可以注册,此次注册成功。 部分代码如下:
Node node = dom.selectSingleNode("//user[@name='"+name.trim()+"']");
if(node!=null){//用户已经存在 不能创建
response.getWriter().write("该用户已存在,请重新输入");
}else{//可以注册
response.getWriter().write("注册成功");
}
最后,完整代码如下:
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>JAVAWEB-DAY3-Servlet技术</title>
</head>
<body>
<!--
<a href="first">访问FirstServlet</a>
<hr/>
<h2>演示解决中文乱码问题</h2>
<h1>以下是演示用户登录</h1>
<form action="login" method="post">
姓名:<input type="text" name = "name"/><br/>
密码:<input type="password" name = "pwd"/><br/>
<input type="submit" value="登录">
</form>
-->
<hr/>
<h2>演示Servlet的第二种创建--继承GenericServlet</h2>
<form action="/servletDemo_jun/second" method="post">
姓名:<input type="text" name = "name"/><br/>
密码:<input type="password" name = "pwd"/><br/>
<input type="submit" value="登录">
</form>
<hr/>
<h2>演示Servlet的第三种创建--继承HttpServlet</h2>
<form action="/servletDemo_jun/third" method="post">
姓名:<input type="text" name = "name"/><br/>
密码:<input type="password" name = "pwd"/><br/>
<input type="submit" value="登录">
</form>
<hr/>
<h2>下面演示一个小项目---用户注册</h2>
<h3>采用new servlet的方式创建servlet</h3>
<form action="/servletDemo_jun/reg" method="post">
姓名:<input type="text" name = "name"/><br/>
密码:<input type="password" name = "pwd"/><br/>
<input type="submit" value="注册">
</form>
<!-- 因为所有超链接都是以get方式请求的,我这里借用这点,用来区分功能。
这里get是用来查看所有用户,而post则是用来注册用户 的
-->
<a href="/servletDemo_jun/reg">查看所有用户</a>
</body>
</html>
SecondServlet
package cn.hncu.servlets.day2;
import java.io.IOException;
import javax.servlet.GenericServlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class SecondServlet extends GenericServlet {
//我们要覆盖的是这个空参的init方法。如果覆盖了带参数的init方法,会导致下面使用
//config的地方出错。空参的init方法是留给我们覆盖的,方便。
@Override
public void init() throws ServletException {
System.out.println("init..."+this);
}
//适配器模式的一个知识点:适配器中的init(ServletConfig config)中帮我们把
//它当中的config对象赋值且调用 一个空参的init()。我们以后应该覆盖空参的init()。
//因为如果覆盖了这个带参数的,那么就无法实现为它的config对象赋值,由此导致其
//中使用config对象的方法会出错。
//在GenericServlet私有化一个config变量,然后在init(ServletConfig config)中
//做了一个 this.config = config 。这里是赋值语句,如果我们覆盖了这个方法,
//那么GenericServlet私有的config变量就是null。
//其实这种方法(调用 一个空参的init()且 该参数方法中什么也没做 )也程序员之
//间的一种交流方式,告诉我们要覆盖空参的方法,这样它在帮我们做完事情会调用
//我们的覆盖方法
// @Override
// public void init(ServletConfig config) throws ServletException {
//
// }
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
res.setContentType("text/html;charset=utf-8");
String name = req.getParameter("name");
String pwd = req.getParameter("pwd");
System.out.println("name:"+name+", pwd:"+pwd);
}
}
ThirdServlet
package cn.hncu.servlets.day2;
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 ThirdServlet extends HttpServlet {
//注意,采用继承HttpServlet的方式写servlet,doGet和doPost这两个方法通过都要覆盖,
//否则如果doGet方法没覆盖,有get请求时就会出现405错误,不覆盖doPost方法同理。
//这是HttpServlet中自己写的。具体的可以自己去看api的底层代码
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("doget...");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("dopost...");
}
}
RegServlet
package cn.hncu.servlets.day2;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.dom4j.Document;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.Node;
import cn.hncu.factory.Dom4jFactory;
public class RegServlet extends HttpServlet {
/**
* 查看所有用户
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
Document dom = Dom4jFactory.getDocument();
List<Element> users= dom.selectNodes("//user");
PrintWriter out = response.getWriter();
out.print("<html><body>");
for(Element e : users){
String id = e.attributeValue("id");
String del = " <a href='/servletDemo_jun/del?id="+id+"'>删除</a>";
out.print("用户名:"+e.attributeValue("name")+",密码:"+e.attributeValue("pwd")+del+"<br/>");
}
out.print("<a href='javascript:history.go(-1);'>返回</a>");
out.print("</body></html>");
}
/**
* 注册用户
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
String name = request.getParameter("name");
String pwd = request.getParameter("pwd");
Document dom = Dom4jFactory.getDocument();
Node node = dom.selectSingleNode("//user[@name='"+name.trim()+"']");
if(node!=null){//用户已经存在 不能创建
response.getWriter().write("该用户已存在,请重新输入");
}else{//可以注册
Element root = dom.getRootElement();
Element user = root.addElement("user");
user.addAttribute("id", UUID.randomUUID().toString().replaceAll("-", ""));
user.addAttribute("name", name);
user.addAttribute("pwd",pwd);
Dom4jFactory.save();
response.getWriter().write("注册成功");
response.getWriter().write("<a href='javascript:history.go(-1);'>返回</a>");
}
}
}
Dom4jFactory
package cn.hncu.factory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class Dom4jFactory {
private static Document dom = null;
private static String path;
static{
// 学习一下服务器下的资源路径加载方式(因为我们的资源已经从MyEclipse中
//发布到Tomcat服务器中了,所以跟原来纯Java项目不一样了)
// 利用当前类找到它的类加载器,然后通过该类加载器再去获得资源路径
try {
SAXReader sax = new SAXReader();
path = Dom4jFactory.class.getClassLoader().getResource("users.xml").getPath();
dom = sax.read(new FileInputStream(path));
} catch(Exception e) {
throw new RuntimeException("解析文档出错",e);
}
}
public static Document getDocument(){
return dom;
}
public static void save(){
try {
XMLWriter writer = new XMLWriter(new FileOutputStream(new File(path)));
writer.write(dom);
writer.close();
} catch (Exception e) {
throw new RuntimeException("保存出错");
}
}
// public static void main(String[] args) {
// System.out.println(getDocument());
// }
}
DdeServlet
package cn.hncu.servlets.day2;
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;
import org.dom4j.Document;
import org.dom4j.Node;
import cn.hncu.factory.Dom4jFactory;
public class DdeServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String delId = request.getParameter("id");
Document dom = Dom4jFactory.getDocument();
Node node = dom.selectSingleNode("//user[@id='"+delId+"']");
if(node != null){
node.getParent().remove(node);
Dom4jFactory.save();
}
response.sendRedirect("/servletDemo_jun/index.jsp");
}
}
users.xml
<?xml version="1.0" encoding="UTF-8"?>
<users>
</users>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>
<servlet>
<servlet-name>SecondServlet</servlet-name>
<servlet-class>cn.hncu.servlets.day2.SecondServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>ThirdServlet</servlet-name>
<servlet-class>cn.hncu.servlets.day2.ThirdServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>FirstServlet</servlet-name>
<servlet-class>cn.hncu.servlets.FirstServlet</servlet-class>
<init-param>
<param-name>name</param-name>
<param-value>jack</param-value>
</init-param>
<!--
<load-on-startup>15</load-on-startup>
-->
</servlet>
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>cn.hncu.servlets.LoginServlet</servlet-class>
<init-param>
<param-name>charset</param-name>
<param-value>utf-8</param-value>
</init-param>
</servlet>
<servlet>
<servlet-name>RegServlet</servlet-name>
<servlet-class>cn.hncu.servlets.day2.RegServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>DdeServlet</servlet-name>
<servlet-class>cn.hncu.servlets.day2.DdeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>FirstServlet</servlet-name>
<url-pattern>/first</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>SecondServlet</servlet-name>
<url-pattern>/second</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ThirdServlet</servlet-name>
<url-pattern>/third</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>RegServlet</servlet-name>
<url-pattern>/reg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>DdeServlet</servlet-name>
<url-pattern>/del</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>