JavaWeb系列七: 动态WEB开发核心(Servlet) 下

news2024/10/6 10:26:00

韩老师学生

  • ServletConfig
  • ServletContext
    • 网站计数器
  • HttpServletRequest
    • 细节1
    • 细节2
    • 细节3
  • Dispathcer
    • 请求转发应用实例
    • 请求转发细节和注意事项
    • 习题
  • HttpServletResponse
    • 请求重定向
    • 请求重定向注意事项
    • 动态获取到application context
    • 练习题

在这里插入图片描述

ServletConfig

ServletConfig基本介绍
1.ServletConfig 类是为Servlet程序配置信息的类
2.Servlet程序和ServletConfig对象都是由Tomcat负责创建的
3.Servlet程序默认是第1次访问的时候创建.ServletConfigServlet程序创建时, 就创建一个对应的ServletConfig对象

ServletConfig类能干什么
1.获取Servlet程序的servlet-name的值
2.获取初始化参数init-param
3.获取ServletContext对象

ServletConfig应用实例
需求: 编写DBServlet.java, 实现如下功能
1.在web.xml中编写连接mysql的用户名和密码
2.在DBServlet执行doGet() / doPost()方法时, 均可以获取到web.xml配置的用户名和密码
3.示意图(思路分析)
在这里插入图片描述

1.web.xml配置DBServlet

<servlet>
    <servlet-name>DBServlet</servlet-name>
    <servlet-class>com.zzw.servlet.DBServlet</servlet-class>
    <!--配置信息, 而不是硬编码到程序-->
    <init-param>
        <param-name>username</param-name>
        <param-value>zzw</param-value>
    </init-param>
    <init-param>
        <param-name>pwd</param-name>
        <param-value>123456</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>DBServlet</servlet-name>
    <url-pattern>/dbServlet</url-pattern>
</servlet-mapping>

2.在com.zzw.servlet下新建DBServlet

public class DBServlet extends HttpServlet {

    /**
     * 老师梳理ServletConfig config 使用流程
     * 1.当DBServlet对象初始化时, tomcat会同时创建一个 ServletConfig对象
     * 2.这时如果DBServlet init() 方法中你调用super.init(config)
     * 3.调用 父类 GenericServlet
     *     public void init(ServletConfig config) throws ServletException {
     *         this.config = config;
     *         this.init();
     *     }
     * 4.这时就会把 Tomcat创建的 ServletConfig对象赋给 GenericServlet的属性 config
     * 5.如果注销super.init(config), 那么在doGet,doPost和其它方法中将无法通过 getServletConfig() 方法获取ServletConfig
     * 6.因此如果你要重写init()方法, 还想在其它方法通过 getServletConfig() 方法获取ServletConfig
     *   , 则一定要记住 在init()方法中 调用 super.init(config)
     * @param config
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("init() config=" + config);
        super.init(config);

    }

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

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //在DBServlet执行doGet() / doPost()方法时, 均可以获取到web.xml配置的用户名和密码
        //OOP程序员->现有的方法或对象来实现
        //DBServlet的父类有GenericServlet有getServletConfig()
        /**
         * 解读
         * 1. getServletConfig() 方法是 GenericServlet
         * 2. 返回的 servletConfig对象是 GenericServlet private transient ServletConfig config;
         * 3. 当一个属性被transient修饰, 表示该属性不会被串行化(有些重要信息, 不希望保存到文件)
         */
        ServletConfig servletConfig = this.getServletConfig();
        System.out.println("doPost() servletConfig=" + servletConfig);
        String username = servletConfig.getInitParameter("username");
        String pwd = servletConfig.getInitParameter("pwd");
        System.out.println("初始化参数username=" + username);
        System.out.println("初始化参数pwd=" + pwd);
    }
}

ServletContext

为什么需要ServletContext
1.先看一个需求: 如果我们希望统计某个web应用所有的Servlet被访问的次数, 怎么办?
2.方案1-DB

在这里插入图片描述

2.方案2-ServletContext

在这里插入图片描述

ServletContext基本介绍

  1. ServletContext是一个接口, 他表示Servlet上下文对象
  2. 一个web工程, 只有一个ServletContext对象实例
  3. ServletContext对象在web工程启动的时候创建, 在web工程停止的时候销毁
  4. ServletContext对象可以通过this.getServletConfig().getServletContext()方法获得ServletContext对象的引用, 也可以通过this.getServletContext()来获得其对象的引用
  5. 由于一个WEB应用中的所有Servlet共享同一个ServletContext对象, 因此Servlet对象之间可以通过ServletContext对象来实现通信. ServletContext对象通常也称之为域对象.

ServletContext可以做什么
1.获取web.xml 中配置的上下文参数context-param[这个信息和整个web应用相关, 而不是属于某个Servlet]
2.获取当前的工程路径, 格式: /工程路径 ⇒ 比如 /servlet
3.获取工程部署后在服务器硬盘上的绝对路径 (比如: D:\idea_project\zzw_javaweb\servlet\out\artifacts\servlet_war_exploded)
4.像Map一样存取数据, 多个Servlet共享数据
在这里插入图片描述

应用实例1-获取工程相关信息
●需求如下
1.获取web.xml中配置的上下文参数 context-param
2.获取当前的工程路径, 格式: /工程路径
3.获取工程部署后在服务器硬盘上的绝对路径

●代码实现
1.修改web.xml, 增加相关配置

<!--配置整个网站的信息-->
<context-param>
    <param-name>website</param-name>
    <param-value>http://www.baidu.com</param-value>
</context-param>
<context-param>
    <param-name>company</param-name>
    <param-value>百度</param-value>
</context-param>

2.web.xml配置ServletContext_

<!--配置ServletContext_-->
<servlet>
    <servlet-name>ServletContext_</servlet-name>
    <servlet-class>com.zzw.servlet.servletcontext.ServletContext_</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ServletContext_</servlet-name>
    <url-pattern>/servletContext_</url-pattern>
</servlet-mapping>

3.com.zzw.servlet.servletcontext下新建ServletContext_

public class ServletContext_ extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取web.xml的context-parameter

        //1.获取ServletContext对象
        ServletContext servletContext =
                this.getServletConfig().getServletContext();
        //2.获取website
        String website = servletContext.getInitParameter("website");
        String company = servletContext.getInitParameter("company");
        //3.获取项目的工程路径
        String contextPath = servletContext.getContextPath();
        //4.获取项目发布后, 真正的工作路径
        //  / 表示我们的项目(发布后)的 根路径
        //  D:\idea_project\zzw_javaweb\servlet3\out\artifacts\servlet3_war_exploded
        String realPath = servletContext.getRealPath("/");
        System.out.println("项目发布后的绝对路径 realPath=" + realPath);
        System.out.println("contextPath=" + contextPath);
        System.out.println("website=" + website);
        System.out.println("company=" + company);
    }
}

网站计数器

需求分析/图解
1.需求: 完成一个简单的网站访问次数计数器
2.使用Chrome访问Servlet01, 每访问一次, 就增加1访问次数, 在后台输出, 并将结果返回给浏览器显示.
3.使用火狐访问Servlet02, 每访问一次, 就增加1访问次数, 在后台输出, 并将结果返回给浏览器显示.
在这里插入图片描述

●代码实现
1.在web.xml配置OrderServlet, PayServlet

<servlet>
    <servlet-name>OrderServlet</servlet-name>
    <servlet-class>com.zzw.servlet.servletcontext.OrderServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>OrderServlet</servlet-name>
    <url-pattern>/orderServlet</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>PayServlet</servlet-name>
    <servlet-class>com.zzw.servlet.servletcontext.PayServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>PayServlet</servlet-name>
    <url-pattern>/payServlet</url-pattern>
</servlet-mapping>

2.com.zzw.servlet.servletcontext创建OrderServlet

public class OrderServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取到ServletContext对象
        ServletContext servletContext =
                this.getServletConfig().getServletContext();

        //System.out.println("OrderServlet servletContext=" + servletContext + " 运行类型=" + servletContext.getClass());

        从servletContext获取 visit_count 属性
        //Object visit_count = servletContext.getAttribute("visit_count");
        判断visit_count是否为null
        //if (visit_count == null) {//说明是第1次访问
        //    servletContext.setAttribute("visit_count", 1);
        //    visit_count = 1;
        //} else {//是第二次或以后
        //    //取出visit_count属性的值+1
        //    visit_count = Integer.parseInt(visit_count + "") + 1;
        //    //放回到servletContext
        //    servletContext.setAttribute("visit_count", visit_count);
        //}

        Integer visit_count = WebUtils.visitCount(servletContext);
        //输出显示
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("<h1>新网站被访问的次数是</h1>" + visit_count + "次</h1>");
    }
}

3.com.zzw.servlet.servletcontext创建PayServlet

public class PayServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取到ServletContext对象
        ServletContext servletContext =
                this.getServletConfig().getServletContext();

        //System.out.println("PayServlet servletContext=" + servletContext + " 运行类型=" + servletContext.getClass());

        从servletContext获取 visit_count 属性
        //Object visit_count = servletContext.getAttribute("visit_count");
        判断visit_count是否为null
        //if (visit_count == null) {//说明是第1次访问
        //    servletContext.setAttribute("visit_count", 1);
        //    visit_count = 1;
        //} else {//是第二次或以后
        //    //取出visit_count属性的值+1
        //    visit_count = Integer.parseInt(visit_count + "") + 1;
        //    //放回到servletContext
        //    servletContext.setAttribute("visit_count", visit_count);
        //}

        Integer visit_count = WebUtils.visitCount(servletContext);
        //输出显示
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("<h1>新网站被访问的次数是</h1>" + visit_count + "次</h1>");
    }
}

4.在com.zzw.servlet.servletcontext新建WebUtils

public class WebUtils {

    //这个方法就是对访问的次数累积, 同时返回次数
    public static Integer visitCount(ServletContext servletContext) {
        //从servletContext获取 visit_count 属性
        Object visit_count = servletContext.getAttribute("visit_count");
        //判断visit_count是否为null
        if (visit_count == null) {//说明是第1次访问
            servletContext.setAttribute("visit_count", 1);
            visit_count = 1;
        } else {//是第二次或以后
            //取出visit_count属性的值+1
            visit_count = Integer.parseInt(visit_count + "") + 1;
            //放回到servletContext
            servletContext.setAttribute("visit_count", visit_count);
        }
        return Integer.parseInt(visit_count + "");
    }
}

5.测试
在这里插入图片描述

HttpServletRequest

  1. HttpServletRequest对象代表客户端的请求
  2. 当客户端/浏览器通过HTTP协议访问服务器时, HTTP请求头中所有的信息都封装在这个对象中
  3. 通过这个对象的方法, 可以获取客户端信息
  • 常用方法
  1. getRequestURI() 获取请求的资源路径 http://localhost:8080/servlet/login.html
  2. getRequestURL() 获取请求的统一资源定位符(绝对路径) http://localhost:8080/servlet/login.html
  3. getHeader() 获取请求头
  4. getParameter() 获取请求的参数
  5. getParameterValues() 获取请求的参数(多个值时使用) 比如checkbox, 或返回的数组
  6. getRemoteHost() 获取客户端的主机
  7. getRemoteAddr() 获取客户端的ip
  8. getMethod() 获取请求的方式(GET或POST)
  9. setAttribute(key, value) 设置域数据
  10. getRequestDispatcher() 获取请求转发对象(核心对象)
public class HttpServletRequestMethods extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /********************************
         *      获取http请求头相关信息      *
         ********************************/
        System.out.println("请求头信息");
        System.out.println("资源路径URI(请求中的)=" + request.getRequestURI());
        System.out.println("统一资源定位符(绝对路径)URL=" + request.getRequestURL());
        System.out.println("客户端ip地址=" + request.getRemoteAddr());
        //获取http请求头的信息: 可以使用request.getHeader("请求头字段")
        // 可以指定 Accept, Accept-Encoding, Accept-Language, Connection, Cookie, Host, Referer
        String accept = request.getHeader("Accept");
        System.out.println("http请求头中的Accept信息=" + accept);
        /********************************
         *        获取表单提交的数据        *
         ********************************/
        //1.获取单个表单数据
        // 解决接收参数的中文乱码问题, 不能写在request.getParameter()后面
        request.setCharacterEncoding("utf-8");//浏览器按照urlEncode编码方式提交数据, 后端要用utf-8来接收
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println("username=" + username);
        System.out.println("password=" + password);//前端不填传给后端则是一个空字符串"", 不是null
        //2.获取一组表单数据 复选框, 下拉框
        String[] favorites = request.getParameterValues("favorite");
        if (favorites != null) {//复选框前端不选则后端返回一个null
            for (String favorite : favorites) {
                System.out.println(favorite);
            }
        }
    }
}

细节1

  1. text, date, password, email类型的输入框和下拉框如果不填值会将空字符串传给后端:username=&password=&date=, 后端用request.getParameter()接收这些值便是空字符串
  2. 单选框, 复选框如果不选(不包括下拉框), 则不向后台传值, 即username=&password=&date=这里根本就没有单选框和复选框的参数, 后台通过request.getParameter()或request.getParameterValues()获取实际上是获取了一个不存在的参数. 如果单选框, request.getParameter()返回一个字符串, 这个字符串为null, 如果是复选框, request.getParameterValues()返回字符串数组, 那么这个字符串数组为null, 如果对这个字符串数组遍历会报错, 因为null.length会报错

细节2

  1. 浏览器按照urlEncode编码方式提交数据, 后端要用utf-8来接收: request.setCharacterEncoding(“utf-8”); 且这句话要写在request.getParameter()前面
  2. 后台将接收的数据返回给页面时, 要设置响应头的Content-Type参数为text/html; charset=utf-8, 因为数据中包含中文, 并且是文本类型
    //本质实在http响应头加上Content-Type: text/html;charset=utf-8
    response.setContentType("text/html; charset=utf-8");
    PrintWriter writer = response.getWriter();
    writer.print("<h1>提交的用户名=" + username + "</h1>");
    writer.flush();
    writer.close();

细节3

再次理解Http协议Content-Type的含义, text/html 表示返回的数据类型, 浏览器会根据这个类型来解析数据

    //本质实在http响应头加上Content-Type: text/html;charset=utf-8
    // text/plain 表示返回的数据,请浏览器使用文本方式解析
    // application/x-tar 表示返回的是一个文件,浏览器就会以下载文件的方式处理
    response.setContentType("application/x-tar; charset=utf-8");
    PrintWriter writer = response.getWriter();
    writer.print("<h1>提交的用户名=" + username + "</h1>");
    writer.flush();
    writer.close();

Dispathcer

在这里插入图片描述

  1. 实现请求转发: 请求转发指一个web资源收到客户端请求后, 通知服务器(比如Tomcat)去调用另外一个web资源进行处理
  2. HttpServletRequest对象(也叫Request对象)提供了一个getRequestDispather方法, 该方法返回一个RequestDispacher对象, 调用这个对象的forward方法可以实现请求转发
  3. request对象同时也是一个域对象, 开发人员通过request对象在实现转发时, 把数据通过request对象带给其它web资源
    setAttribute方法
    getAttribute方法
    removeAttribute方法
    getAttributeNames方法
    在这里插入图片描述

请求转发应用实例

前提: 新建两个Servlet, 并做好配置

public class CheckServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("CheckServlet doPost 输出");
        //根据用户名来确定该用户是什么身份
        request.setCharacterEncoding("utf-8");
        String username = request.getParameter("username");
        //注意: 如果是同一个request对象(请求转发), 那么可以在不同的Servlet中使用getParameter取出同一个参数
        if ("猫".equals(username)) {
            //分配管理员权限
            request.setAttribute("role", "管理员");
        } else {
            request.setAttribute("role", "普通用户");
        }
        //获取分发器
        //解读一下:1./managerServlet写的是 要转发的servlet的url
        //       2./ 会被解析成 /servlet
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/managerServlet");
        //       3.forward(request, response) 会把当前Servlet的request,response对象传给下一个Servlet使用
        requestDispatcher.forward(request, response);
    }
}
public class ManagerServlet extends HttpServlet {
    private int count;
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        String username = request.getParameter("username");
        String role = (String) request.getAttribute("role");

        //输出
        response.setContentType("text/html; charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("<h1>用户名 " + username + "</h1>");
        writer.print("<h1>角色=" + role + "</h1>");
        writer.flush();
        writer.close();
    }
}

请求转发细节和注意事项

  1. 浏览器地址栏不会发生变化(地址会停留在第1个servlet的url)
  2. 在同一次HTTP请求中, 进行多次转发, 仍然是一次HTTP请求
  3. 在同一次HTTP请求中, 进行多次转发, 多个Servlet可以共享request域/对象的数据(因为始终是同一个request对象)
  4. 可以转发到WEB-INF目录下
  5. 不能访问当前WEB工程外的资源
  6. 转发和重定向的后续代码会被执行, 根据情况可添加return 👉参考
    在这里插入图片描述

习题

编写一个Servlet获取请求参数中的操作系统和位数

public class GetInfoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //谷歌浏览器:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
        String userAgent = request.getHeader("User-Agent");
        String regStr = "\\(([\\w\\ \\.;]+)\\)";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(userAgent);
        matcher.find();
        //group(0) = (Windows NT 10.0; Win64; x64)
        //group(1) = Windows NT 10.0; Win64; x64
        String[] split = matcher.group(1).split(";");
        System.out.println("操作系统=" + split[0]);
        System.out.println("操作系统位数=" + split[1].trim());
    }
}

HttpServletResponse

  • 基本介绍
  1. 每次HTTP请求, Tomcat会创建一个HttpServletResponse对象传递给Servlet使用
  • 乱码问题
  1. 处理乱码问题方案1
    在这里插入图片描述
  2. 处理乱码问题方案2
    在这里插入图片描述

请求重定向

  1. 请求重定向是指: 一个web资源收到客户端请求后, 通知客户端去访问另外一个web资源, 这称之为重定向
  2. 请求重定向分析图
    在这里插入图片描述
    测试代码
public class DownServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("DownServlet 自己的业务");
        //1.sendRedirect 本质会返回一个 302状态码 和 Location: /servlet/downServletNew
        //2.因此 302状态码 和 /servlet/downServletNew是浏览器解析的
        //3.浏览器会将 /servlet/downServletNew 解析成http://localhost:8080/servlet/downServletNew
        response.sendRedirect("/servlet/downServletNew");
    }
}

public class DownServletNew extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("DownServletNew doPost");
        response.setContentType("application/x-tar; charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("<h1>下载完成</h1>");
        writer.flush();
        writer.close();
    }
}
<body>
<h2>下载文件</h2>
<a href="http://localhost:8888/servlet/downServlet">下载&lt;&lt;三体&gt;&gt;小说</a>
</body>

测试结果
在这里插入图片描述
在这里插入图片描述

请求重定向注意事项

  1. 最佳应用场景: 网站迁移, 比如原域名是 www.zzw.com 迁移到 www.world.cn, 但是百度抓取的还是原来的网址
  2. 浏览器地址会发生变化, 本质是两次Http请求
  3. 不能共享Request域中的数据, 本质是两次Http请求, 会生成两个HttpServletRequest对象
  4. 不能重定向到WEB-INF下的资源
  5. 可以重定向到Web工程以外的资源, 比如到http://www.baidu.com
  6. 重定向有两种方式, 推荐使用第1种
//第一种重定向使用
response.sendRedirect("/servlet/downServletNew");
//第二种重定向使用
response.setStatus(302);//设置http响应的状态码
//设置http响应的Location: /servlet/downServletNew
response.setHeader("Location", "/servlet/downServletNew");

动态获取到application context

在这里插入图片描述

//动态获取 application context
String contextPath = getServletContext().getContextPath();
System.out.println(contextPath);// /servlet
response.sendRedirect(contextPath + "/downServletNew");

在这里插入图片描述

练习题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>支付页面</title>
</head>
<body>
<h1>支付页面</h1>
<!--这里action的第1个/ 会被浏览器解析成浏览器地址栏的主机名-->
<form action="/servlet/myPayServlet">
    用户编号:<input type="text" name="userId"/>
    支付金额:<input type="text" name="money"/>
    <input type="submit" value="点击支付">
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>支付成功</title>
</head>
<body>
<h1>恭喜你支付成功</h1>
</body>
</html>
public class MyPayServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        String userId = request.getParameter("userId");
        String money = request.getParameter("money");
        String contextPath = getServletContext().getContextPath();
        if (WebUtils.parseString(money) > 100) {
            response.sendRedirect(contextPath + "/pay_ok.html");
        } else {
            response.sendRedirect(contextPath + "/pay.html");
        }
    }
}
public class WebUtils {
    public static int parseString(String str) {
        int num = 0;
        try {
            //shortcuts: ctrl+alt+t
            num = Integer.parseInt(str);
        } catch (NumberFormatException e) {
            System.out.println("输入的str格式不正确");
        }
        return num;
    }
}
<servlet>
        <servlet-name>MyPayServlet</servlet-name>
        <servlet-class>com.zzw.servlet.response.MyPayServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyPayServlet</servlet-name>
        <url-pattern>/myPayServlet</url-pattern>
    </servlet-mapping>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1859536.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker--基础详解

目录 Docker介绍 Docker与传统虚拟机相比的优势 Docker基础插件 Docker镜像 容器和仓库 Docker介绍 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言开发&#xff0c;遵从Apache2.0开源协议&#xff0c;依赖Linux内核的Cgroup和Namespace等技术&#xff0c;对进…

智启万象|2024 Google 谷歌开发者大会报名开启!

邀你 8 月 7 日 - 8 日齐聚北京 共同探索 Google 最新的开发者工具与技术 助力高效创新&#xff0c;释放无限潜能 想要抢先一步找到官方剧透&#xff1f; 点击下方卡片 解锁大会更多精彩内容 ↓ 看到这里&#xff0c;是不是开始期待来到现场了呢&#xff1f; 更多亮点不容错过 …

快速清理Word中的嵌套表格

实例需求&#xff1a;Word文档中表格有的单元格中包含嵌套表格&#xff08;注意其中表格中有合并单元格&#xff09;&#xff0c;如下图所示。 现在需要删除单元格顶部的嵌套表格&#xff08;如上图中的表格1和表格3&#xff09;&#xff0c;如下图所示&#xff0c;如果表格较多…

Docker部署私有仓库(registryHarbor)

简介Docker Hub 官方仓库 在 Docker 中&#xff0c;当我们执行 docker pull xxx 的时候 &#xff0c;它实际上是从 registry.hub.docker.com 这个地址去查找&#xff0c;这就是Docker公司为我们提供的公共仓库。在工作中&#xff0c;我们不可能把企业项目push到公有仓库进行管理…

【机器学习项目实战(二)】基于朴素贝叶斯的中文垃圾短信分类

完整代码、数据集和相应的报告 链接已经放在了正文最下方, 供大家参考学习 摘要 ​ 本文探讨了中文垃圾短信分类的问题,通过收集实际数据集,运用多种机器学习算法进行分类,并对比了不同算法在垃圾短信分类任务上的性能。本研究旨在提高中文垃圾短信的识别准确率,为构建更…

【KMP 滚动哈希】1392. 最长快乐前缀

本文涉及知识点 KMP 滚动哈希 LeetCode1392. 最长快乐前缀 「快乐前缀」 是在原字符串中既是 非空 前缀也是后缀&#xff08;不包括原字符串自身&#xff09;的字符串。 给你一个字符串 s&#xff0c;请你返回它的 最长快乐前缀。如果不存在满足题意的前缀&#xff0c;则返回…

改装的电荷泵从数字信号中提取能量

本设计理念中描述的倍压器是 Dickson 电荷泵的改进版。与该电路不同&#xff0c;它不需要直流输入电压&#xff0c;而只需要一个数字时钟&#xff0c;其峰值理想情况下在输出端加倍为直流电压。 图 1 倍压器产生自己的局部 V 该电路用作电荷泵&#xff0c;其中 C1 充电至输入时…

Android笔记-adb keycode大全

使用方法 用adb发送按键事件时&#xff0c;可以使用下面表中的枚举值或者直接使用数值&#xff0c;比如 adb shell input keyevent KEYCODE_HOME 或者 adb shell input keyevent 3 下面按三种排序方法列出所有按键的 keycode&#xff0c; 分别是&#xff1a; 按功能分 按枚…

【实用软件】Paragon NTFS for Mac 15下载及安装教程

​习惯上来说所有操作只需轻轻一点&#xff1a;轻量级的快捷菜单栏&#xff0c;可访问所有NTFS驱动器并执行最常见的卷操作&#xff0c;如挂载&#xff0c;卸载和验证&#xff0c;从菜单栏中快速启动NTFS for Mac界面&#xff0c;一键点击&#xff0c;更加方便。11510182322410…

昇思25天学习打卡营第01天|基本介绍快速入门

一、什么是昇思MindSpore&#xff1f; 昇思MindSpore是一个全场景深度学习框架&#xff0c;详见基本介绍 那什么是深度学习呢&#xff1f; 深度学习是一种特殊的机器学习&#xff0c;主要是利用了多层神经网络模拟人脑&#xff0c;自动提取特征并进行预测。 什么是机器学习…

【Python机器学习】凝聚聚类——层次聚类与树状图

凝聚聚类生成了所谓的层次聚类。聚类过程迭代进行&#xff0c;每个点都从一个单点簇变为属于最终的某个簇。每个中间步骤都提供了数据的一种聚类&#xff08;簇的个数也不相同&#xff09;。有时候&#xff0c;同时查看所有可能的聚类也是有帮助的。 举例&#xff1a; import …

【pytorch07】broadcast广播

Broadcasting expand&#xff08;与上一节说的expand功能相同&#xff0c;可以扩展维度&#xff0c;但是这里是自动的&#xff0c;扩展的时候不需要拷贝数据&#xff09;without coping data broadcast实施 从最小的维度开始匹配&#xff0c;如果前面没有维度的话&#xff0…

BFS:解决拓扑排序问题

文章目录 什么是拓扑排序&#xff1f;关于拓扑排序的题1.课程表2.课程表Ⅱ3.火星词典 总结 什么是拓扑排序&#xff1f; 要知道什么拓扑排序我们首先要知道什么是有向无环图&#xff0c;有向无环图我们看名字其实就很容易理解&#xff0c;有向就是有方向&#xff0c;无环就是没…

类的默认成员函数——构造与析构函数

如果一个类中什么成员都没有&#xff0c;简称为空类。但是空类中真的什么都没有吗&#xff1f; 当然不是&#xff0c;任何类在什么都不写的情况下&#xff0c;编译器会自动生成6个默认成员函数 1.构造函数 1.1概念引入 对于以下这个Date类&#xff0c;可以通过Init公有方法给…

北邮《计算机网络》传输层笔记

内容一览 缩写复习单词复习传输层前言传输协议的要点拥塞控制UDPTCP VS UDPTCP 缩写复习 AIMD XCP ECN WFQ max-min-fair ARQ PAWS TSAP NSAP TCP UDP RTT SCTP SACK NAK RST MSS 单词复习 inverse multiplexing(SCTP) convergence crashed machine protocol scenarios asym…

IIC学习笔记

目录 #I2C涉及相关知识 #I2C相关介绍 欢迎指正&#xff0c;希望对你&#xff0c;有所帮助&#xff01;&#xff01;&#xff01; 个人学习笔记&#xff0c;参考文献&#xff0c;链接最后&#xff01;&#xff01;&#xff01; #I2C涉及相关知识 SDA串行数据线&#xff1a; Ser…

GB28181视频汇聚平台EasyCVR接入Ehome设备视频播放出现异常是什么原因?

多协议接入视频汇聚平台EasyCVR视频监控系统采用了开放式的架构&#xff0c;系统可兼容多协议接入&#xff0c;包括市场标准协议&#xff1a;国标GB/T 28181协议、GA/T 1400协议、JT808、RTMP、RTSP/Onvif协议&#xff1b;以及主流厂家私有协议及SDK&#xff0c;如&#xff1a;…

RK3568平台(音频篇)耳机插拔检测

一.硬件原理图 耳机输出硬件原理图&#xff1a; 耳机实物图&#xff1a; 耳机插入硬件原理&#xff1a; 耳机插入后HP_DET_L会连接耳机的GND&#xff0c;从而实现HP_DET_L叫从高到低的状态。 耳机插入软件原理&#xff1a; 软件需要在驱动里面定时的读取gpio的状态&#xf…

2024期权交易佣金手续费最低是多少?期权交易有哪些成本?

显性成本 期权交易的显性成本包含期权交易的佣金和交易所费用&#xff0c;分别支付给券商和交易所&#xff0c;统一由券商代收。 佣金 期权佣金是期权交易时支付给券商的费用&#xff0c;佣金通常以交易金额的一定比例计算&#xff0c;可以是固定费用&#xff0c;也可以是滑…

尽管与 ChatGPT 达成了合作,但据报道苹果仍在与 Meta 进行人工智能谈判

苹果最近宣布计划将人工智能纳入 iOS 18 以及新的 iPhone 16 和 iPhone 16 Pro 机型中&#xff0c;并开始与潜在的生成式人工智能合作伙伴 Meta 进行讨论。 据《华尔街日报》报道&#xff0c;苹果已与 Meta 就将其跨平台使用的生成式人工智能模型整合到 Apple Intelligence 中…