学习:JAVAEE_4 Filter/Listener/发送邮件/MD5算法

Filter

Filter:一个实现了特殊接口(Filter)的Java类. 实现对请求资源(jsp,servlet,html,)的过滤的功能.

过滤器是一个运行在服务器的程序(项目里面包含了过滤器,只要发布(启动)了项目,过滤器就会运转),优先于请求资源(Servlet或者jsp,html)之前执行. 过滤器是javaweb技术中最为实用的技术.

过滤器的作用

  • 对目标资源(Servlet,jsp)进行过滤.

  • 应用场景:登录权限检查,解决网站中文编码统一,过滤敏感字符 ...

通过xml配置方式

/*
    1. 实现接口Filter

    2. 注册过滤器 , web.xml
 */

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

public class DemoFilter01 implements Filter{

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    System.out.println("DemoFilter01::init~!");
    //假设存在这样的需求,就是在这个init方法里面读取某个文件的内容。
    //但是又不想直接在init方法里面硬编码写死这个文件的名字,此时可以使用初始化参数来配置文件的名字
    String fileName = filterConfig.getInitParameter("fileName");
    System.out.println("fileName=" + fileName);
  }

  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    System.out.println("DemoFilter01::doFilter~!");
  }

  @Override
  public void destroy() {
    System.out.println("DemoFilter01::destroy~!");
  }
}

web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_2_5.xsd"
         version="2.5">

  <!--注册DemoFilter01-->
  <filter>
    <filter-name>demo01</filter-name>
    <filter-class>com.zml.filter.demo.DemoFilter</filter-class>
  <!--配置初始化参数-->
    <init-param>
      <param-name>fileName</param-name>
      <param-value>C:/aa/bb/cc.jpg</param-value>
    </init-param>
  </filter>

  <!--以后只要浏览器打过来这个地址:  localhost:8080/项目映射名/aa-->
  <filter-mapping>
    <filter-name>demo01</filter-name>
    <url-pattern>/aa</url-pattern>
  </filter-mapping>
</web-app>

通过注解方式

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter("/bb")
public class DemoFilter02 implements Filter{

 @Override
 public void init(FilterConfig filterConfig) throws ServletException {
     System.out.println("DemoFilter02::init~!");
 }

 @Override
 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
     System.out.println("DemoFilter02::doFilter~!");
 }

 @Override
 public void destroy() {
     System.out.println("DemoFilter02::destroy~!");
 }
}

Filter的生命周期

生命周期方法

  • init(FilterConfig):初始化 服务器启动的时候, 会调用init()方法进行初始化【调用一次】

  • doFilter(ServletReqeust req,ServletResponse resp,FilterChain chain):执行过滤的方法 任何一次请求都会调用doFilter()方法进行过滤【路径相匹配】

  • destroy():销毁 服务器正常关闭或者项目从服务器移除, 调用destroy()方法进行销毁【调用一次】

Filter的拦截方式

我们可以控制过滤器过滤指定的内容,但是我们在访问资源的时候,并不是每次都是直接访问,有时是以转发的方式访问的 (过滤器默认不过滤请求转发。),这就需要我们要让过滤器可以区分不同的访问资源的方式,有不同的拦截方式。 通过 DispatcherType 来指定的.

一般情况下, 转发我们不会过滤的. 转发属于服务器内部的行为. 直接使用默认值的情况偏多

  • DispatcherType.REQUEST

默认值,默认情况下,过滤器只会拦截浏览器发出来的请求。但是如果是一个Servlet请求转发跳转到另一个Servlet,这段跳转,过滤器默认不会过滤。

  • DispatcherType.FORWARD

    只过滤转发过来的请求

/*@WebFilter("/*")
urlpatterns :  对应就是这个过滤器它想过滤的资源请求路径
dispatcherTypes :过滤的方式。默认只会过滤浏览器过来的请求: DispatcherType.REQUEST
    如果还想过滤请求转发的请求,需要额外加上 DispatcherType.FORWARD*/
@WebFilter(urlPatterns = "/*" ,dispatcherTypes= {DispatcherType.REQUEST,DispatcherType.FORWARD})
public class DemoFilter07 implements Filter{

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("DemoFilter07::init~!");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("DemoFilter07::doFilter~!");

        //放行
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("DemoFilter07::destroy~!");
    }
}

过滤器链

过滤器链机制:当一个filter收到请求的时候,调用chain.doFilter 放行才可以访问下一个匹配的filter,若当前的filter是最后一个filter,调用chain.doFilter 放行才能访问目标资源 。 前一个过滤器不放行,那么请求不会到达下一个过滤器或者目标资源

  • 过滤器链执行顺序

    • 配置文件: 谁先配置filter-mapping 谁先执行

    • 注解方式: 按照Filter的首字母顺序 eg: AFilter BFilter A在B的前面, AFilter先执行

非法字符过滤案例

@WebServlet("/data/comment")
public class CommentServlet extends HttpServlet {

 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     System.out.println("CommentServlet...doGet...");


     //1. 获取要发布的评论内容
     String comment = req.getParameter("comment");

     //2. 直接输出到页面上
     resp.getWriter().write("您发布的评论是:"+ comment);
 }

 @Override
 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     System.out.println("CommentServlet...doPost...");
     doGet(req, resp);
 }
}
/*
    1. 拷贝敏感词汇文件到项目里面的web文件夹下
    2. 在init方法里面读取敏感词汇文件  ServletContext
    3. 把文件的内容保存到一个List集合中
 */

@WebFilter("/data/*")
public class CommentFilter implements Filter{

    static List<String> wordsList = new ArrayList<>();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        try {
            System.out.println("CommentFilter::init~!");

            //1. 得到servletcontext
            ServletContext servletContext = filterConfig.getServletContext();

            //2. 读取文件
            InputStream is = servletContext.getResourceAsStream("IllegalWords.txt");

            //3. 使用bufferreader来包装is ,以便可以按行来读内容 , 如果有中文,需要指定编码
            BufferedReader br = new BufferedReader(new InputStreamReader(is , "utf-8"));

            //4. 开始读取每一行
            String line ;
            while( (line = br.readLine()) != null){
                //5. 把每一行都装到集合list里面
                wordsList.add(line);
            }

            //6. 关闭流
            br.close();
            System.out.println("list=" + wordsList);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("CommentFilter::doFilter~!");



        //1. 获取先要发布的评论内容
        String comment = servletRequest.getParameter("comment");

        //2. 判定是否含有敏感词汇
        for(String word :wordsList){
            if(comment.contains(word)){
                //有敏感词汇
                servletResponse.getWriter().write("含有敏感词汇,禁止发表!");

                return;
            }
        }
        //3. 如果没有敏感词汇,就直接放行
        filterChain.doFilter(servletRequest, servletResponse);

    }

    @Override
    public void destroy() {
        System.out.println("CommentFilter::destroy~!");
    }
}

Listener

  • 监听器就是一个Java类,用来监听 其他的JavaBean对象的变化

    • 在javaweb中监听器就是监听三个作用域对象的状态的。request,session,servletContext(application),

    • 说的具体一些就是监听这三个对象的创建和销毁,还有session里面的数据变化(钝化和活化)

JavaWeb的监听器使用步骤

  • 创建一个类实现ServletContextListener

  • 在web.xml配置 | 在类上使用注解配置(只要配置一次即可)

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

/*
    1. 定义一个类,实现接口 ServletContextListener

    2. 实现方法:
        contextInitialized: servletcontext创建的时候调用, 项目发布的时候,
        contextDestroyed: servletcontext销毁的时候调用, 项目从服务器中移除,服务器关闭了

    3. 注册|配置 监听器
        注解: @WebListener
        xml:
            <listener>
                <listener-class>com.itheima.listener.MyServletContextListener</listener-class>
            </listener>
 */

@WebListener
public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("contextInitialized...");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("contextDestroyed...");
    }
}

web.xml文件配置

<listener>
  <listener-class>com.itheima.listener.MyServletContextListener</listener-class>
</listener>

发送邮件案例

需要使用jar包: mail.jar

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;

public class SendMessages {
  public static void Send(String tittle,String value) throws MessagingException {
    Properties properties = new Properties();
    properties.put("mail.transport.protocol", "smtp"); // 连接协议
    properties.put("mail.smtp.host", "smtp.qq.com"); // 主机名
    properties.put("mail.smtp.port", 465); // 端口号
    //        properties.put("mail.smtp.auth", "true");  // 需要验证 QQ邮箱开启后会发送到垃圾箱中
    properties.put("mail.smtp.ssl.enable", "true"); // 是否启用ssl认证
    properties.put("mail.debug", "true"); // 调试信息

    // 得到会话对象
    Session session = Session.getInstance(properties);

    // 获取邮件对象
    Message mimeMessage = new MimeMessage(session);

    // 设置发件人
    mimeMessage.setFrom(new InternetAddress("247321017@qq.com"));
    // 设置收件人
    mimeMessage.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress("123456@qq.com"));
    // 设置邮件主题
    mimeMessage.setSubject(tittle);
    // 设置邮件内容
    mimeMessage.setText(value);

    // 得到邮件传输对象
    Transport transport = session.getTransport();
    // 连接自己的邮箱账户
    transport.connect("247321017@qq.com", "qzznvklcxxxxxxx"); // 密码为QQ邮箱提供的授权码
    // 发送邮件
    transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
  }

MD5加密算法

package com.example.basic;

import java.security.MessageDigest;

/**
 * 写一个MD5算法,运行结果与MySQL的md5()函数相同
 * 将明文密码转成MD5密码
 * 123456->e10adc3949ba59abbe56e057f20f883e
 */
public  class Md5Util {
	private Md5Util(){}
	/**
	 * 将明文密码转成MD5密码 
	 */
	public static String encodeByMd5(String password) throws Exception{
		//Java中MessageDigest类封装了MD5和SHA算法,今天我们只要MD5算法
		MessageDigest md5 = MessageDigest.getInstance("MD5");
		//调用MD5算法,即返回16个byte类型的值
		byte[] byteArray = md5.digest(password.getBytes());
		//注意:MessageDigest只能将String转成byte[],接下来的事情,由我们程序员来完成
		return byteArrayToHexString(byteArray);
	}
	/**
	 * 将byte[]转在16进制字符串 
	 */
	private static String byteArrayToHexString(byte[] byteArray) {
		StringBuffer sb = new StringBuffer();
		//遍历
		for(byte b : byteArray){//16次
			//取出每一个byte类型,进行转换
			String hex = byteToHexString(b);
			//将转换后的值放入StringBuffer中
			sb.append(hex);
		}
		return sb.toString();
	}
	/**
	 * 将byte转在16进制字符串 
	 */
	private static String byteToHexString(byte b) {//-31转成e1,10转成0a,。。。
		//将byte类型赋给int类型
		int n = b;
		//如果n是负数
		if(n < 0){
			//转正数
			//-31的16进制数,等价于求225的16进制数 
			n = 256 + n;
		}
		//商(14),数组的下标
		int d1 = n / 16;
		//余(1),数组的下标
		int d2 = n % 16;
		//通过下标取值
		return hex[d1] + hex[d2];
	}
	private static String[] hex = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
	/**
	 * 测试
	 */
	public static void main(String[] args) throws Exception{
		String password = "123456";
		String passwordMD5 = Md5Util.encodeByMd5(password);
		System.out.println(password);
		System.out.println(passwordMD5);
	}
}

综合练习CRUD

注册登录添加查询功能

基础对象的创建

// 数据库表对应的对象
public class LinkMan implements Serializable{
private int id;
private String name;
private String sex;
private int age;
// get set 有参 无参构造方法
}

// 分页查询数据封装对象
public class PageBean<T> {
private List<T> list; //联系人列表
private int curPage;//当前页码
private int sumPage;//总页码
private int count;//总数量
private int curSize;//一页显示的数量
}

web层代码

@WebServlet("/linkManServlet")
public class LinkManServlet extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 //0.处理乱码
 request.setCharacterEncoding("utf-8");
 response.setContentType("text/html;charset=utf-8");

 //1.获得method请求参数
 String methodStr = request.getParameter("method");

 // 使用反射的方式调用方法
 // 获取现在要请求的是什么动作|方法,获取method的值
 String methodName = req.getParameter("method");  //这个method其实就是方法名!

 //2. 由于method 从页面上传递过来的其实就是方法名
 // 如果是查询所有,那么传递过来的是 findAll
 // 如果是添加联系人,页面传递过来的是add
 //有了方法名就可以直接调用方法。有对象才能调用。

 //2.1 使用方法名,在当前这个类上找到方法。
 //使用反射去找方法的时候,除了要写对方法的名字之外,还要写对方法的参数类型。
 // this : 当前这个类的对象 this.getClass 得到这个类的字节码
 //getMethod 就表示要在这个类上找它的一个方法
 // 参数一: 方法名字
 //参数二: 这个方法需要的第一个参数的类型
 //参数三: 这个方法需要的第二个参数的类型。
 Method m = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);

 //2.2 调用方法
 //m 就是刚才找到的方法
 //m.invoke 是一种反射调用的写法
 // 参数一:  调用这个方法使用的对象是什么, this.
 // 参数二: 调用这个方法需要用到的参数 req
 // 参数三: 调用这个方法需要用到的第二个参数 resp
 m.invoke(this , req, resp);

} catch (Exception e) {
 e.printStackTrace();
}
/*
     //2. 判定到底想要执行的是什么方法
     if("findAll".equals(method)){
         findAll(req, resp); //执行查询所有的方法
     }else if("add".equals(method)){
         add(req,resp);  //执行添加方法
     }else if("delete".equals(method)){
         delete(req , resp); //执行删除方法
     }else if("findByPage".equals(method)){
         findByPage(req,resp);
     }*/

}

//删除联系人
public void delete(HttpServletRequest request,HttpServletResponse response){
try {
 //1. 获取参数
 int id = Integer.parseInt(req.getParameter("id"));

 //2. 交代service
 LinkManService service = new LinkManService();
 int row = service.delete(id);

 //3. 响应
 if(row > 0){ //删除成功
   //跳转到列表页面显示最新的数据,但是切忌直接跳转到list.jsp页面
   findAll(req, resp);
 }
} catch (SQLException throwables) {
 throwables.printStackTrace();
}

}

//查询所有的联系人
public void findAll(HttpServletRequest request,HttpServletResponse response){
try {
 //如果想要在这个方法上存值,或者跳转页面。

 //1. 获取参数 ,由于是查询所有的联系人,所以这一步不用写!

 //2. 调用service。
 LinkManService service = new LinkManService();
 List<LinkMan> list = service.findAll();

 //3. 响应
 //3.1 先把list集合存到作用域里面去 request作用域 | session作用域
 req.setAttribute("list", list);

 //3.2 跳转到list.jsp : 请求转发,重定向
 req.getRequestDispatcher("list.jsp").forward(req, resp);
} catch (Exception e) {
 e.printStackTrace();
}
}

//添加联系人
public void add(HttpServletRequest request,HttpServletResponse response){
try {
 //1. 获取所有参数
 Map<String, String[]> map = req.getParameterMap();

 //1.1 把map的数据封装到对象中。
 LinkMan linkMan = new LinkMan();
 BeanUtils.populate(linkMan , map);

 //2. 交代service干活
 LinkManService service = new LinkManService();
 int row = service.add(linkMan);

 //3. 响应 ,判定结果
 if(row > 0 ){ //添加成功
   //跳转到list.jsp页面,显示最新的数据。 添加完毕之后不能直接跳转到到list.jsp页面,
   // 因为没有查询数据,所以页面不会有任何显示。
   //req.getRequestDispatcher("list.jsp").forward(req, resp);
   findAll(req,resp);
 }
} catch (Exception e) {
 e.printStackTrace();
}
}

//分页展示联系人
public void findByPage(HttpServletRequest req, HttpServletResponse resp){

try {
 //0. 一开先设置好默认展示第1页,每页展示5条记录。
 int currentPage = 1;
 int pageSize = 2;

 /*
            1. 获取参数
                1.1 有时候可以不用携带参数过来,有时候也可以携带参数过来
                1.2 比如在index.jsp里面的分页入口,就可以不用携带参数
                1.3 比如在分页列表页面上,允许用户选择:想看其中的第几页,每页想看多少条。
                1.4 为了能够匹配更多的情况,这里的就需要获取参数。
                1.5 如果也面有传递想看第几页,每页想看多少条,那么就是用页面传递过来的,否则就使用默认定义的。
         */
    String currentPageStr = req.getParameter("currentPage"); //想看第几页
    String pageSizeStr = req.getParameter("pageSize"); //每页想看几条。

    if(currentPageStr != null){
      currentPage = Integer.parseInt(currentPageStr);
    }
    if(pageSizeStr!= null){
      pageSize = Integer.parseInt(pageSizeStr);
    }

    //2. 交代service干活
    LinkManService service = new LinkManService();
    PageBean<LinkMan> pageBean = service.findByPage(currentPage , pageSize);

    //3. 响应
    //3.1 把pageBean存到作用域
    req.setAttribute("pageBean" , pageBean);

    //3.2 跳转到list_page.jsp显示数据
    req.getRequestDispatcher("list_page.jsp").forward(req, resp);
  } catch (Exception e) {
    e.printStackTrace();
  }

  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request, response);
  }
}

Service层代码

public List<LinkMan> findAll() throws SQLException {
  //创建dao对象
  LinkManDao dao  = new LinkManDao();

  //调用findAll方法~
  return dao.findAll();
}

public int add(LinkMan linkMan) throws SQLException {

  //调用Dao的add方法!
  LinkManDao dao = new LinkManDao();
  return dao.add(linkMan);
}

public int delete(int id) throws SQLException {

  //调用dao的delete方法
  LinkManDao dao = new LinkManDao();
  return dao.delete(id);
}

/**
     * 分页查询联系人
     * @param currentPage 想看第几页
     * @param pageSize 每页想看多少条
     * @return PageBean 里面封装了当前页的集合数据以及页码使用的信息。
     */
public PageBean<LinkMan> findByPage(int currentPage , int pageSize) throws SQLException {
  //1. 创建PageBean对象
  PageBean<LinkMan> pageBean = new PageBean<LinkMan>();

  //1.1 调用dao,准备数据
  LinkManDao dao = new LinkManDao();
  // 获取当前这一页的集合数据
  List<LinkMan> list = dao.findByPage(currentPage, pageSize);

  // 总记录数 101
  int totalSize = dao.findCount();

  //向上取整计算总页数: 101/10 = 10.1  ---> 11   10.9 ----> 11
  // int totalPage = (int) Math.ceil(totalSize * 1.0 / pageSize);
  int totalPage = ((totalSize -1) / pageSize) + 1;

  //2. 封装PageBean
  pageBean.setPageSize(pageSize); //每页显示个数 10
  pageBean.setTotalSize(totalSize); //总记录数,代表就是这张LinkMan表有多少条记录。

  pageBean.setCurrentPage(currentPage); //当前页是第几页
  pageBean.setTotalPage(totalPage); // 总共多少页

  pageBean.setList(list); //当前这一页的集合数据

  return pageBean;
}

Dao层代码

public List<LinkMan> findAll() throws SQLException {
  //创建QueryRunner对象
  QueryRunner runner = new QueryRunner(C3P0Utils.getDataSource());

  //定义Sql语句
  String sql = "select * from linkman";

  //执行查询,由于查询所有,所以得到的数据很多,那么必须要传的是BeanListHandler。
  return runner.query(sql ,new BeanListHandler<LinkMan>(LinkMan.class));
}

public int add(LinkMan linkMan) throws SQLException {
  //创建QueryRunner对象
  QueryRunner runner = new QueryRunner(C3P0Utils.getDataSource());
  //定义Sql语句
  String sql = "insert into linkman values(null,?,?,?)";
  //执行添加
  return runner.update(sql, linkMan.getName() , linkMan.getSex() ,linkMan.getAge());
}

public int delete(int id ) throws SQLException {

  //创建QueryRunner
  QueryRunner runner = new QueryRunner(C3P0Utils.getDataSource());
  //删除语句
  String sql = "delete from linkman where id = ?";

  //执行删除
  return runner.update(sql , id );
}

//==============下面的两个方法专门用来做分页的==================

/**
     * 返回linkMan表的总记录数
     * @return
     */
public int findCount() throws SQLException {
  QueryRunner runner = new QueryRunner(C3P0Utils.getDataSource());
  String sql = "select count(*) from linkman";

  //查询总记录数,对于这种聚合查询(查总数、最大值、平均值、最小值...)得到的都是一个数字回来
  //一般就是用ScalarHandler来处理结果 ,这种聚合查询回来的是一个long类型。
  long result = (long) runner.query(sql , new ScalarHandler());
  return (int) result;
}

/**
     * 查询当前某一页的集合数据
     * @param currentPage 具体第几页
     * @param pageSize 每页显示多少条
     * @return 返回这一页集合数据List<LinkMan>
     */
public List<LinkMan> findByPage(int currentPage , int pageSize) throws SQLException {
  QueryRunner runner = new QueryRunner(C3P0Utils.getDataSource());
  //定义sql语句,要注意这里是分页查询记录的语句,所以limit关键字肯定少不了
  String sql = "select * from linkman limit ? , ? ";
  // 参数一: sql语句,参数二: 结果集的处理器
  //参数三: 忽略|跳过前面的多少条记录,参数四:每页显示多少条记录
  return  runner.query(sql , new BeanListHandler<LinkMan>(LinkMan.class) ,(currentPage - 1) * pageSize, pageSize);
}

前端JSP页面

herf 属性中调用js函数的方法 href="javascript:方法名(EL表达式)"

<h3 style="text-align: center">显示所有联系人</h3>
<table border="1" class="table table-bordered table-hover">
  <tr class="success">
    <th>编号</th>
    <th>姓名</th>
    <th>性别</th>
    <th>年龄</th>
  </tr>
  <c:forEach items="${list}" var="linkMan" varStatus="i">
    <tr>
      <td>${i.count}</td>
      <td>${linkMan.name}</td>
      <td>${linkMan.sex}</td>
      <td>${linkMan.age}</td>
      <td><a class="btn btn-default btn-sm" href="修改联系人.html">修改</a>&nbsp;

        <%-- herf 属性中调用js函数的方法 href="javascript:方法名(EL表达式)"

  <a class="btn btn-default btn-sm" href="linkManServlet?method=delete&id=${linkMan.id}">删除</a> --%>

        <a class="btn btn-default btn-sm" href="javascript:del(${linkMan.id})">删除</a>
      </td>
    </tr>
  </c:forEach>
  <tr>
    <td colspan="8" align="center">
      <a class="btn btn-primary" href="${pageContext.request.contextPath }/add.jsp">添加联系人</a></td>
  </tr>
</table>

<script>
  function del(id) {
    if (confirm("确定要删除吗?")) {
      location.href = "linkManServlet?method=delete&id=" + id;
    }
  }
</script>
<%        -------------------         %>
<h3>添加联系人页面</h3>
<form action="linkManServlet?method=add" method="post">
  <div class="form-group">
    <label for="name">姓名:</label>
    <input type="text" class="form-control" id="name" name="name" placeholder="请输入姓名">
  </div>

  <div class="form-group">
    <label>性别:</label>
    <input type="radio" name="sex" value="男" checked="checked"/>男
    <input type="radio" name="sex" value="女"/>女
  </div>

  <div class="form-group">
    <label for="age">年龄:</label>
    <input type="text" class="form-control" id="age" name="age" placeholder="请输入年龄">
  </div>

  <div class="form-group" style="text-align: center">
    <input class="btn btn-primary" type="submit" value="提交" />
    <input class="btn btn-default" type="reset" value="重置" />
    <input class="btn btn-default" type="button" value="返回" />
  </div>
</form>
<%        -------------------         %>

<h3 style="text-align: center">分页所有联系人</h3>
<table border="1" class="table table-bordered table-hover">
  <tr class="success">
    <th>编号</th>
    <th>姓名</th>
    <th>性别</th>
    <th>年龄</th>
    <th>操作</th>
  </tr>
  <c:forEach items="${pageBean.list}" var="linkMan" varStatus="i">
    <tr>
      <td>${i.count}</td>
      <td>${linkMan.name}</td>
      <td>${linkMan.sex}</td>
      <td>${linkMan.age}</td>
      <td><a class="btn btn-default btn-sm" href="修改联系人.html">修改</a>&nbsp;
        <a class="btn btn-default btn-sm" href="linkManServlet?method=delete&id=${linkMan.id}">删除</a></td>
    </tr>
  </c:forEach>
  <tr>
    <td colspan="8" align="center">
      <ul class="pagination success">
        <%--如果现在的当前页是第一页,那么禁止点击 << 回到前一页--%>
        <c:if test="${pageBean.currentPage == 1}">
          <li class="disabled"><a href="#" aria-label="Previous">
            <span aria-hidden="true">&laquo;</span></a></li>
        </c:if>

        <%-- 如果现在的当前页不是第一页,那么可以点击 << 回到前一页--%>
        <c:if test="${pageBean.currentPage != 1}">
          <li>
            <a href="linkManServlet?method=findByPage&currentPage=${pageBean.currentPage-1}&pageSize=${pageBean.pageSize}"
               aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>
        </c:if>

        <c:forEach begin="1" end="${pageBean.totalPage}" var="i">

          <%--这里的页码也有特殊的地方,如果这个页码正好是当前页,那么给他来一点背景色--%>
          <c:if test="${pageBean.currentPage == i}">
            <li class="active"><a href="#">${i}</a></li>
          </c:if>

          <%--如果这个页码不是当前页,那么就是一种普通的<li>标签就行--%>
          <c:if test="${pageBean.currentPage != i}">
            <%--这里还要考虑点击页码,请求这一页的数据回来的情况。--%>
            <li>
              <a href="linkManServlet?method=findByPage&currentPage=${i}&pageSize=${pageBean.pageSize}">${i}</a>
            </li>
          </c:if>
        </c:forEach>

        <%--如果现在的当前页已经是最后一页了,那么禁止点击 >> --%>
        <c:if test="${pageBean.currentPage == pageBean.totalPage}">
          <li class="disabled"><a href="#" aria-label="Next"><span aria-hidden="true">&raquo;</span></a>
          </li>
        </c:if>

        <%--如果现在的当前页不是最后一页,那么可以点击 >> 去下一页。   --%>
        <c:if test="${pageBean.currentPage != pageBean.totalPage}">
          <li>
            <a href="linkManServlet?method=findByPage&currentPage=${pageBean.currentPage+1}&pageSize=${pageBean.pageSize}"
               aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>
        </c:if>

        <li><a href="#" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>
      </ul>
    </td>
  </tr>
</table>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值