JSP(第五章:Servlet)

1 Servlet基础

2 Servlet技术开发

3 Servlet的典型应用

4 Servlet例子

5 Servlet过滤器

1 Servlet基础

Servlet是按照Servlet规范编写的Java类,使用Java Servlet接口(API),它可以处理Web应用中的相关请求。
Servlet是一种服务器端的Java应用程序,它的功能就是处理客户端请求,并做出响应。

1.1 model 2 模式

model 2 模式=JSP+Servlet+JavaBean

  • Controller:应用程序中用户交互部分(Servlet)
  • Model:应用程序数据逻辑部分(JavaBeans)
  • View:数据显示部分(JSP)

优点——职责清晰,较适合于大型项目架构

缺点——分层较多,不适合小型项目开发

1.2 Servlet的功能

  1. 创建并返回动态JSP页面
  2. 创建HTML或JSP中的片段
  3. 与服务器资源通信
  4. 处理多个客户的请求
  5. 图像转换
  6. 用户合法性认证

1.3 Servlet的特点

  1. 可移植性
  2. 功能强大
  3. 性能高
  4. 安全性
  5. 效率
  6. 节省投资
  7. 灵活性和扩张扩展性

1.4 Servlet的生命周期

Servlet的生命周期分为三个阶段。

1.初始化

init()方法:创建和初始化它在处理请求时需要用到的资源。

Tomcat服务器会装入Servlet:

  1. 可以配置启动服务器时自动装入Servlet
  2. 客户机首次向Servlet发出请求,创建一个Servlet实例,调用init()方法

仅执行一次,以后就不再执行。

2.处理请求

service()方法,从请求对象获得请求信息,处理该请求并用响应对象的方法将响应传回客户机。
对于到达服务器的客户机请求,服务器创建特定于请求的一个请求对象和一个响应对象。
service()方法可以调用doGet()或者doPost()等方法来处理请求。

3.终止

destroy()方法标志Servlet生命周期的结束。仅执行一次。

2 Servlet技术开发

2.1 Servlet核心

HttpServlet是GenericServlet的子类,所以从HttpServlet继承最合适。
HttpServlet为Servlet做出实现,并提供了Http请求的处理方法。

2.1.1 Servlet接口

  1. init():初始化Servlet类
  2. service():响应客户端请求
  3. destroy():摧毁Servlet实例以便收回占有的资源

2.1.2 HttpServletRequest接口

  1. getContextPath():返回上下文路径。
  2. getCookies():返回HTTP请求中的所有的Cookie。
  3. getMethod():返回HTTP请求方式,如post,或get。
  4. getQueryString():返回HTTP请求中的查询字符串。
  5. getRequestURI():返回主机名到请求参数之间部分的字符串。

2.1.3 HttpServletResponse接口

  1. addCookie(Cookie):增加一个cookie到响应中
  2. sendRedirect():重定向
  3. sendError():向客户端发送错误信息

2.1.4 HttpServlet抽象类

  1. 一般通过继承HttpServlet抽象类重写它的doGet()和doPost()方法就可以实现自己的Servlet。

HttpServletRequest:封装了客户端到服务器端一系列的请求。
HttpServletResponse:封装了服务器端返回给客户端的对象。

2.2 Servlet的配置问题

  1. web.xml中配置servlet是Servlet 3.0之前的配置方式
  2. Servlet 3.0可以通过注解方式配置

开发Servlet3的程序需要一定的环境支持。Servlet3是Java EE6规范的一部分,MyEclipse10和Tomcat7都提供了对Java EE6规范的支持。
Tomcat需要Tomcat7才支持Java EE6,Tomcat7需要使用JDK6。

2.3 表单的action属性设置

第一种方式——绝对路径
action=”/ch6_example4/AddServlet”
ch6_example4为工程名
第二种方式——绝对路径
action=”<%=request.getContextPath()%>/AddServlet”
第三种方式——相对路径
action=”my/HelloWorldServlet”
/my/HelloWorldServlet
注意:AddServlet前不要加/
因为/代表根目录,加/后对于Tomcat而言代表webApps那个目录,没有项目名

3 Servlet的典型应用

3.1 读取表单数据

getParameter()——获取到客户端通过表单或url请求参数发送过来的参数值
getParameterValues()——如果参数出现一次以上,则调用该方法,并返回多个值,如复选框
getParameterNames()——如果想要得到当前请求中的所有参数的完成列表,则调用该方法
getParameterMap()——将参数封装成Map类型

3.2 实现页面转发

RequestDispatcher接口:

forward(ServletRequest,ServletResponse)——用于将Servlet传递给服务器上另外的Servlet、JSP页面或者HTML文件。再forward()方法调用之后,原来在响应缓存中的没有提交的内容自动清除!原来的Servlet终止!

include(ServletRequest,ServletResponse)——与forward()方法一样,但Servlet对该请求做出的响应将进入原来的响应对象中,原来的Servlet还可以继续输出响应信息

3.3 读取当前页面的绝对路径

PrintWriter out = response.getWriter();
ServletContext context=this.getServletContext();
out.println("真实路径为:"+context.getRealPath(""));
【输出为:】
C:\Users\Administrator\Workspaces\MyEclipse 2016 CI\.metadata\.me_tcat7\webapps\ch6_example5

3.4 Servlet操作Cookie

Cookie是由服务器端生成,发送给浏览器,浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用cookie)。

Cookie:服务器端写到客户端的文本信息,是以名-值-对的形式。

服务器可以利用Cookies包含信息的任意性来筛选并经常性维护这些信息,以判断在HTTP传输中的状态。Cookies最典型的应用是判定注册用户是否已经登录网站,用户可能会得到提示,是否在下一次进入此网站时保留用户信息以便简化登录手续,这些都是Cookies的功用。另一个重要应用场合是“购物车”之类处理。用户可能会在一段时间内在同一家网站的不同页面中选择不同的商品,这些信息都会写入Cookies,以便在最后付款时提取信息。

注意HTTP协议是无连接的,含义就是当客户端从服务器端得到某个文件的内容时,连接就会中断,相当于socket的close方法。但是考虑购物网站,当你在一个页面购买了东西,连接就断了,当你又访问另外一个页面去结账时,这时就不知道购买的东西是什么了。这时的解决办法就是cookie。也就是当你购买了某种商品后,服务器就在客户端记录下相应的信息来,这就是cookie。
但是要遵循两个原则:
(1)只允许写文本文档,不允许写其他类型的文件,避免那些恶意的程序。
(2)客户端可以阻止服务器写入。

4 Servlet例子

4.1【User.java】

package my.bean;

public class User {
    private String name;
    private int age;
    private String sex;
    private String address;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }

}

4.2【AddServlet.java】

package my.servlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import my.bean.User;

/**
 * Servlet implementation class AddServlet
 */
@WebServlet("/AddServlet")
public class AddServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public AddServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.getWriter().append("Served at: ").append(request.getContextPath());
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html");

        String name=request.getParameter("name");
        String ageStr=request.getParameter("age");
        String sex=request.getParameter("sex");
        String address=request.getParameter("address");

        String regex="^\\+?[1-9][0-9]*$";
        int age=0;
        if(ageStr.matches(regex)) {//判断是否满足正则表达式
            age=Integer.parseInt(ageStr);
        }

        User user=new User();
        user.setName(name);
        user.setAge(age);
        user.setSex(sex);
        user.setAddress(address);

        ServletContext application=getServletContext();

        List<User> lt=(List<User>)application.getAttribute("users");
        if(lt==null) {
            lt=new ArrayList<User>();
        }
        lt.add(user);
        application.setAttribute("users", lt);

        //转发
        request.getRequestDispatcher("/list.jsp").forward(request, response);
    }
}

4.3【index.jsp】

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <form action="AddServlet" method="post">
        <table>
            <tr>
                <td>姓名</td>
                <td><input type="text" name="name"></td>
            </tr>
            <tr>
                <td>年龄</td>
                <td><input type="text" name="age"></td>
            </tr>
            <tr>
                <td>性别</td>
                <td><input type="radio" name="sex" value="男" checked="checked">男<input type="radio" name="sex" value="女">女</td>
            </tr>
            <tr>
                <td>地址</td>
                <td><input type="text" name="address"></td>
            </tr>
            <tr>
                <td><input type="submit" value="添加"></td>
            </tr>
        </table>
    </form>
</body>
</html>

4.4【list.jsp】

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*,my.bean.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <table border="1">
    <% List <User> lt=(List<User>)application.getAttribute("users");%>
        <% if(lt!=null){ 
            for(User user:lt){ %>
                <tr>
                    <td><%=user.getName() %></td>
                    <td><%=user.getSex() %></td>
                    <td><%=user.getAge() %></td>
                    <td><%=user.getAddress() %></td>
                </tr>
    <% }} %>
    </table>
<//body>
</html>

4.5 效果图

服务器不关闭,可以一直添加信心。

5 Servlet过滤器

5.1 过滤器简介

Servlet过滤器与Servlet十分相似,但它具有拦截客户端(浏览器)请求的功能,Servlet过滤器可以改变请求中的内容,来满足实际开发中的需要。对于程序开发人员而言,过滤器实质就是在Web应用服务器上的一个Web应用组件,用于拦截客户端(浏览器)与目标资源的请求,并对这些请求进行一定过滤处理再发送给目标资源,过滤器的处理方式如下图所示。

5.2 过滤器的核心对象

过滤器对象放置在javax.servlet包中,其名称为Filter,它是一个接口。除这个接口外,与过滤器相关的对象还有FilterConfig对象FilterChain对象,这两个对象也同样是接口对象,位于javax.servlet包中,分别为过滤器的配置对象与过滤器的传递工具。

创建一个过滤器对象需要实现javax.servlet.Filter接口,同时实现Filter接口的三个方法。

5.3 过滤器应用

1.字符编码过滤器(注解方式)

package my.pack;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;

// 字符编码过滤器
@WebFilter(filterName="AMyFilter",urlPatterns = "/*")//urlPatterns指定过滤器对谁起作用,/*表示全部
//@WebInitParam指定初始化的参数
public class MyCharactorFilter implements Filter {
    // 字符编码
    public  void destroy() {
    }
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        // 设置request的编码格式    
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html");

        System.out.println("类名:MyCharactorFilter=注释名:AMyFilter");
        // 传递给下一过滤器
        chain.doFilter(request, response);    
    }
    public void init(FilterConfig filterConfig) throws ServletException {
    }
}

2.记录访客数量(注解方式)

2.1【CountFilter.java】

package my.pack;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
@WebFilter(filterName = "BMyFilter", urlPatterns = "/*",//urlPatterns指定过滤器对谁起作用,/*表示全部
initParams = {@WebInitParam(name = "count",value="10000")})
//@WebInitParam指定初始化的参数
public class CountFilter implements Filter{

    //来访数量
    private int count;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //获取初始化参数
        String param=filterConfig.getInitParameter("count");
        //将字符串转换为int
        count=Integer.valueOf(param);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse resoinse, FilterChain chain)
            throws IOException, ServletException {
        //访问数量自增
        count++;
        //将ServletRequest转换成HttpServletReuqest
        HttpServletRequest req =(HttpServletRequest) request;
        //获取ServletContext的全局对象
        ServletContext context=req.getServletContext();
        //将来访数量放入到ServletContext中
        context.setAttribute("count", count);

        System.out.println("类名:CountFilter=注解名:BMyFilter");

        //向下传递过滤器(!必须写!)
        chain.doFilter(request, resoinse);    
    }    
}

2.2【index.jsp】

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h2>
        欢迎光临,<br>
        您是本站的第【<%=application.getAttribute("count") %>】为访客!
    </h2>
</body>
</html>

2.3 效果图

刷新页面数字+1

5.4 过滤器执行顺序

过滤器运行顺序是按照 过滤器类名 的次序,并且注释名不能决定。

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

客官,赏一瓶怡宝吧。

支付宝
微信