zoukankan      html  css  js  c++  java
  • 关于BaseServlet

    BaseServlet 是项目中所有servlet的父类,作用是为了让一个servlet可以同时处理多个请求,因为我们之前比如说完成对于商品的增删改查的时候,每一个需求就要创建一个servlet,这样会显得很臃肿,所以就用到BaseServlet;采用的是反射的技术


    步骤 :1. 写一个BaseServlet继承HttpServlet;

       2.重写service方法

    package com.qf.web.servlet;
     
     
    import java.io.IOException;
    import java.lang.reflect.Method;
     
     
    import javax.management.RuntimeErrorException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
     
     
    public class BaseServlet extends HttpServlet {
     
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try {
    // 1.获取表单中的路径后面带的参数method=方法名中的方法名
    String m = request.getParameter("method");
     
    // 如果获取的路径后面没有带method这个参数的话,就默认跳转到首页,具体原因请看后面的解释
    if (m == null || m.trim().isEmpty()) {
     
    m = "index";// 把名称定为index,然后在这个类中写一个index方法;所有继承这个类的servlet都可以重写这个方法;
     
    }
     
    /*
    * this为当前调用这个方法的类,即这个BaseServlet的子类,而不是指这个BaserServlet;谁调用谁就是这个this
    *
    * this.getClass()获得当前这个类的对象 getMethod(方法名,后面的HttpServletRequest.class,
    * 
    * HttpServletResponse.class是固定参数,固定写法);
    */
     
     
    // 获得方法对象
    Method method = this.getClass().getMethod(m, HttpServletRequest.class, HttpServletResponse.class);
     
    // 调用这个请求后处理的方法返回的字符串,指的是要转发还是重定向的路径(在子类servlet返回的)
    String text = (String) method.invoke(this, request, response);
     
    //如果返回字符串为null,说明没有要求我做转发还是重定向,所以我什么都不用做
    if(text==null||text.trim().isEmpty()) {
    return;
    }
     
    //字符串.contains("子字符串")  字符串是否包含该子字符串 
    if(!text.contains(":")) {
     
    //比如返回的是"/index.jsp"
     
    //如果不包含,说明没规定要转发还是重定向,所以默认转发;记得一定要写forward
    request.getRequestDispatcher(text).forward(request, response);
     
    }else {
     
    //比如text返回的是 "f:/index.jsp"  或 "r:"+request.getContextPath()+"/index.jsp"
     
    int index=text.indexOf(":");//如果有包含的话获取:在这个字符串中第一次出现的索引
     
    //从0下标开始截取到:的前一个下标为止,(包前不包后) 获取标志f/r
    String bz = text.substring(0, index);//从字符串的0下标开始截取到指定的索引(包前不包后)
     
    //从冒号的下标1+1为2的下标获取路径  /index.jsp 
    String path = text.substring(index+1);//从指定索引开始截取字符串,直到末尾
     
    //如果标志是f的话,就是要转发
    if (bz.equalsIgnoreCase("f")) {//忽略大小写,比如F/f
     
    request.getRequestDispatcher(path).forward(request, response);//一直忘了写forward
     
    //如果标志是r的话,就是要重定向
    }else if (bz.equalsIgnoreCase("r")) {
     
    response.sendRedirect(path);
     
    }else {//这个else可以不写的
     
    throw new RuntimeException("您的指令有误");
    }
     
    }
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
     
     
    }
     
    //在BaseServlet中写index方法,那么继承他的所有servlet都可以重写该方法;
    //这里主要是为了上面的第一个if语句默认跳转到首页准备的
     
    public String index(HttpServletRequest request,HttpServletResponse response) {
     
    return null;
    }
     
     
    }

    3.以前我们在jsp页面的时候只要直接写跳转的路径即可,比如

    <form action="${pageContext.request.contextPath() } / loginServlet "></form>

    然后在写个loginServlet完成用户登录操作就可以了,但是注册的时候我们还得写个注册的servlet,
    注销又是一个servlet,这样就会很麻烦,很臃肿. 所以我们以后只要把路径改为:

    <form action="${pageContext.request.contextPath() } / userServlet ? method=login">

     记得跟上method=方法名

    4.然后我们只要写一个userServlet,里面收入关于用户登录/注册/注销等有关的方法即可;以注册为例.(注意点: 方法中的参数固定为HttpServletRequest,HttpServletResponse)


    在index.jsp页面中有个注册的按钮(其他代码省略)

    <form action="${pageContext.request.contextPath() } / user?method=registUI " method="post">
    <input  type="submit" value="注册">
    </form>
    

     其实我们平时都是直接跳转到注册的jsp的.但是现在不那么做了,说是因为这样会不安全.所以我们也是跳转到路径为/user的UserServlet中的registUI方法中.在这里面完成跳转到jsp页面;


    以下为路径/user的UserServlet的代码;

    public class UserServlet extends BaseServlet {
    public String registUI(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    return "/jsp/register.jsp";//这个没有写 f:还是 r:前缀的话,在上面的BaseServlet中是默认按转发处理的;
    }

    这里面还有一个关于用户注册的方法

    public String  register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      
    request.setCharacterEncoding("utf-8");
    response.setContentType("text/html;charset=utf-8");
     
    //封装数据
    User user=new User();
       try {
                //因为我数据库里有个用户id,而这个id不是用户在注册的时候自己填的,而是后台自动生成的,所以我们需要这这里设置一下随机生成 id; 
     
     
                  user.setUid(UUID.randomUUID().toString().replace("-", "").toUpperCase());
     
     
    //code是激活码,用户注册后要通过邮箱激活码激活;这个也是随机生成的
     
     
         user.setCode(UUID.randomUUID().toString().replace("-", "").toUpperCase());
     
     
    //对用户密码进行加密处理,用到的是md5算法加密,具体代码见下面
     
     
                 user.setPassword(MD5Utils.md5(user.getPassword()));
     
     
      //因为注册页面有个生日选项,在user这个javabean中,数据类型为Date(一般建议为string类型,就不需要转换了)
                ConvertUtils.register(new DateLocaleConverter(), Date.class);//这个是BeanUtils提供的方法,这一行的代码是固定的,无须改动
     
    BeanUtils.populate(user, request.getParameterMap());
     
     
    //调用业务逻辑
    UserService us=new UserServiceImpl();
    us.add(user);
     
     
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
     
       return "r:"+request.getContextPath()+"/success.jsp";//返回要BaseServlet做重定向处理
     
     
     
     
    }

    中间省略user实体类, UserService及其实现类, UserDao的代码,直接上连库代码,即UserDaoImpl中的操作

    public class UserDaoImpl implements UserDao {
     
     
    @Override
    public void add(User user) throws Exception {
     //c3p0Utils是自己写的数据池操作
              QueryRunner qr=new QueryRunner(C3P0Utils.getDatasource());
              
              //向数据库里插入数据(预编译写法)
     String sql="insert into users values(?,?,?,?,?,?,?,?,?,?)";
     
     //写入实际参数
     qr.update(sql, user.getUid(),user.getUsername(),user.getPassword(),user.getName(),user.getEmail(),user.getTelephone(),user.getBirthday(),user.getSex(),user.getState(),user.getCode());
     
     
    }
     
     
    }

    最下面是对于md5算法的代码

    public class MD5Utils {
     
    public static String md5(String plainText) {
    byte[] secretBytes = null;
    try {
    secretBytes = MessageDigest.getInstance("md5").digest(plainText.getBytes());
    } catch (NoSuchAlgorithmException e) {
    throw new RuntimeException("找不到md5算法");
    }
    String md5code = new BigInteger(1, secretBytes).toString(16);
    for (int i = 0; i < 32 - md5code.length(); i++) {
    md5code = "0" + md5code;
    }
    return md5code;
    }
     
     
    }



    参考资料:

    https://blog.csdn.net/cyuc0425/article/details/79171711

    https://blog.csdn.net/wn084/article/details/79009322

  • 相关阅读:
    布隆过滤器原理与应用场景
    【转】程序员的世界真的很难懂~
    IDEA 2019.2.4 破解安装教程
    【转】只有程序员才能看得懂的段子
    Linux 正则表达式
    【转】雷军做程序员时写的博客,很强大!
    如何同步 Linux 集群系统时间
    百度共享云盘
    Shell 脚本 test 命令详解
    Linux 命令大全
  • 原文地址:https://www.cnblogs.com/moonsoft/p/9936272.html
Copyright © 2011-2022 走看看