JSP学习记录

JSP相关

参考: 菜鸟教程JSP

JSP生命周期

https://www.runoob.com/jsp/jsp-life-cycle.html

JSP生命周期与Servlet生命周期类似, 只不过JSP首先需要将JSP文件转成Servlet并编译

  • 编译阶段

    IDEA中可以通过以下目录找到编译后的JSP文件

    C:\Users\用户名\AppData\Local\JetBrains\IntelliJIdea2020.2\tomcat\部署在服务器中的项目名\work\Catalina\localhost\部署在服务器中的项目名\org\apache\jsp

    image-20210407132544114

    • test.jsp

          <%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>测试</title>
          </head>
          <body>
              <p>请求JSP文件时, JSP文件会被转化成相应的Servlet实例, 编译生成Java代码</p>
          </body>
          </html>
      
    • test_jsp.java

      package org.apache.jsp;
      
      import javax.servlet.*;
      import javax.servlet.http.*;
      import javax.servlet.jsp.*;
      
      public final class test_jsp extends org.apache.jasper.runtime.HttpJspBase
          implements org.apache.jasper.runtime.JspSourceDependent,
                       org.apache.jasper.runtime.JspSourceImports {
      
        private static final javax.servlet.jsp.JspFactory _jspxFactory =
                javax.servlet.jsp.JspFactory.getDefaultFactory();
      
        private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
      
        private static final java.util.Set<java.lang.String> _jspx_imports_packages;
      
        private static final java.util.Set<java.lang.String> _jspx_imports_classes;
      
        static {
          _jspx_imports_packages = new java.util.HashSet<>();
          _jspx_imports_packages.add("javax.servlet");
          _jspx_imports_packages.add("javax.servlet.http");
          _jspx_imports_packages.add("javax.servlet.jsp");
          _jspx_imports_classes = null;
        }
      
        private volatile javax.el.ExpressionFactory _el_expressionfactory;
        private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
      
        public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
          return _jspx_dependants;
        }
      
        public java.util.Set<java.lang.String> getPackageImports() {
          return _jspx_imports_packages;
        }
      
        public java.util.Set<java.lang.String> getClassImports() {
          return _jspx_imports_classes;
        }
      
        public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
          if (_el_expressionfactory == null) {
            synchronized (this) {
              if (_el_expressionfactory == null) {
                _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
              }
            }
          }
          return _el_expressionfactory;
        }
      
        public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
          if (_jsp_instancemanager == null) {
            synchronized (this) {
              if (_jsp_instancemanager == null) {
                _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
              }
            }
          }
          return _jsp_instancemanager;
        }
      
        public void _jspInit() {
        }
      
        public void _jspDestroy() {
        }
      
        public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
            throws java.io.IOException, javax.servlet.ServletException {
      
          if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
            final java.lang.String _jspx_method = request.getMethod();
            if ("OPTIONS".equals(_jspx_method)) {
              response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
              return;
            }
            if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
              response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
              response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
              return;
            }
          }
      
          final javax.servlet.jsp.PageContext pageContext;
          javax.servlet.http.HttpSession session = null;
          final javax.servlet.ServletContext application;
          final javax.servlet.ServletConfig config;
          javax.servlet.jsp.JspWriter out = null;
          final java.lang.Object page = this;
          javax.servlet.jsp.JspWriter _jspx_out = null;
          javax.servlet.jsp.PageContext _jspx_page_context = null;
      
      
          try {
            response.setContentType("text/html;charset=UTF-8");
            pageContext = _jspxFactory.getPageContext(this, request, response,
            			null, true, 8192, true);
            _jspx_page_context = pageContext;
            application = pageContext.getServletContext();
            config = pageContext.getServletConfig();
            session = pageContext.getSession();
            out = pageContext.getOut();
            _jspx_out = out;
      
            out.write("\r\n");
            out.write("\r\n");
            out.write("<html>\r\n");
            out.write("<head>\r\n");
            out.write("    <title>测试</title>\r\n");
            out.write("</head>\r\n");
            out.write("<body>\r\n");
            out.write("    <p>请求JSP文件时, JSP文件会被转化成相应的Servlet实例, 编译生成Java代码</p>\r\n");
            out.write("</body>\r\n");
            out.write("</html>\r\n");
          } catch (java.lang.Throwable t) {
            if (!(t instanceof javax.servlet.jsp.SkipPageException)){
              out = _jspx_out;
              if (out != null && out.getBufferSize() != 0)
                try {
                  if (response.isCommitted()) {
                    out.flush();
                  } else {
                    out.clearBuffer();
                  }
                } catch (java.io.IOException e) {}
              if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
              else throw new ServletException(t);
            }
          } finally {
            _jspxFactory.releasePageContext(_jspx_page_context);
          }
        }
      }
      
      
  • 初始化-执行-销毁阶段

    image-20210407132225245

JSP基本语法

1)脚本程序 <% %>

包含在<% %>中的jsp代码,在编译生成相应Servlet后, 会包含在_jspService()方法中

所以凡是可以写在_jspService()方法中的java代码, 都可以包含在<% %>

如:

<%
	for (int i = 1; i <= 3; i++) {
%>
	<p class="text-success">哈哈哈</p>
<%
	} 
%>
public void _jspService(final HttpServletRequest request,final HttpServletResponse response)
{
    for (int i = 1; i <= 3; i++) {
        out.write("\n");
        out.write("                    <p class=\"text-success\">哈哈哈</p>\n");
        out.write("                ");
    } 
}

2)声明<%! %>

包含在<%! %>中的jsp代码,在编译生成相应Servlet后, 会包含在相应Servlet类中(类中, 方法外)

所以凡是可以写在Servlet类中的java代码, 都可以包含在<%! %>

<%!
    public int x = 100;
    public void sayHi(){
    System.out.println("Hi");
    }
 %>
public final class jsp脚本元素_jsp {
    public int x = 100;
    public void sayHi() {
    	System.out.println("Hi");
    }
    public void _jspInit() {
    }
	
	public void _jspService() {
    }
    
    public void _jspDestroy() {
    }
}

3)表达式<%= %>

可以JSP页面在任何地方插入表达式, 因为表达式会先被转成string,再插入

<p>
     <br>程序范围属性:<%=application.getAttribute("number")%>
     <br>会话范围属性:<%=session.getAttribute("number")%>
     <br>请求范围属性:<%=request.getAttribute("number")%>
     <br>页面范围属性:<%=pageContext.getAttribute("number")%>
</p>

4)指令<%@ %>

用来设置与整个JSP页面相关的属性

<%@ directive(指令) attribute="value" %>

5)注释 <%-- --%>

<%-- JSP注释,注释内容不会被发送至浏览器甚至不会被编译 --%>

JSP指令

https://www.runoob.com/jsp/jsp-directives.html

image-20210412150218715

1) Page指令

发送给Web容器, 定义JSP页面的全局属性, 一个JSP页面可以包含多个Page指令

<%@ page attribute="value" %>

image-20210407133725832

  • buffer / autoFlush

    <%@page buffer="8kb" autoFlush="true" %>
    

    JSP页面的缓冲区大小默认为8kb, 例如在浏览页面时, 图片一般先写入缓冲区, 等缓冲区满后,再flush显示在页面上

  • isTreadSafe

    默认值为true,如果设置成false,则JSP页面转化后的Servlet会实现singleThreadModel接口

    public final class jsp指令_jsp implements javax.servlet.SingleThreadModel {
    
  • session

    默认值为true

     session = pageContext.getSession();
    

    如果设置成false,则无法在JSP页面中使用session对象

  • contentType / pageEncoding

    指定当前JSP页面的MIME类型和字符编码

    <%@page contentType="text/html" pageEncoding="UTF-8" %>
    

    编译后:

    response.setContentType("text/html;charset=UTF-8");
    
  • errorPage / isErrorPage 配置错误页面

    image-20210413155120446

    通过errorPage配置当前页面发生异常是需要跳转的错误处理页面

    <%@page errorPage="errorPage.jsp" %> // A.jsp
    

    通过isErrorPage指定当前页面可以作为错误配置页面

    <%@page isErrorPage="true"%>  // errorPage.jsp
    
  • import 导入所需的Java类

    <%@ page import="java.lang.String"%>
    

2) Include指令

可以在A页面包含B页面的内容, 例如在多个页面添加同一个导航栏, 可用此指令, 方便维护

<%@include file="menu.html" %>

image-20210412135606890

3) Taglib指令

用于引入一个自定义标签集合

<%@ taglib uri="标签库的地址" prefix="标签的前缀" %>

如引入JSTL的核心标签

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

这样就可以使用JSTL的核心标签了

<c:forEach begin="1" end="3">
     <p>测试</p>
</c:forEach>

image-20210412141853999

JSP的四种属性范围

https://blog.csdn.net/evankaka/article/details/46877371

四种属性范围都支持:

public void setAttribute(String name,Object value)
public Object getAttribute(String name)
public void removeAttribute(String name)

作用范围有小到大依次是:

  • page

    使用pageContext对象设置属性

    只在当前的JSP页面内有效, 跳转后无效

  • request

    使用request对象设置属性

    在当前JSP页面有效, 若转发该request对象, 则在下一个页面也有效

  • session

    使用session对象设置属性

    在一次会话范围内,无论何种跳转都可以使用,但是新开浏览器无法使用

  • application

    使用application对象设置属性

    属性保存在服务器上,所有页面,所有用户都可以使用.

    如果两个项目运行在同一个服务器上, 他们都能获取到相应的属性

JSP动作

https://www.runoob.com/jsp/jsp-actions.html

JSP动作基本上都是一些预定义的函数. 用来替代JSP页面中的Java代码.

image-20210413154457509

  • < jsp:forword >

    <jsp:forward page="second.jsp"></jsp:forward>
    

    其实就相当于

    request.getRequestDispatcher("second.jsp").forward(request,responce);
    
  • < jsp: include>

    <jsp:include page="second.jsp"></jsp:include>
    

    其实就相当于

    request.getRequestDispatcher("second.jsp").include(request,responce);
    

JSP隐式对象

https://www.runoob.com/jsp/jsp-implicit-objects.html

https://blog.csdn.net/evankaka/article/details/46877371

image-20210322231224680

1) pageContext

作用域 page

pageContext对象可以获取当前JSP页面的任何对象,如request, session, application(ServletContext), response, out, ErrorData等

image-20210412164711230

可以获取当前页面四种作用域(page(默认), request, session, application)的属性

public abstract Object getAttribute(String name, int scope);

也可以设置四种作用域的属性

public abstract void setAttribute(String name, Object value, int scope);
PageContext.PAGE_SCOPE(默认)1page范围
PageContext.REQUEST_SCOPE2request范围
PageContext.SESSION_SCOPE3session范围
PageContext.APPLICATION_SCOPE4application范围

2) request

作用域request, 与Servlet中的用法相同

3) session

作用域session,与Servlet中的用法相同

4) application

application是ServletContext的实例

application = pageContext.getServletContext(); // JSP转化后的代码

作用域application, 可以将信息保存在服务器中, 直至服务器关闭

5) Exception

Exception代表发生异常的JSP页面中的异常对象.

Exception必须在处理异常的页面中使用,

A.jsp发生异常, 必须在B.jsp(处理异常的页面)使用Exception, Exception封装了A.jsp的相关异常信息.

<%@page isErrorPage="true" %> // B.jsp
<%
	out.println("<br>异常类型:" + exception.getClass());
    out.println("<br>异常消息:" + exception.getMessage());
    out.println("<br>异常对象:" + exception);
%>

如果想获得更多错误信息, 可以从pageContext中获取ErrorData对象,再获取相关错误信息

 <%
    ErrorData ed = pageContext.getErrorData(); 
    out.println("<br>请求的URI:" + ed.getRequestURI());
    out.println("<br>状态代码:" + ed.getStatusCode());
    out.println("<br>异常对象:" + ed.getThrowable());
%>
  • 如网页访问量统计

    image-20210412154844775

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>网页访问量统计</title>
    </head>
    <body>
        <%
            if(application.getAttribute("count") == null) {
                application.setAttribute("count",0);
            }
            application.setAttribute("count", (int)application.getAttribute("count") + 1);
        %>
        <p>
            当前网页的访问量: <%=(int)application.getAttribute("count")%>
        </p>
    </body>
    </html>
    

EL表达式

1) 访问变量

EL表达式无法直接访问Java代码段中定义的变量,

<% int number = 200 %>
${number1} <%-- 无法访问到 number --%>

必须将该变量添加至四个属性范围中的任意一个才能访问

<% pageContext.setAttribute("number", number); %>
${number1} <%-- 200 --%>

2) 运算符

运算符与Java基本一致

${1+1} // 2

注意EL表示式中/ 的计算结果是浮点数

${4/2} // 2.0 

另外empty可以测试是否为空值

${empty object} // true false

3) 自动处理空值

EL表达式会自动处理空值, 不会出现NULL POINTER异常

${number} <!-- 对于为空值变量或属性,EL不会在页面中显示 -->
${number + 1} <!-- 对于算术运算中的空值, EL会作为0处理  1  -->
${number && true} <!-- 对于逻辑运算中的空值, EL会作为false处理 -->

4) 使用函数

image-20210419110101818

  • 使用JSTL预定义函数

    image-20210420142206321

  • 使用Java自定义静态方法

    • 首先编写相关的java静态方法

      package com.xxx.util;
      public class StringUtil {
          public static String getMobile(String mobile){
              return mobile.substring(0,3)+"****"+mobile.substring(7,11);
          }
      }
      
      package com.xxx.util;
      import java.util.Random;
      public class NumberUtil {
          public static int sum(int a, int b) { 
              return a + b;
          }
      }
      
    • 创建编写TLD文件

      TLD(即Tag Library Descriptor 标记库描述符)用于描述如何使用标记和函数

      <?xml version="1.0" encoding="UTF-8"?>
      <taglib 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-jsptaglibrary_2_1.xsd"
              version="2.1">
      
          <tlib-version>1.0</tlib-version> <!--自定义当前标签库的版本-->
          <short-name>uf</short-name> <!--当前标签库的简称-->
          <uri>http://shy.com/util_functions</uri> 
          <!--标签库的唯一表示, 用于在jsp页面中引用该标签库-->
      
          <function>
              <name>sum</name>
              <function-class>com.qdu.util.NumberUtil</function-class> 
              <!-- 方法的签名: 返回值类型 方法名(参数1类型,参数2类型,...) -->
              <function-signature>int sum(int,int)</function-signature> 
          </function>
          <function>
              <name>getMobile</name>
              <function-class>com.qdu.util.StringUtil</function-class>
              <!-- 对于需要导入的包,需要写包的全限定名 -->
              <function-signature>java.lang.String getMobile(java.lang.String)</function-signature>
          </function>
      </taglib>
      
      
    • 在JSP页面引入自定义的标签库

      <%@taglib prefix="utilfc" uri="http://shy.com/util_functions" %> 
      <!-- prefix可以自定义 -->
      
    • 使用EL表达式调用静态方法

      ${utilfc:sum(3,4)}
      ${utilfc:getMobile("18888888888")}
      

4)EL 隐含对象

https://www.runoob.com/jsp/jsp-expression-language.html

image-20210322231751899

1) Scope对象

用来获取各个作用域范围内的Attribute

<p>
     <br>程序范围属性:${applicationScope.number}
     <br>会话范围属性:${sessionScope.number}
     <br>请求范围属性:${requestScope.number}
     <br>页面范围属性:${pageScope.number}
</p>
2) pageContxt对象

即当前页面的pageContext隐式对象, 可以获取/设置各作用域的属性, 获取当前页面的对象

3) param对象

获取初始化参数, 如表单中的参数 或是 URL中包含的数据

4) paramValues 对象

获取一个请求参数的一组值, 如获取多选框的值

<form action="first.jsp">
爱好:
    <!--多个同一个组的复选框名称可以相同,可以不同,但是一般建议相同-->
    <!--如果相同,则参数作为一个字符串数组提交给服务器-->
	<input id="h1" checked type="checkbox" name="hobbies" value="LOL">
    <label for="h1">英雄联盟</label>
    <input id="h2" checked type="checkbox" name="hobbies" value="贪玩蓝月">
    <label for="h2">贪玩蓝月</label> 
    <input id="h3" checked type="checkbox" name="hobbies" value="王者荣耀">
    <label for="h3">王者荣耀</label>
    <input id="h4" checked type="checkbox" name="hobbies" value="绝地求生">
    <label for="h4">绝地求生</label> 
    <input id="h5" checked type="checkbox" name="hobbies" value="学习">
    <label for="h5">学习</label>
    <button class="btn btn-success">提交请求参数给first.jsp</button>
<form>

image-20210419131330690

  • 非遍历方式获取

    <br>爱好:   ${paramValues.hobbies[0]} 
                ${paramValues.hobbies[1]}
                ${paramValues.hobbies[2]} <%--EL表达式会自动处理空值--%>
                ${paramValues.hobbies[3]} <%--EL表达式会自动处理空值--%>
                ${paramValues.hobbies[4]}
    
  • 遍历方式获取

     <br>爱好:
     <c:forEach items="${paramValues.hobbies}" var="value">
     	${value}
     </c:forEach>
    

JSTL:jsp标准标签库

1) 安装JSTL库

在项目中导入相应JAR包

image-20210412142720212

image-20210412142738681

jstl.jarstandard.jar可以在Apache官网下载获得

接下来,在每个您想使用JSTL标签的JSP页面上使用 taglib指令引入相应标签

  • 如使用核心标签

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

2) 核心标签

image-20210419133653834

  • 引用核心标签

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
  • <c:set> 定义变量

    image-20210420145505035

    <c:set var="number1" value="${1+2}" scope="page"></c:set>
    
    <c:set var="array" value="${[1,2,3]}"></c:set> <!-- 定义数组 -->
    
  • <c:remove> 移除变量

    <c:remove var="number1"></c:remove>
    
  • <c:if>

    image-20210420145728877

    <c:set var="salary" value="6000" />
    <c:if test="${salary >= 5000}" var="result" scope="page">
        <c:out value="${salary}"></c:out>
    </c:if>
    <c:out value="判断结果:${result}"></c:out>
    
  • <c:choose> 类似于if…else / swith…case

    <!-- 优秀 -->
    <c:set var="score" value="86" />
    <c:choose>
        <c:when test="${score >= 85}">优秀</c:when>
        <c:when test="${score >= 60}">及格</c:when>
        <c:otherwise>不及格</c:otherwise>
    </c:choose>
    
  • <c:foreach> 遍历

image-20210419134015496

image-20210421103823809

 <br>爱好:
 <c:forEach items="${paramValues.hobbies}" var="value">
 	${value}
 </c:forEach>

3) 格式化标签

用来格式化并输出文本、日期、时间、数字, 以及国际化等等

image-20210425112627266

简单介绍一下,具体参考API

  • fmt:formatNumber

    可以用来格式化数字, 货币, 百分比

    image-20210425113256159

    <br>格式化数字:<fmt:formatNumber value="123456789.987654321" type="number"/>
    <br>格式化百分比:<fmt:formatNumber value="22.5" type="currency"/>
    <br>格式化金额:<fmt:formatNumber value="0.55" type="percent"/>
    

    image-20210425113638962

  • fmt:formatNumber

    可以格式化日期/时间

    image-20210425113936708

    <!--Date类需要用 @page import指令导包-->
    <%@ page import="java.util.Date" %>
    <c:set var="now" value="<%=new Date()%>" />
    <br> 未格式化:${now}
    <br> 格式化日期:<fmt:formatDate value="${now}" type="date"></fmt:formatDate>
    <br> 格式化时间:<fmt:formatDate value="${now}" type="time"></fmt:formatDate>
    <br> 格式化日期和时间:<fmt:formatDate value="${now}" type="both"></fmt:formatDate>
    

image-20210425114202317

  • <fmt:setLocale>

    将给定的区域存储在locale配置变量中, 从而实现国际化

    从而根据不同的语言环境,显示不同的格式

    image-20210425130901063

    ISO-语言码和ISO-3166国家码

    <fmt:setLocale value="zh_CN"/>
    日期: <fmt:formatDate value="<%=new Date()%>" type="both"/>
    金额: <fmt:formatNumber value="123456789.987654321" type="currency"/>
    

    image-20210425131432943

  • <fmt:setbundle>

    根据设置的locale,载入相应的资源束

    image-20210426114153204

    image-20210426113911799

    <fmt:setLocale value="en_US" />
    <fmt:setBundle basename="com.shy.bundles.resource" var="mybundle"/>
    
  • <fmt:message>

    根据所载入的资源束, 找到对应的映射, 替换显示在页面中

    image-20210426114139752

    image-20210426114009350

    <form class="form-inline">
        <fmt:message key="labelUname"  bundle="${mybundle}"/>
        <br>
        <input type="text" name="uname" class="form-control"><br><br>
        <fmt:message key="labelUpwd"  bundle="${mybundle}"/>
        <br>
        <input type="text" name="pwd" class="form-control"><br><br>
        <button class="btn btn-sm btn-primary" >
            <fmt:message key="labelLogin" bundle="${mybundle}"/>
        </button>
        <a href="#"><fmt:message key="labelReg" bundle="${mybundle}"/></a>
    </form>
    

    image-20210426114423160

4) SQL 标签

利用SQL标签可以在不编写Java代码而操作相关数据库, 不过还是推荐使用JDBC的方式操作数据库

这里简要了解一下SQL标签

image-20210426131725739

  • <sql:setDataSource>

    image-20210426132312519

    <sql:setDataSource  driver="com.mysql.cj.jdbc.Driver" 
                                    url="....."
                                    user="root"
                                    password="....."
                                    var="ds" 
                                    scope="session"
    />
    
    <sql:query dataSource="${ds}" var="rs" scope="page"> <!-- rs保存了查询的结果集-->
        select * from student where sbatch=?
        <sql:param value="班级"></sql:param> <!-- 将?设为"班级" -->
    </sql:query>
    
    <!-- 结果集(ResultSet)包含很多信息,不仅仅包含行(row)数据,还包含数据的额外信息
         需要使用${结果集.rows}获取所有的行数据进行遍历 -->
    <c:forEach items="${rs.rows}" var="row">
        <tr>
            <td>${row.sid}</td>             
            <td>${row.spassword}</td>       
            <td>${row.sname}</td>              
            <td>${row.sgender}</td>             
            <td>${row.sbatch}</td>             
        </tr>
    </c:forEach>
    

JSP 国际化

  • Locale

    JSP容器能够根据request的locale属性来提供正确地页面版本

    request.getLocale()
    

    image-20210425132502807

  • Content-Language

    通过设置Http报头的Content-Language,来使页面能够显示其他语言

    <%@ page import="java.io.*,java.util.Locale" %>
    <%@ page import="javax.servlet.*,javax.servlet.http.* "%>
    <%
        // 设置页面内容要显示的语言
        response.setHeader("Content-Language", "es");
        String title = "En Espa?ol";
    %>
    <html lang="es"> <!-- lang属性为告知浏览器该页面的语言, 从而浏览器可以提供翻译功能 -->
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <head>
        <title><%out.print(title); %></title>
    </head>
    <body>
        <p>¡Vamos Barça!</p>
    </body>
    </html>
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值