14.JSP、EL表达式、JSTL标签

JSP、EL表达式、JSTL标签

第一节 JSP

Servlet3.1

JSP 2.3

Servlet的用途:
1 接受浏览器的请求,获取数据
2 转发、重定向
3 负责调用业务层

Servlet缺点:不适合展示数据,如果想要写一个网站,那么需要打印html中的每一行

1.1 JSP是什么

全称: Java Server Pages,java服务器页面。和Servlet一样,是sun公司定义的一种动态网页开发技术。本质上就是servlet,只不过使用它来开发网页非常的方便。
特点:基于html模版,可以在html模版嵌入java代码和jsp中的标签。

tomcat可以包含的资源:
静态资源:
html:静态页面。
CSS:修饰美化html页面。
JavaScript:动态修改html页面和css样式。
动态资源
Servlet:运行在服务器上的java小程序。适合编写java代码,写网页困难,适合业务处理
Servlet三个用途:1 接受浏览器发送的数据 2 负责调用业务层 3转发重定向
JSP:适合编写动态内容,不适合写java代码,主要用于显示页面。

1.2 为什么要用JSP

2.1 jsp性能好,可以在html页面中动态嵌入元素
2.2 服务器调用的是已经编译好的JSP文件
2.3 JSP基于Java Servlet Api,有很多强大企业的支持。
2.4 JSP可以与处理业务逻辑的Servlet一起使用,该模式被Java Servlet模版引擎所支持。

1.3 JSP优势

3.1 与纯 Servlet 相比:JSP可以很方便的编写或者修改HTML网页而不用去面对大量的println语句
3.2 与JavaScript相比:虽然JavaScript可以在客户端动态生成HTML,但是很难与服务器交互,因此不能提供复杂的服务,比如访问数据库和图像处理等等。
3.3 与静态HTML相比:静态HTML不包含动态信息

1.4 JSP语法
1.4.1 JSP语法格式

JSP页面中可以包含指令,Java语句、变量、方法或表达式、静态内容(html、css、javascript)

​ 语法格式:

指令:

​ <%@ page language=“java” contentType=“text/html; charset=UTF-8”

pageEncoding=“UTF-8”%>

脚本

​ <% java代码 %>

​ <% int i=10;%>
脚本表达式:

​ 输出变量: <%=2+3%>等价于输出语句 (注意:不能使用分号来结束表达式)

声明:

​ <%!

​ 定义方法

​ %>

静态资源:HTML、CSS、JS

1.4.2 JSP注释

​ 格式: <%-- 网页注释 --%>:安全,省流量
​ 网页注释: ,特点,不安全,耗流量

1.4.3 代码演示
<%--指令,页面的设置--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" %>
    <%--1、模板元素 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>第一个JSP页面</title>
</head>
<body>
<%--我是jsp特有的注释 --%>
<!--我是HTML的注释  -->
<a href="http://www.baidu.com">百度一下</a>
<%--jsp脚本 --%>
<% int c=10; %>
</body>
</html>
<%--指令,页面设置信息 --%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta charset="UTF-8">
<title>第二个JSP页面</title>
</head>
<body>
<%--我是JSP的注释,我是不会出现在对应的java类中的 --%>
<!--我是HTML的注释,会写出到页面  -->
  
<!--jsp脚本之声明  -->
<!--声明一个属性  -->
<%!private int count; %>
<!--声明并且实现方法  -->
<%!public void show(){
	System.out.println(count); 
} %>
<%!private int age=10; %>
<%-- <%!show(); %> --%>
<!--jsp脚本之方法内使用  -->
<!-- 局部变量 -->
<%
  int c=1;
%>
<%
  	count++;
	c++;%>
<%
System.out.println("局部变量:"+c);
System.out.println("成员变量:"+count);
%>
<%
  System.out.println("请求的IP地址:"+request.getRemoteAddr());
 %>
<!--jsp脚本之三:赋值、输出内容  -->
<h1>访问次数:<%=count %></h1>

</body>
</html>

​ 通过查看源码,发现所有的jsp页面都变成类, (文件名_jsp.java),类继承HttpJspBase, HttpJsbBase又继承HttpServlet,所有的jsp页面都是Servlet。

1.5 JSP指令

告诉JSP引擎如何解析jsp文件中的内容
​ 语法: <%@ 指令名称 属性名称1=“属性值1” 属性名称2=“属性值2” …%>
​ 示例:<%@ page language=“java” contentType=“text/html; charset=UTF-8” pageEncoding=“UTF-8”%>

1.5.1 page指令

作用:用于定义JSP页面的各种属性。

import和java代码的含义一样
<%@ page import=“java.util.Date,java.util.List”%>
或者:
<%@ page import=“java.util.Date”%>
<%@ page import=“java.util.List”%>
session:是否会自动创建session对象,默认值为true;
buffer:JSP中有java.servlet.jsp.JspWriter输出字符流。设置输出数据的缓存大小。默认8kb.
errorPage:如果页面中有错误,跳转到指定的资源 errorPage="/uri" 如果写“/”则代表当前应用的目录 下,绝对路径。 如果不写“/”则代表相对路径
isErrorPage:是否创建throwable对象。默认是false
contentType:等同于response.setContentType(“text/html;charset=utf-8”);服务器发送客户端的内容编码
pageEncoding: Jsp文件本身的编码
isELIgnored: 是否支持EL表达式。 默认是false,支持表达式;是true表示不支持表达式,${1+1};false输出结果2 true按照原样输出

1.5.2 include指令

include指令
静态包含:把其它资源包含到当前页面中 <%@ include file=“header.jsp” %>
动态包含: <jsp:include page=“header.jsp"></jsp:include>
两者的区别:翻译的时间段不同(可在tomcat工作目录下查看)
静态包含:在翻译时就把两个文件进行合并,运行时效率高。
动态包含:不会合并文件,当代码执行到include时,才包含另一个文件的内容。

1.5.3 taglib指令

作用:在JSP页面中导入JSTL标签库。JSTL替换jsp中的java代码片段。
<%@ taglib uri="http://java.sun.com/jsp/jstl/core"prefix=“c” %>

1.6 JSP的6个动作标签

使用标签的形式表示一段java代码,例如:
jsp:include 动态包含
jsp:forward请求转发
jsp:param 请求设置参数
注意:主页面中设置编码类型utf-8 jsp:param的value属性才可以使用中文,不然会乱码

jsp:useBean 创建一个对象
jsp:setProperty给指定的对象属性赋值
jsp:getProperty取出指定的对象属值

    <jsp:include page="footer.jsp">
        <jsp:param name="username" value="zhangsan"></jsp:param>
    </jsp:include>
    
  <%--  <jsp:forward page="sub.jsp?username=张三">
        <jsp:param name="age" value="20"></jsp:param>
    </jsp:forward>
	转发,地址不变,但是页面会显示sub.jsp,同时传入参数name和age
--%>

    <jsp:useBean id="user" class="com.qf.domain.User"></jsp:useBean>
    <jsp:setProperty name="user" property="username" value="张三"></jsp:setProperty>
    <jsp:setProperty name="user" property="password" value="123"></jsp:setProperty>
    <jsp:setProperty name="user" property="email" value="zhangsan@qq.com"></jsp:setProperty>

    <jsp:getProperty name="user" property="username"></jsp:getProperty><br/>
    <jsp:getProperty name="user" property="password"></jsp:getProperty><br/>
    <jsp:getProperty name="user" property="email"></jsp:getProperty><br/>

注意如果sub.jsp出现乱码,那么需要设置request编码格式。注意需要设置的是sub.jsp上级的编码格式。

1.7 内置对象

Servlet中内置对象:request 、response、session、application、out(PrintWriter)

Jsp本质是Servlet,包含九个内置对象

对象名类型说明
requestjavax.servlet.http.HttpServletRequest
responsejavax.servlet.http.HttpServletResponse
sessionjavax.servlet.http.HttpSession由session=“true”开关
applicationjavax.servlet.ServletContext
configjavax.servlet.ServletConfig
exceptionjava.lang.Throwable由isErrorPage=“false”开关
outjavax.servlet.jsp.JspWriterjavax.servlet.jsp.JspWriter
pageContextjavax.servlet.jsp.PageContext
pagejava.lang.Object当前对象this当前servlet实例

r r s a c e o p p

代码演示:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP内置对象</title>
</head>
<body>
<%
//页面上下文对象
pageContext.setAttribute("msg", "我是PageContext对象");
System.out.println(pageContext.getAttribute("msg"));
//请求对象
System.out.println("请求对象:"+request);
//响应对象
response.getWriter().print("OK");
//当前页面对象
System.out.println(page.getClass());//输出到控制台
//输出对象
out.print(48);//输出到浏览器:48
out.write(48);//输出到浏览器:0
int no=101;
//会话对象
System.out.println(session);
//全局对象
System.out.println(application.getRealPath("/"));
//配置对象--初始化参数
System.out.println(config.getServletName());
//异常对象
System.out.println(exception);
System.out.println(application);
application.setAttribute("author", "1711");
%>
<h1>jsp脚本:<%=no %></h1>
<h1>jsp脚本:<% out.print(no); %></h1>
</body>
</html>

jsp的out和getWriter()方法的区别

	1 out是JspWriter类型,getWriter()是PrintWriter类型
	2 out输出到缓冲区中,没有写到response中,getWriter()直接写到response中。
	3 out一般用在jsp中,getWriter()用在Servlet中

1.8 pageContext对象

pageContext作用:

​ 1 代表页面上下文,获取其他八个内置对象

​ 2 作用容器使用

1.8.1 域对象

jsp中共包含四个域对象分别是request、session、application、pageContext

request域的使用场景:本次请求之后,数据就不再使用了,根据学号查询学生,根据新闻id查询新闻。

session域的使用场景:同一个会话中共享的数据,使用session,用户登录信息

application域的使用场景:所有用户共享的数据。整个程序的配置信息

pageContext域的使用场景:当前页面。

其中pageContext可以操作其他三个域对象(request,session,application)的数据

    void setAttribute(String name,Object o);
    Object getAttribute(String name);
    void removeAttribute(String name);

操作其它域对象的方法
    void setAttribute(String name,Objecto,int Scope);
    Object getAttribute(String name,intScope);
    void removeAttribute(String name,intScope);
Scope作用域,值如下:
    PageContext.PAGE_SCOPE
    PageContext.REQUEST_SCOPE
    PageContext.SESSION_SCOPE
    PageContext.APPLICATION_SCOPE

findAttribute(Stringname)自动从pageContext,request ,session ,application依次查找,
                         找到了就取值,结束查找  (作用域的范围由小到大)

1.8.2 它可以访问其它的8个内置对象

在普通类中可以通过PageContext获取其它JSP隐式对象,具体如下:

getException方法返回exception隐式对象 
getPage方法返回page隐式对象
getRequest方法返回request隐式对象 
getResponse方法返回response隐式对象 
getServletConfig方法返回config隐式对象
getServletContext方法返回application隐式对象
getSession方法返回session隐式对象 
getOut方法返回out隐式对象

1.8.3 提供了简易方法
pageContext.forward(“2.jsp”);//转发  request.getRequestDispatcher().forward();
pageContext.include(“2.jsp”);//动态包含

第二节 EL表达式
2.1 EL概述和基本语法

注意java代码需要在<%%>java代码块中书写,在其他地方可以直接写html语句,使用EL表达式可以方便的使用.运算符,语法为${},打括号内加入之前setAttribute声明的name,不加双引号。使用集合时就算越界也不会报错,map可以使用.运算符,但是如果key是数字只能用 ${map[‘2’]}的方法来获取值。

​ EL表达式:Expression Language表达式语言
​ 目的:简化jsp中java代码开发,代替脚本表达式<%=username%>
​ 它不是一种开发语言,是jsp中获取数据的一种规范
​ 格式如: ${EL表达式} 等价于<%=pageContext.findAttribute(name)%>
最大的优势是表达对象及对象属性时非常简单

2.2 EL的具体功能

​ 案例1:获取简单数据

<br />=====================案例一:获取简单数据===================
	<br />
	<%
		pageContext.setAttribute("username", "张三");
		request.setAttribute("age", "25");
		//request.setAttribute("username", "李四");
		session.setAttribute("phone", "13838383838");
		application.setAttribute("address", "北京昌平沙河");

		User user = new User();
		user.setUsername("学智");
		user.setPassword("8888");
		user.setPhone("1899999999");
		user.setGender("妖");
		user.setAdd(new Address("泰国","曼谷","xxx区"));
		pageContext.setAttribute("u", user);
	%>
	<br />-----------------findAttribute()获取数据-------------------
	<br />
	<%=pageContext.findAttribute("username")%><br />
	<%=pageContext.findAttribute("age")%><br />
	<%=pageContext.findAttribute("phone")%><br />
	<%=pageContext.findAttribute("address")%><br />
	<br />-----------------el表达式获取数据-------------------
	<br /> ${username }
	<br /> ${age }
	<br /> ${phone }
	<br /> ${address }
	<br /> ${"username" }
	<br />

比较方便的是可以使用${user.address.city}的方式来输出对象的对象属性的属性。
​ 案例2:获取实体类对象中的属性值

<%
User user= new User();
user.setName("gggg");

Address  address = new Address();
address.setAddr("北京市海淀区");
user.setAddress(address);

session.setAttribute("user", user);
/* request.getRequestDispatcher("testEl.jsp").forward(request, response); */
response.sendRedirect("testEl.jsp");
%>
<!--  EL表达式中的.表示调用该属性的get方法 -->
<%-- 我是:$住在{user.name }  , 住在  ${user.address.addr } --%>

​ 案例3:使用List和Map集合

    <h3>案例3:使用list和map集合</h3>
    <%
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("华为" );
        arrayList.add("小米" );
        arrayList.add("苹果");
        pageContext.setAttribute("list", arrayList);

        Map<String,String> map = new HashMap<>();
        map.put("1", "aa");
        map.put("2", "bb");
        map.put("cc", "3");
        pageContext.setAttribute("map", map, PageContext.PAGE_SCOPE);
    %>

    <h3>EL表达式获取list集合,越界不报错</h3>
    ${list[0]}
    ${list[1]}
    ${list[2]}
    ${list[3]}

    <h3>EL表达式获取map集合可以使用.   可以使用["key"]</h3>
    ${map['1']}
    ${map['2']}
    ${map.cc}
2.3 使用EL表达式执行运算、empty关键字

执行运算

	算术运算
	${10+20 }<br/>
	${10-20 }<br/>
	${10*20 }<br/>
	${3%5}<br/>
	关系运算
	${10==9 }<br/>
	${"abc"=="abc" }<br/>
	${s1==s2 } equals<br/>
	${s1 eq s2 }<br/>
	${10>20}<br/>
	${10 gt 20}<br/>
	${5 < 10}<br/>
	${5 lt 10}<br/>
	${5 != 10}<br/>
	${5 ne 10}<br/>
	

	三目运算
	${score>80?"优秀":"一般" }<br/>  
	${flag==0?"没有激活":flag==1?"激活":"删除" }<br/>  
	${sex==0?"男":"女" }<br/>  
	
     逻辑运算
	${true &&  false}<br/> 
	${true || false}<br/> 
	${!true}<br/> 
	${true and  false}<br/> 
	${true or false}<br/> 
	${not true}<br/> 

EL表达式中的eq就相当于jav中==

<% String s1="";
pageContext.setAttribute("s1", s1);
String s2=null;
pageContext.setAttribute("s2", s2);
String s3="122222";
pageContext.setAttribute("s3", s3);
List list1 =new ArrayList();
pageContext.setAttribute("list1", list1);
%>

<!-- empty关键只要内容是空true   域内无该对象,字符串"",集合无元素-->
${empty user}<br>
${empty str}<br>
${empty  list1}<br>

2.4 隐式对象(11个)

JSP 表达式语言定义了一组隐式对象,其中许多对象在 JSP servlet和表达式中可用:

**pageContext:**页面上下文,可以获取jsp中其他八个内置对象

pageScope、requestScope、sessionScope、applicationScope表示四个域对象中集合

param 表示request.getParameter(“username”); ${param.username}

paramvalues 表示request.getPrameterValues(“hobby”); ${paramValues.hobby}

header 表示 request.getHeader(“accept”); ${header.accept};

headerValues 表示 request.getHeaderValues(“accept-encoding”); ${headerValues[“accept-encoding”][0]}

cookie 表示 request.getCookies(); ${cookie.JSESSIONID}

initParam 表示 ServletContext(application)初始化参数

第三节 JSTL
3.1 什么是JSTL

JSTL:全称Java Server Pages Standard Tag Library,JSP标准标签库,代替jsp页面的脚本,实现逻辑控制。

3.2 JSTL的作用

实现JSP页面中逻辑处理。如判断, 循环等;

下载JSTL库,https://archive.apache.org/dist/tomcat/taglibs/

把jstl.jar、standard.jar放入WEB-INF/lib目录下

3.3 使用JSTL

必须在JSP页面添加tablib指令库

<% @taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c">

3.4 常用标签介绍
3.4.1 通用标签set,out,remove
<!-- 基础标签:声明变量,输出变量,移除变量,变量默认值 -->
	<h3>基础标签:声明变量,输出变量,移除变量,变量默认值</h3>
<!--1.声明变量k   var:是变量名  value:变量的值(必须是EL表达式)-->
	<c:set var="k" value="${1+1}"></c:set>
<!--2.输出变量k   value:使用EL表示表示变量-->
	移除前输出的内容:<c:out value="${k}"></c:out><br>
<!--3.移除指定变量  -->	
	<c:remove var="k"/>
	移除后输出的内容:<c:out value="${k}"></c:out><br>
<!--4.给指定变量赋默认值  -->
	默认值:<c:out value="${m}" default="123456"></c:out>

3.4.2 条件标签if,choose

<c:if>

<!-- 条件标签:if  choose -->
	<!-- test属性中是条件,但是条件需要使用EL表达式来书写 -->
	<h3>条件标签:if</h3>
	<c:if test="${8>2 }">
    8大于2是成立的
     </c:if>
	<c:if test="${8<2 }">
    8小于2是成立的
    </c:if>
	<br>
	<%--  如果只是一个基本数据类型直接书写不需要${} --%>
	<c:set var="m" value="5"></c:set>
	<c:if test="${m>3}">
     5大于3是成立的
  </c:if>

<c:choose>

<h3>条件标签:choose(等价于java中switch)</h3>
<%-- 测试成绩等级 >90 优秀   >80  良好    >70 中等   >60及格--%>
<c:set var="score" value="80"></c:set>
<c:choose>
	<c:when test="${score>=90 }">优秀</c:when>
	<c:when test="${score>=80 }">良好</c:when>
	<c:when test="${score>=70 }">中等</c:when>
	<c:when test="${score>=60 }">及格</c:when>
	<c:otherwise>不及格</c:otherwise>
</c:choose>

3.4.3 迭代标签foreach

for基础遍历

<!-- 遍历for:输出1到10 的值 -->
	<!--var: 变量,把遍历的每一个值都存储在变量中进行输出
    begin:开始   如果是变量使用EL表达式表示
    end:结束    如果是变量使用EL表达式表示
    step:间隔的长度
    
    for( int i=0;i<10;i++){
     System.out.println(i);
    }
     -->
示例代码:从几开始,到几结束
<c:forEach var="i" begin="1" end="10" step="2">
 ${i}<br>
</c:forEach>

foreach遍历

  <h3>测试list集合遍历获取学生列表</h3>
      <table border="1" width="80%" bordercolor="red" cellspacing="0"
          align="center">
          <tr>
              <th>学号</th>
              <th>姓名</th>
              <th>成绩</th>
              <th>班级</th>
              <th>是否是第一个</th>
              <th>是否是最后一个</th>
              <th>计数count</th>
              <th>索引index</th>
          </tr>
   <!-- varStatus:变量状态:遍历出的每一项内容的状态:
      isFirst()      first
      isLast()       last
      getCount()     count  计数  重要的
      getIndex()     index
       -->
       <!-- var :遍历出的每一项使用变量先存储
            items:集合(使用El表达式)
            -->
          <c:forEach var="stu" items="${students}" varStatus="vs">
              <tr>
                  <td>${stu.id}</td>
                  <td>${stu.name}</td>
                  <td>${stu.score}</td>
                  <td>${stu.classes}</td>
                  <td>${vs.first}</td>
                  <td>${vs.last}</td>
                  <td>${vs.count}</td>
                  <td>${vs.index}</td>
              </tr>
          </c:forEach>
   </table>
3.4.4 url标签
<c:url var="" value="">

举例:
 <c:url var="loc" value="/stu.jsp">
        <c:param name="username" value="张三"></c:param>
    </c:url>

 <a href="${loc}">学生列表</a>

综合案例:

总结

1 jsp 包含的内容

​ 指令 脚本 脚本表达式 声明 HTML css javascript

​ <%@page language=“java” contentType="" pageEncoding=“utf-8”%>

​ <%

​ %>

​ <%=aaa%>

​ <%!

​ %>

2 指令

​ page指令

​ contentType

​ pageEncoding

​ session

​ errorPage

​ include包含指令

​ 静态包含:主页面直接把子页面的内容包含进来,子页面没有生成java文件。

​ 主页面创建变量,子页面可以使用,属于同一个pageContext

​ 动态包含 (jsp:inclue):主页面在执行的时候,才把子页面包含进来,子页面生成了java文件。

​ 主页面创建变量,子页面不能使用,不属于同一个pageContext

​ taglib 指令

​ 添加标签库

3 jsp动作标签

​ jsp:include:动态包含

​ jsp:forward:转发

​ jsp:parm:转发的参数,需要主主页面设置编码

​ jsp:useBean 创建对象,并放入pageContext中

​ jsp:setPropertity:给对象属性赋值

​ jsp:getPropertity:获取属性值

4 jsp内置对象(九大内置对象)

​ request

​ response

​ session

​ application

​ config

​ exception

​ out

​ pageContext(重点)

​ page

5 pageContext: 1获取其他八个内置对象 ,2 作为容器使用,可以获取或设置其他容器中的数据

6 4个域对象 pageContext request session application

7 EL表达式 :代替页面中的脚本表达式(输出语句)<%=pageContext.findAttribute("")%>

​ ${表达式}

​ 7.1 输出简单数据

​ ${ username}

​ 7.2 输出对象的属性

​ ${user.username}

​ ${user.address.counry}

​ 7.3 输出集合数据

​ list集合

​ ${list[0]}

​ ${list[1]}

​ map集合

​ ${maps.cn}

​ ${maps[“10”]}

​ 7.4执行运算

​ 算术运算

​ 关系元素

​ 逻辑元素

​ 三元操作

​ empty空判断 “” null 集合没有元素

​ 7.5 EL 11个隐式对象

​ pageContext ${pageContext.request.contextPath}

​ pageScope 、requestScope、sessionScope、applicationScope

​ param

​ paramValues

​ header

​ headerValues

​ initparam

​ cookie

8 JSTL

​ 三个通用标签 set out remove

​ 逻辑控制 if choose (when otherwise) foreach

​ url 网址标签

​ fmt:formatDate

​ fmt:parseDate

作业题
1、使用JSP实现登录注册和图书浏览功能
面试题
1、Jsp和Servlet的区别
2、Jsp的执行原理
3、说说Jsp的隐藏对象有哪些
4、说出Jsp内置对象以及方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值