Javaweb笔记

JavaWeb

JavaWeb前端:HTML CSS JS 开发静态页面

JavaWeb基础:servlet JSP AJAX 开发动态页面

一. 什么是web

1. Web服务

Web:World Wide Web 万维网

​ Web服务是最广泛的,最重要的信息服务类型。信息服务 邮箱服务等。

​ Web服务传输的数据是以超文本标记语言(HTML)进行组织。使用HTTP(超文本传输协议)协议进行传输。

2. URL 和 URI

URL:Uniform Resource Locator 统一资源定位器

组成:协议名 服务器名(域名) 端口号 路径 文件名

URI: Uniform Resource Identifier 统一资源标识符

组成:协议名 服务器名(域名) 端口号 路径

URI包含很多个URL

3. Web程序特点:

Web程序存放在服务器上。

​ Web程序在服务器上运行。

​ 通过给服务器端发送请求,服务器端运行程序。

​ 运行结果是HTTP格式的数据。

​ 使用JSP PHP ASP等语言开发。

4. b/s架构和c/s架构

b/s:browser/server 浏览器/服务器 如:淘宝 搜狐

c/s:client/server 客户端/服务器 如:QQ 微信

b/s优点:

开发成本低

管理维护简单

产品升级便利

对用户培训费用低

b/s缺点:

安全性不足

客户端不能随心变化,受浏览器的限制。

二. Tomcat服务器

  1. 什么是web服务器

    安装了web服务器程序,用来实现页面传递,执行web程序的主机。

    Web服务器程序:Tomcat IIS Apache

  2. 服务器的命名

    URL:协议名 服务器名:端口号 路径 文件

    局域网:主机名 如:js64

    互联网:域名 如:www.sohu.com www.taobao.com

    服务器名对应某些IP地址

    主机名—主机IP地址 如:js64—192.169.7.164 localhost—127.0.0.1

    查看本地主机的IP地址:ipconfig /all

    查看两个主机网络连接是否畅通:ping 对方主机的IP

  3. Tomcat服务器目录结构

    bin:批处理文件。Startup.bat:启动 shutdown.bat:关闭

    conf:配置文件.xml server.xml web.xml

    xml:由标签组成。要求标签正确嵌套。标签名区分大小写。用于保存数据

    新格式文件:JSON yml

    Lib:代码库 Tomcat服务器程序运行需要的程序

    webapps:存放web程序

    Work:由jsp文件生成的servlet文件

  4. 主目录

    主目录:映射到站点域名的目录

    主目录是站点访问者的起始点

    Tomcat服务器程序中 webapps就是主目录

  5. 虚拟目录

    要从主目录以外的目录发布信息,可以创建虚拟目录。
    修改server.xml文件中的标签中添加:

    <Context path="/virtual" docBase="C:\\myweb">	</Context>
    

    Path的值是url中的路径。
    docBase的值是保持web程序的物理路径。

  6. 更改Tomcat服务器端口号

    修改server.xml文件:

    <Connector port="8088" protocol="HTTP/1.1"		
    connectionTimeout="20000"
    redirectPort="8443" />
    

192.169.7.164
http:// 192.169.7.164:8088/a/hello.html

三. HTTP协议

HTTP协议是应用层的协议

HTTP协议是请求相应式协议

HTTP协议发送请求有两种方式:get、 post

Get请求方式的特点:

  • 发送数据量小,一般2KB以内。
  • 不安全、效率高。

Servlet

  1. 什么是servlet技术

    Servlet是使用Java语言开发的。

    使用系统提供的Servlet接口或实现了Servlet接口的类

  2. servlet的主要功能

    • 创建并返回一个包含基于客户端请求动态内容完整HTML页面
    • 与其他服务器资源(如:数据库 基于java的应用程序等)进行通信
  3. servlet技术的特点

    • 不能在html文件中嵌入servlet程序。
    • 不能操作html文件中的标签。
    • 可以直接在网页中调用。
  4. servlet程序的调用方式

    1. 在浏览器的地址栏中输入url
    2. 使用超链接。<a href="url">
    3. 使用form表单。<form action="url">
    4. 在servlet程序中通过调用函数。转发和重定向
  5. 实现servlet

    1. 实现Servlet接口

      在服务器上部署文件:WEB-INF\web.xml

      ​ classes\HelloServletTest.java

      ​ 开发、编译程序Public类型的类

      ​ 导入javax.servlet中的类和接口

      ​ 增加CLASSPATH= C:\work\apache-tomcat-8.5.33\lib\servlet-api.jar

      javac -d . HelloServletTest.java

      ​ 配置web.xml文件

      <servlet>       
      <servlet-name>helloservlet</servlet-name>       	<servlet-class>com.tedu.servlet.HelloServletTest</servlet-class>  </servlet>     
      <servlet-mapping>       
        <servlet-name>helloservlet</servlet-name>      
        <!-- /代表根目录   http://localhost:8080/helloServlet/hello -->       
        <url-pattern>/hello</url-pattern>  
      </servlet-mapping>  
      
    2. 继承 GenericServlet

    3. 继承 HttpServlet

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Oo0u1prr-1642840307010)(E:\Code\Note\JavaWeb\01.png)]

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YF9e2Bii-1642840307011)(E:\Code\Note\JavaWeb\02.png)]

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4iMrygb8-1642840307012)(E:\Code\Note\JavaWeb\03.png)]

  6. idea开发Servlet

使用注解方式设置servlet和url的映射:
@WebServlet(name = "ServletTwo", urlPatterns = {"/a", "/b"})

发送请求:
    地址栏   超链接-href   表单-action   函数

    url=/   该斜线代表主目录。
获取参数:
        request.getParameter("参数名");
响应数据:
        PrintWriter out = response.getWriter();
    	out.write("hello servlet");

  1. Servlet生命周期

    1. 启动服务器。有些服务器程序在启动时会将servlet字节码文件加载到内存。
    2. 客户端发送请求,服务器端接收请求,创建一个请求对象和响应对象。将客户端发送的数据封装在请求对象中。根据请求创建对应的servlet对象,调用init方法。
    3. 激活servlet的service方法,将请求对象和响应对象传递给service方法的形参。通过请求对象获取客户端发送的数据,通过响应对象给客户端响应数据。如果客户端再次给该servlet发送请求,则使用已有的servlet对象。
    4. 当服务器关闭,则调用servlet中的destroy方法销毁servlet,垃圾回收机制将servlet对象回收。
  2. Servlet常用类

HttpServletRequest
接收客户端发送的数据
getParameter:获取一个值的参数。
getParameterValues:获取多个值的参数。

进行页面跳转

getRequestDispatcher("url").forward(request, response);
//注意:url的第一个/代表根目录。			该页面跳转称为:转发。

域对象(类似于集合—对象—存储数据)
通过域对象实现页面间数据的传输。
生命期为一次请求。

setAttribute("属性名", 对象);
getAttribute("属性名");

设置客户端发送数据的编码

setCharacterEncoding("utf-8");

HttpServletResponse
主目录:webapps
根目录:webapps/lesson

  1. 进行页面跳转----重定向

    转发与重定向的区别:

  • 转发是在服务器内部进行页面的跳转;重定向时客户端再次给服务器发送了一次请求。
  • 转发url不改变;重定向url改变。
  • 转发可以读取request对象中保存的数据;重定向不可以读取request对象中保存的数据。
  • 转发代码中的url第一个斜线表示根目录;重定向代码中的url第一个斜线表示主目录。
  • 转发只能跳转到本网站的页面;重定向可以跳转到任意页面。
  • 转发效率高;重定向效率低;能用转发的跳转就用转发。
  • 转发可以跳转到WEB-INF目录下的页面;重定向不可以跳转到WEB-INF目录下的页面。
  1. 给客户的响应数据
PrintWriter out = response.getWriter();
out.write("<!DOCTYPE html>");
  1. 设置编码
    setContentType("text/html;charset=UTF-8");

HttpSession

获取HttpSession对象:

request.getSession()

域对象:

​ 一次会话-----从浏览器第一次发生请求开始到浏览器关闭结束。

ServletConfig

获取ServletConfig对象:

getServletConfig()

获取web.xml文件的servlet标签中配置的数据:

<servlet>
        <servlet-name>config</servlet-name>
        <servlet-class>ServletServletConfig</servlet-class>
        <init-param>
            <param-name>charset</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>config</servlet-name>
        <url-pattern>/config</url-pattern>
    </servlet-mapping>

servletConfig.getInitParameter("charset");
//只能在该Servlet类中获取。

给标签中设置的url发送请求。不能给

@WebServlet中设置的url发送请求。

ServletContext

获取SevletContext对象:

getServletContext()

域对象:

服务器启动时创建该对象,服务器关闭则该对象销毁。

读取web.xml文件中配置的信息:

<context-param>
    <param-name>char</param-name>
    <param-value>gb</param-value>
</context-param>

servletContext.getInitParameter("char");
//可以在所有的servlet代码中获取。

  1. JSP

    1. JSP:Java Server Page java服务器页面

      JSP技术:HTML CSS JS java servlet 标签

      好处:更方便的创建动态页面,将页面返回给客户端。

      本质:会将JSP程序转换为servlet程序,最终执行servlet。

      ***.jsp->***_jsp.java(servlet)

    标签(***元素 el jstl) 文件上传 文件下载 过滤器 监听器

    1. JSP脚本元素

      <% 标签体 %>:

      标签体:Java程序。如:jdbc

      本质:会将标签体中的java程序编译到servlet中的

      _jspService方法中。

      <%=标签体 %>:

      标签体:java表达式

      功能:将java表达式的结果显示到页面中。

      注意:表达式末尾不能有分号。

      <%!标签体 %>:

      ​ 标签体:java程序,定义变量,定义方法。

      ​ 本质:定义的变量和方法是该类的数据成员和方法成员。

    2. 脚本元素

      ​ <%=java表达式%>:

      ​ 使用表达式的 结果 替换 <%=java表达式%>
      ​ 可以在标签的属性中使用。
      ​ 表达式中的字符串永远用双引号包括。

    ​ 注释:

    ​ // /**/:java程序

    ​ :HTML标签。可以在对应的servlet中显示。

    ​ <%----%>:HTML标签和JSP标签

    1. 指令元素

      提供给服务器,指明如何编译生成servlet程序。

      ​ 指令元素的格式:<%@ 指令元素名 属性=”值” ……>

      ​ page:

      import:

      ​ 导入包

      ​ language:

      ​ 指定脚本语言中使用的编程语言。

      session:

      ​ 指定session对象是否可以使用。

      ​ false:不可以使用。

      ​ info:

      ​ 该属性的值可以通过 getServletInfo() 获取。

      errorPage:

      ​ 给该属性赋url,当该jsp出现505错误时,跳转(转发)到该页面。
      ​ 只对该jsp文件有效。

      Web.xml:

      <error-page>
         <error-code>500</error-code>
         <location>/500.jsp</location>
      </error-page>
      
      

      ​ 对该工程中的所有jsp文件有效。

      ​ 跳转是转发。

      contentType:

      ​ 设置页面中中文编码。

      isErrorPage:

      ​ 赋值为true时,则生成的servlet程序中会创建exception对象,通过该对象可以获取错误信息。

      ​ autoFlush:

      ​ true:缓冲区内容自动刷新。

      ​ include:

      ​ 将某个页面包含到该页面中。

      [%@include file="/sub.jsp"%](mailto:%@include file="/sub.jsp"%)

      ​ File值中的/表示根目录。

      包含进来的子页面设置的样式会影响该页面。

      ​ 将子页面中的代码拷贝到了该页面中,生成一个文件。

      ​ taglib:

      ​ EL JSTL

    2. 动作元素

      <jsp:名字  属性=“值” ……>
          
      <jsp:forward>	// 重点
      	实现页面的跳转(转发)。
      	<jsp:forward page="/WEB-INF/first.jsp?user=wang&pwd=123">
      </jsp:forward>
      
      <jsp:param>
      		在实现页面跳转,包含页面时传递参数。
      
      <jsp:include>
      		将某个页面包含到当前页面。
      		有两个jsp文件,对应两个servlet文件。
      
      

内置对象

九大内置对象

request  response  session  application  page  out  pageContext  config   exception 

  • Request

    1. 获取客户端发送的数据

    2. 实现页面的跳转(转发)

    3. 设置客户端发送的中文编码

    4.

    //获取请求头中的数据
    http://192.169.7.164:8088/lesson_war_exploded/first.jsp
    
    //获取请求头中所有的name:
    	request.getHeaderNames();
    //根据传入的名字返回该名字对应的值:
    	request.getHeader(name);
    //获取客户端发送请求的方式:
    	getMethod();
    //获取客户端发送请求的url(重点)
    	getRequestURL()
    //获取发送请求的客户端的ip地址(重点)
    	getRemoteAddr();
    //获取客户端发送给服务器端的Cookie对象(重点)
    	getCookies();
    
    //应用:
    //防止盗链:不可以从其他网站的某个网页跳转到本网站的某个网页,只能通过本网站的某个网页跳转到本网站的某个网页。
    
    
  • Response

    1. 页面跳转(重定向)

    2. 设置编码

    3. 创建PrintWriter对象,从而给客户端相应数据。

    4. 设置页面自动刷新—重定向

      response.setHeader("refresh", "*秒");

    5. 设置页面延迟一定时间后自动跳转到另一个页面。–重定向

      response.setHeader("refresh", "*秒; URL=url");

    6. 保存Cookie,将Cookie返回给客户端 (重点)

      Cookie类,保存数据,在服务器端创建,将Cookie对象添加到response中,通过response对象将Cookie对象返回给客户端,Cookie在客户端以文件的形式保存,不同的浏览器对应不同的文件;客户端给服务器端发送请求时,会将该服务器的Cookie数据发送过去。

      //操作Cookie:
      		//创建Cookie对象,同时设置name和value。
      		//设置最大生命期。
      		//设置路径。
      		//添加到response对象中。
      
      
      Cookie c = new Cookie("user", "wang");
      c.setMaxAge(10);        //秒
      c.setPath("/");
      response.addCookie(c);
      
      
  • Out

    向客户端输出信息
    
    isAutoFlush()
    getBufferSize()
    write("<h1>非常好</h1>");
    flush()
    
    
  • Session

    域对象
    生命期为一次会话。
    <%@ page session="true" %>
    
    域对象:
    设置会话闲置间隔时间:		//重点
    	setMaxInactiveInterval()
    获取session的IDgetId()
    	removeAttribute("key");	//
    销毁session对象:			//
    	session.invalidate()    //
    
    
  • Application

    javax.servlet.ServletContext类对象。
    域对象
    生命期为一次服务器的启动到关闭过程。		//重点
    获取在web.xml文件中的<context-param>标签中配置的数据。
    获取工程中文件的绝对路径:getRealPath("/文件名")  /表示工程中的web目录
    
    应用:显示页面浏览次数。
    http:// 192.169.7.164:8088/lesson/浏览次数.jsp
    
    
  • Page

    this

  • pageContext

    创建四个的内置对象。
    域对象:
    生命期默认为一个页面。
    
    可以设置生命期为一次请求,一次会话,一次服务器启动到关闭,本质是将数据写入到了request,session,application
    
    获取根目录:		//重点
    
    String contextPath;
    HttpServletRequest req = (HttpServletRequest) pageContext.getRequest();
    contextPath = req.getContextPath();
    
    
  • Config

    作用:获取web.xml文件中配置的数据。

    <servlet>
            <servlet-name>conf</servlet-name>
            <jsp-file>/config.jsp</jsp-file>
            <init-param>
                <param-name>charset</param-name>
                <param-value>gbk</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>conf</servlet-name>
            <url-pattern>/jspconfig</url-pattern>
        </servlet-mapping>
    
    

    重定向到WEB-INF目录下的jsp文件:

    <servlet>
        <servlet-name>ok</servlet-name>
        <jsp-file>/WEB-INF/ok.jsp</jsp-file>
    </servlet>
    <servlet-mapping>
        <servlet-name>ok</servlet-name>
        <url-pattern>/ok</url-pattern>
    </servlet-mapping>
    
    
  • Exception

    <%@ page isErrorPage="true" %>
    exception.getMessage()
    
    

EL

  • Expression Language 表达式语言
  • 好处:简化代码
  • EL开关:<%@page isELIgnored="false" %>\
  • 语法:${表达式}
  1. 部分术语
系统定义的对象。
域对象:获取四个域对象中保持的属性值。

获取不同类型的属性值:
String   基本类型:${域对象名.属性名}
对象:
		${域对象名.属性名.数据成员名}
		${域对象名.属性名[“数据成员名”]}
数组 集合:
		${域对象名.属性名[下标]}
	  本质:域对象.getAttribute(“属性名”).数据成员名;
pageScope				//重点
requestScope			//
sessionScope			//
applicationScope		//
如果只写属性名,没有***Scope,则依次pageContext request  session  application

Param					//
		${param.参数名}
		Request.getParameter(“参数名”);
paramValues				//

header
headerValues
cookie
initParam

  1. 操作运算

    符号类型示例
    数值12
    布尔true / false
    字符串“ab” / ‘ab’
    null
    运算符解释
    + / - / * / ‘/’ / % /基本运算(+不能进行字符串拼接)
    > (gt)大于(great)
    < (lt)小于(litter)
    >= (ge)大于等于(great equal)
    <= (le)小于等于(litter equal)
    == (eq)等于(equal)
    != (ne)不等于(not equal)
    && (and)
    || (or)
    ! (not)
    式1 ? 式2 : 式3三元表达式
    empty空运算符
  2. EL对象

    Student   id  name
       student = new Student(1001, "a");
       request.setAttribute("stu", student)
       ${stu.id}    ${stu["id"]}
    
       param
       paramValues
       header:
    获取请求头中的数据
    header.属性名
    header["属性名"]
    本质:
    request.getHeader("Accept-Language")
       initParam:
    获取<context-param>中配置的参数。
    本质:
    application.getInitParameter("charset")
       cookie:
    cookie.属性名
    
    

JSTL

JSP Standard Tag Library JSP标准标签库

  • 好处

    • a. 简化JSP和web程序的开发。
    • b.提供了一致的接口,最大程度的提高了web应用程序在各种服务器上的移植。
    • c. 减少了jsp文件中java程序的数量。
    • d. 支持EL
  • 分类

    核心:分支 循环
    XML:访问xml文件中的数据
    国际化:实现中英文转换
    数据库:访问数据库

  • 环境配置

    a. 添加jar包
    b. <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

  1. 常用标签
<c:out value="">		//重点
将value属性值替换该标签。

<c:out value="你好"></c:out>
在value属性值中可以使用EL<c:out value="<p style='color:red;'>abc</p>" 
    default="默认值" escapeXml="false"></c:out>

  <c:set >
1。给域对象设置属性值。
<c:set var="user" value="zhou" scope="request"></c:set>

2。给域对象中的属性值的数据成员设置值。
<c:set target="${stu}" property="id" value="9999"></c:set>
注意:需要使用 ${stu} 获取域对象中对应的 对象。

  1. 分支标签

    <c:if>:类似于if				//重点
    	<c:if test="el表达式">
    
          <c:choose>:类似于switch	//
    	<c:when test="el表达式">	
    	<c:otherwise>
    
        有一个或多个when标签,当一个when标签的test为true时,则执行该标签中的内容,执行完则chookse结束。如果所有的when的test都为false时,则执行otherwise标签中的内容。		//
    
    可以使用choose实现if-else的效果。
    
    
  2. 循环标签

    <c:forEach>:类似于for		//重点
    1. 指定开始 结束 步长
        begin:开始值
        end:结束值
        step:步长
        varStatus:
            index:从begin到end之间的值
            count:1 2 3 4 。。。。
            first:是否是第一次执行
            last:是否是最后一次执行
    2. 从数组或集合中遍历元素
        items:el获取的数组或集合
        var:变量
        varStatus:
        index:从0到最后下标之间的值
    
    

监听器与过滤器

一. 监听器

  1. ServletContext(application)监听
    1) 创建监听类,实现监听接口,重写方法
    2) 在web.xml文件中配置<listener>标签

    a. 监听创建和销毁
    ServletContextListener
    b. 监听属性操作–添加 删除 修改
    ServletContextAttributeListener

  2. ServletSession(session)监听

a. 监听创建和销毁
HttpSessionListener
b. 监听属性操作–添加 删除 修改
HttpSessionAttributeListener

  1. ServletRequest(request)监听

a. 监听创建和销毁
ServletRequestListener
b. 监听属性操作–添加 删除 修改
ServletRequestAttributeListener

  1. ServletSession(session)监听

a. 监听session的 钝化 和 活化

  • 钝化:当服务器正常关闭时,会将session中生命期没结束的对象保存到文件中。
  • 活化:当服务器启动时,会将文件中保持的对象添加到session中。
1> 创建对象,实现 HttpSessionActivationListener, Serializable 这两个接口。
   无需再web.xml文件中配置。
2> 在服务器的conf文件的context.xm文件中增加以下内容:
<Manager className="org.apache.catalina.session.PersistentManager"
    saveOnRestart="true">
<Store className="org.apache.catalina.session.FileStore"
            directory="c:/session"> </Store>
</Manager>

​ b. 监听session 绑定对象 和 解除对象
​ 保存在session中的对象要实现HttpSessionBindingListener

二. 过滤器

  1. 用途,原理

    当在多个web程序中执行相同的操作,则可以把相同的操作放在过滤器中操作。

  2. 实现过滤器

    a. 实现Filter接口

    b. 在web.xml文件中配置<filter>

    url-pattern:

    1. 精确匹配:/路径名和文件名。 如:/jsp/a.jsp

    2. 目录匹配:/路径名/*。 如:/jsp/* /a/b/* /*

    扩展匹配:*.后缀名。 如:*.jsp

    当服务器启动时,创建过滤器对象,执行init方法;

    当服务器关闭时,销毁过滤器对象,执行destroy方法。

    doFilter参数:

    request response 和 servlet中的dopost中参数相同。

    filterChain 用于跳转到url中指定的web程序执行。

  3. 过滤器执行过程

    当浏览器端给服务器端发送请求时才考虑执行过滤器。
    根据请求的url和<url-pattern>中的路径进行匹配,若匹配成功则执行<filter-class>中的类。

注意

  • 一个<filter> 可以对应多个 <filter-mapping>
  • 可以有多个<filter>,成为过滤器链,按照配置的顺序先后执行。

AJAX

Asynchronous Javascript And Xml 异步的JS和xml

好处:不刷新页面,只更新页面的局部。

工作原理

  1. 网页中发生一个事件(页面加载、按钮点击)
  2. 由 JavaScript 创建 XMLHttpRequest 对象
  3. XMLHttpRequest 对象向 web 服务器发送请求
  4. 服务器处理该请求
  5. 服务器将响应发送回网页
  6. 由 JavaScript 读取响应
  7. 由 JavaScript 执行正确的动作(比如更新页面)

JS实现AJAX

  1. 创建XMLHttpRequest对象。

  2. 设置响应处理函数。

    if (xmlhr.status == 200 && xmlhr.readyState == 4)
    xmlhr.responseText:获取服务器端响应的文本数据。
    xmlhr.responseXML:获取服务器端响应的xml数据。
    
    
  3. 执行open方法,设置请求方式,url,异步或同步。

  4. 执行send方法,给指定的rul发生请求。

readyState的五种状态

readyState 状态状态说明
(0)未初始化请求未初始化(还没有调用 open()
(1)载入请求已经建立,但是还没有发送(还没有调用 send()
(2)载入完成请求已发送,正在处理中(通常现在可以从响应中获取内容头)
(3)交互请求在处理中;通常响应中已有部分数据可用了,但是服务器还没有完成响应的生成
(4)完成响应已完成;您可以获取并使用服务器的响应了

Program:

  • 登录的前端后端
  • Cookies
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CPanMirai

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值