首页 » Java » Servlets入门

Servlets入门

2017-06-21 13:20:07阅读(787)

1、ServletRequest

对于每个Http请求,Servlet容器会创建一个ServletRequest实例,并将它传给Servlet的Service方法,ServletRequest封装关于这个请求的信息

2、ServletResponse

表示一个Servlet响应,在调用Servlet的Service方法之前,Servlet容器会首先创建一个ServletResponse,作为第二个参数传入Service方法,ServletResponse隐藏了向浏览器发送响应的复杂过程

在ServletResponse定义的方法里有getWriter方法,它返回了一个可以向客户端发送文本的PrintWriter。

3、ServletConfig

Servlet容器初始化时会给init方法传入一个ServletConfig,ServletConfig封装了可以通过@WebServlet或部署描述符传给Servlet的配置信息,这样传入的每一条信息叫做一个初始化参数,一个初始化参数有key和value,可以通过调用ServletConfig的getInitParameter方法获取。
下面是ServletConfig的例子

@WebServlet(name = "ServletConfigDemo", urlPatterns = { "/ServletConfigDemo" }, initParams = {
        @WebInitParam(name = "admin", value = "Harry Taciak"),
        @WebInitParam(name = "email", value = "1778667492@qq.com") }
)
public class ServletConfigDemo implements Servlet {
    private transient ServletConfig servletConfig;
    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }
    @Override
    public ServletConfig getServletConfig() {
        // TODO Auto-generated method stub
        return servletConfig;
    }
    @Override
    public String getServletInfo() {
        // TODO Auto-generated method stub
        return "ServletConfig demo";
    }
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        // TODO Auto-generated method stub
        this.servletConfig = servletConfig;
    }
    @Override
    public void service(ServletRequest request, ServletResponse response)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        ServletConfig servletConfig = getServletConfig();
        String admin = servletConfig.getInitParameter("admin");
        String email = servletConfig.getInitParameter("email");
        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();
        writer.print("<html><head></head><body>" + "Admin:" + admin
                + "<br/>Email:" + email + "</body></html>");
    }
}

运行结果
这里写图片描述

4、ServletContext

每个Web应用程序只有一个上下文,在将程序同时部署到多个容器的分布式环境中,每台Java虚拟机上的Web应用都会有一个ServletContext对象
通过在ServletConfig中调用getServletContext方法,来获取ServletContext,得到后就可以共享从应用程序中的所有资料访问到的信息,而且还可以动态注册Web对象

5、GenericServlet

抽象类GenericServlet让上面的ServletConfigDemo的代码更简单,GenericServlet实现了Servlet和ServletConfig接口,并完成了init()方法的ServletConfig赋值,还实现了Serlvet的所有方法提供默认的实现

@WebServlet(name = "GenericServletDemo", urlPatterns = { "/GenericServletDemo" }, initParams = {
        @WebInitParam(name = "admin", value = "jyx"),
        @WebInitParam(name = "email", value = "1778667492@qq.com") })
public class GenericServletDemo extends GenericServlet {
    private static final long serialVersionUID=62500890L;
    @Override
    public void service(ServletRequest request, ServletResponse response)
            throws ServletException, IOException {
        ServletConfig servletConfig=getServletConfig();
        String admin=servletConfig.getInitParameter("admin");
        String email=servletConfig.getInitParameter("email");
        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();
        writer.print("<html><head></head><body>" + "Admin:" + admin
                + "<br/>Email:" + email + "</body></html>");    
    }
}

运行结果
这里写图片描述
效果一样,但代码变简洁了

会话管理 1、URL重写

URL重写是一种会话跟踪技术,它将一个或多个token添加到URL的查询字符串中,每个token通常是key=value形式,如
这里写图片描述

@WebServlet(name = "Top2Servlet", urlPatterns = { "/top10" })
public class Top2Servlet extends HttpServlet {
    private List<String> LondonAttrs;
    private List<String> ParisAttrs;
    @Override
    public void init() throws ServletException {
        LondonAttrs = new ArrayList<String>(10);
        ParisAttrs = new ArrayList<String>(10);
        LondonAttrs.add("London eye");
        LondonAttrs.add("2012 park");
        LondonAttrs.add("London eye");
        LondonAttrs.add("2012 park");
        LondonAttrs.add("London eye");
        LondonAttrs.add("2012 park");
        LondonAttrs.add("London eye");
        LondonAttrs.add("2012 park");
        LondonAttrs.add("London eye");
        LondonAttrs.add("2012 park");
        ParisAttrs.add("Notre Dame");
        ParisAttrs.add("Musee d");
        ParisAttrs.add("Notre Dame");
        ParisAttrs.add("Musee d");
        ParisAttrs.add("Notre Dame");
        ParisAttrs.add("Musee d");
        ParisAttrs.add("Notre Dame");
        ParisAttrs.add("Musee d");
        ParisAttrs.add("Notre Dame");
        ParisAttrs.add("Musee d");
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        String city = req.getParameter("city");
        if (city != null && (city.equals("london") || city.equals("paris"))) {
            showAttractions(req, resp, city);
        } else {
            showMainPage(req, resp);
        }
    }
    private void showMainPage(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {
        resp.setContentType("text/html");
        PrintWriter write = resp.getWriter();
        write.print("<html><head>" + "<title>Top 10</title>" + "</head><body>"
                + "please select city:"
                + "<br/><a href='?city=london'>London</a>"
                + "<br/><a href='?city=paris'>Paris</a>" + "</body></html>");
    }
    private void showAttractions(HttpServletRequest req,
            HttpServletResponse resp, String city) throws IOException {
        int page = 1;
        String pageParameter = req.getParameter("page");
        if (pageParameter != null) {
            page = Integer.parseInt(pageParameter);
            if (page > 2) {
                page = 1;
            }
        }
        List<String> attrs = null;
        if (city.equals("london")) {
            attrs = LondonAttrs;
        } else if (city.equals("paris")) {
            attrs = ParisAttrs;
        }
        resp.setContentType("text/html");
        PrintWriter write = resp.getWriter();
        write.println("<html><head>" + "<title>top 10 result</title>"
                + "</html></head>");
        write.println("<a href='top2'>Select city</a>");
        write.println("</hr> page"+ page+"<hr/>");
        int start=page*5-5;
        for(int i=start;i<start+5;i++){
            write.println(attrs.get(i)+"<br/>");
        }
        write.println("<hr/>"+
                        "<a href ='?city="+city+"&page=1'>page 1</a>"
                );
        write.println(
                "&nbsp; <a href ='?city="+city+"&page=2'>page 2</a>"
        );
        write.println("</body></html>");
    }
}

这里写图片描述
这里写图片描述

Session

本实例说明了如何使用 HttpSession 对象获取 session 会话创建时间和最后访问时间。如果不存在 session 会话,我们将通过请求创建一个新的 session 会话。

/**
 * Created by 在云端 on 2017/6/9.
 */
@WebServlet(name="MyServletSession", urlPatterns = { "/MyServletSession" })
public class MyServletSession extends HttpServlet {
    /*
    如果你修改了此类, 要修改此值。否则以前用老版本的类序列化的类恢复时会出错。为了在反序列化时,确保类版本的兼容性,
    最好在每个要序列化的类中加入private static final long serialVersionUID这个属性,具体数值自己定义。
     */
    private static final long serialVersionUID = 1L;
    @Override
    protected void doGet(HttpServletRequest request,
                         HttpServletResponse response) throws ServletException, IOException {
        //如果不存在session会话,则创建一个session对象
        HttpSession session = request.getSession(true);
        //获取session创建时间
        Date createTime = new Date(session.getCreationTime());
        //获取该网页的最后一次访问时间
        Date lastAccessTime = new Date(session.getLastAccessedTime());
        //设置日期输出的格式
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String title = "Servlet Session";
        Integer visitCount = new Integer(0);
        String visitCountkey = new String("visitCount");
        String userIDKey = new String("userID");
        String userID = new String("Runoob");
        //检查网页是否有新的访问者
        if (session.isNew()) {
            title = "Servlet Session";
            session.setAttribute(userIDKey, userID);
        } else {
            visitCount = (Integer) session.getAttribute(visitCountkey);
            visitCount = visitCount + 1;
            userID = (String) session.getAttribute(userIDKey);
        }
        session.setAttribute(visitCountkey, visitCount);
        //设置响应内容类型
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String docType = "<!DOCTYPE html>\n";
        out.println(docType +
                "<html>\n" +
                "<head><title>" + title + "</title></head>\n" +
                "<body bgcolor=\"#f0f0f0\">\n" +
                "<h1 align=\"center\">" + title + "</h1>\n" +
                "<h2 align=\"center\">Session 信息</h2>\n" +
                "<table border=\"1\" align=\"center\">\n" +
                "<tr bgcolor=\"#949494\">\n" +
                "  <th>Session 信息</th><th>值</th></tr>\n" +
                "<tr>\n" +
                "  <td>id</td>\n" +
                "  <td>" + session.getId() + "</td></tr>\n" +
                "<tr>\n" +
                "  <td>创建时间</td>\n" +
                "  <td>" + df.format(createTime) +
                "  </td></tr>\n" +
                "<tr>\n" +
                "  <td>最后访问时间</td>\n" +
                "  <td>" + df.format(lastAccessTime) +
                "  </td></tr>\n" +
                "<tr>\n" +
                "  <td>用户 ID</td>\n" +
                "  <td>" + userID +
                "  </td></tr>\n" +
                "<tr>\n" +
                "  <td>访问统计:</td>\n" +
                "  <td>" + visitCount + "</td></tr>\n" +
                "</table>\n" +
                "</body></html>");
    }
}

这里写图片描述

Servlet Context监听器

ServletContext,是一个全局的储存信息的空间,服务器开始,其就存在,服务器关闭,其才释放。request,一个用户可有多个;session,一个用户一个;而servletContext,所有用户共用一个。所以,为了节省空间,提高效率,ServletContext中,要放必须的、重要的、所有用户需要共享的线程又是安全的一些信息

ServletContext的监听器接口有两个:ServletContextListener和ServletContextAttributeListener

(1)ServletContextListener
ServletContextListener能对ServletContext的创建和销毁做出响应

/*
 *
 */
@WebListener
public class AppListener implements ServletContextListener {
//销毁ServletContext时调用
    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        // TODO Auto-generated method stub
    }
//创建ServletContext时调用
    @Override
    public void contextInitialized(ServletContextEvent ace) {
        ServletContext ServletContext = ace.getServletContext();
        Map<String, String> countries = new HashMap<String, String>();
        countries.put("ca", "Canada");
        countries.put("us", "United States");
        //设置ServletContext属性
        ServletContext.setAttribute("countries", countries);
    }
}

注意要添加jstl包

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>Country List</title>
</head>
<body>
    <c:forEach items="${countries}" var="country">
        <li>${country.value}</li>
    </c:forEach>
</body>
</html>

这里写图片描述

(2)ServletContextAttributeListener

//实现这个接口会收到web 应用中的servlet context属性链修改的通知  
public interface ServletContextAttributeListener extends EventListener {  
    /** Notification that a new attribute was added to the servlet context. Called after the attribute is added.*/  
    //一个属性被添加给servlet context之前会通知  
public void attributeAdded(ServletContextAttributeEvent scab);  
    /** Notification that an existing attribute has been removed from the servlet context. Called after the attribute is removed.*/  
    //属性被删除之后通知  
public void attributeRemoved(ServletContextAttributeEvent scab);  
    /** Notification that an attribute on the servlet context has been replaced. Called after the attribute is replaced. */  
    //属性被替换后通知  
public void attributeReplaced(ServletContextAttributeEvent scab);  
}  
Session Listener

(1)HttpSessionListener
同样销毁和创建时会调用它两个方法sessionDestroyed()、sessionCreated()

@WebListener
public class SessionListener implements HttpSessionListener,ServletContextListener{
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        HttpSession session=se.getSession();
        ServletContext servletContext=session.getServletContext();
        AtomicInteger userCounter=(AtomicInteger) servletContext.getAttribute("userCounter");
        int userCount=userCounter.incrementAndGet();
        System.out.println("userCount incremented to :"+userCount);
    }
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        HttpSession session=se.getSession();
        ServletContext servletContext=session.getServletContext();
        AtomicInteger userCounter=(AtomicInteger) servletContext.getAttribute("userCounter");
        int userCount=userCounter.decrementAndGet();
        System.out.println("--------userCount decremented to:"+userCount);  
    }
    @Override
    public void contextDestroyed(ServletContextEvent se) {  
    }
    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        ServletContext servletContext=arg0.getServletContext();
        servletContext.setAttribute("userCounter", new AtomicInteger());
    }
}

这个监听器用来统计HttpSession的数量,也就不同浏览器访问的个数,它使用AtomicInteger对象来统计,并且将这个对象保存成ServletContext范围的属性,每当有个HttpSession被创建,这个AtomicInteger对象就加一,每当有个HttpSession被销毁,这个AtomicInteger对象就减一,使用AtomicInteger是为了保证同步进行加减

访问http://jyx:8080/ServletDemo/countries.jsp效果
这里写图片描述
注意不同的浏览器访问才加1

(2)HttpSessionBindingListener
当有属性绑定或者解绑定到HttpSession时,这个监听器就会被调用

public class Product implements HttpSessionBindingListener {
    private String id;
    private String name;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    private double price;
    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        String attributeName = event.getName();
        System.out.println(attributeName + " valueBound");
    }
    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        String attributeName = event.getName();
        System.out.println(attributeName + " valueUnBound");
    }
}
ServletRequest Listener

ServletRequestListener会监听ServletRequest 的创建和销毁

public class PerfStatListener implements ServletRequestListener{
    @Override
    public void requestDestroyed(ServletRequestEvent arg0) {
        ServletRequest servletRequest=arg0.getServletRequest();
        Long start=(Long) servletRequest.getAttribute("start");
        Long end=System.nanoTime();
        //将servletRequest强制转换为HttpServletRequest
        HttpServletRequest httpServletRequest=(HttpServletRequest) servletRequest;
        String uri=httpServletRequest.getRequestURI();
        System.out.println("time taken to execute "+uri+
                ":"+((end-start)/1000)+"micoseconds");
    }
    @Override
    public void requestInitialized(ServletRequestEvent arg0) {
        ServletRequest servletRequest=arg0.getServletRequest();
        //java中System.nanoTime()返回的是纳秒
        servletRequest.setAttribute("start", System.nanoTime());
    }
}

总结
这些监听器分为三类:application范围、session范围和request范围,可以通过两种方法注册监听器,在实现类使用@WebListener注解或者在部署描述文件中增加listener元素

最新发布

CentOS专题

关于本站

5ibc.net旗下博客站精品博文小部分原创、大部分从互联网收集整理。尊重作者版权、传播精品博文,让更多编程爱好者知晓!

小提示

按 Ctrl+D 键,
把本文加入收藏夹