Tomcat

Tomcat简介

  • 1.Tomcat是什么?
      Tmocat是一个由ApacheSun其它一些公司及个人共同开发而成的开源免费符合JavaEE规范Web应用服务器软件,属于轻量级应用服务器,是**初学者学习**Web应用开发的首选。

  • 其他常见Web服务器
    【IIS(Internet Information Services)】,属于微软公司。
    【Apache】,属于Apache软件基金会,开放源码,师姐排名第一的Web服务器软件。(tomcat是apache服务器的扩展)。
    【WebShpere】,属于IBM公司。
    【WebLogic】,属于Oracle公司。


Apache、Tomcat与Catalina作为软件名字的含义与关系(小历史)

转自http://blog.csdn.net/csdn1161851523/article/details/52870937

PS:如果只是看一些概念的话,这一段可以略过。

  如果你是从事于计算机软件相关工作的人,那你肯定经常见到Apache这个单词,也应该知道Tomcat这个服务器软件的名字,Catalina可能陌生一点,但你在配置tomcat时,一定会添加一个环境变量,然后指向tomcat的安装路径,这个环境变量的名字就叫Catalina_Home,进入tomcat安装目录,里面很多文件名字也叫Catalina。那么这三个单词作为软件的名字有什么含义、相互之间又是什么关系呢?
  上世纪八十年代,当互联网开始在美国大学流行的时候,美国计算机名校伊利诺伊大学香槟分校(UIUC)的国家超级计算应用中心(National Center for Supercomputing Applications, NCSA)组织了一些研究生开始编写基于HTTP通信协议的服务器端和客户端程序。客户端端程序叫做mosaic,是第一个被普遍使用的网页浏览器,也是Netscape(网景)浏览器的前身,之后演变为Mozilla Firefox。而服务器端程序就是最早的Web服务器软件之一,名叫NCSA HTTPd,它完整地实现了HTTP协议,整个实验获得了成功。然而伊利诺伊大学香槟分校也许仅出于学术研究目的,在实验成功后开发工作就没有继续下去,研究小组也随之解散,但他们将这两个软件开源,其代码可以自由下载修改并发布。
  此时的互联网对HTTP服务器软件的需求越来越大,公开源代码的NCSA HTTPd成了进一步发展的极好起点。很多研究者不断地给它添加功能、增加代码,并对不断出现的Bug打补丁。但因为缺乏规划和管理,出现了越来越多的重复劳动,随之而来的则是越多的补丁带来越多的Bug。1995年2月,为解决这种单打独斗的现象,8名志同道合的开发者决定成立一个小组,一起重写整个NCSA HTTPd程序,发布一个基于NCSA HTTPd的可靠的服务器软件。开发工作完成后,他们将软件命名为Apache,全称Apache HTTP Server。Apache本是美洲原住民印第安人一支部落的名字,这个部落因为高超的作战策略和无穷的耐性而闻名,同时也是最后一个屈服于美国政府的民族。开发小组以此寓意软件高效、可靠,同时表达了大公司迟早会参与竞争并“教化”这块最早的开源网络之地的担心。另外,因为整个软件是在NCSA HTTPd基础上打了很多补丁程序,他们也戏称它是“A Patchy Web Server”,意为一个打了很多补丁的Web服务器软件。“A Patchy”与Apache谐音,故以Apache命名一语双关。
  Apache HTTP Server发布后,由于其具有坚实的稳定性、异常丰富的功能和灵活的可扩展性,得到了极大的成功。1999年6月,为有效支持Apache HTTP Server以及相关软件的发展,Apache开发小组成员们成立了一个非盈利性的Apache软件基金会(Apache Software Foundation)。大家对Apache这个名字的熟悉大概也是因为这个基金会,它支持开发了诸多享誉全球的开源软件,这些软件的名字前都会加上Apache,其中就包括Apache Tomcat。
  Tomcat的这个单词的意思是“公猫”,因为它的开发者姆斯·邓肯·戴维森希望用一种能够自己照顾自己的动物代表这个软件,于是命名为tomcat,它的Logo兼吉祥物也被设计成了一只公猫形象。Tomcat是1999年Apache 软件基金会与Sun等其他公司一起合作的Jakarta(雅加达)项目中的一个子项目,作为服务器的容器支持基于Java语言编写的程序在服务器上运行,这样的程序被称为Servlet,因为它是运行在“Server”上的“Applet”。理论上讲这样一个容器并不是一个完整的服务器软件,因为它只能运行Java程序而不能生成HTML页面数据,也不能处理并发事务。但它集成了HTTP服务器程序,也就可以单独作为一个服务器软件来部署以处理HTTP请求,但tomcat核心技术并不在于此,所以除了用于开发过程中的调试以及那些对速度和事务处理只有很小要求的用户,很少会将Tomcat单独作为Web服务器。通常开发者会让tomcat与其他对Web服务器一起协同工作,比如Apache HTTP Server。Apache HTTP Server负责接受所有来自客户端的HTTP请求,然后将Servlets和JSP的请求转发给Tomcat来处理。Tomcat完成处理后,将响应传回给Apache,最后Apache将响应返回给客户端。于是在tomcat中运行Java程序也就是Servlet的那个模块因为体现了tomcat最核心特点而引起了大家的重视,而这个模块的名字叫做Catalina。
  Catalina是美国西海岸靠近洛杉矶22英里的一个小岛,因为其风景秀丽而著名。Servlet运行模块的最早开发者Craig McClanahan因为喜欢Catalina岛故以Catalina命名他所开这个模块,尽管他从来也没有去过那里。另外在开发的早期阶段,Tomcat是被搭建在一个叫Avalon的服务器框架上,而Avalon则是Catalina岛上的一个小镇的名字,于是想一个与小镇名字相关联的单词也是自然而然。还有一个原因来自于Craig McClanahan养的猫,他养的猫在他写程序的时候喜欢在电脑周围闲逛。但这与Catalina有什么关系呢?我想可能是Catalina岛是个悠闲散步的好地方,猫的闲逛让Craig McClanahan想起了那里。
  评:老外取名好随便,这种取名尽量取能让人理解的名字嘛,不过估计是玩编程玩到一定境界的大佬们的情怀吧,没办法,只能跟着学咯。


Tomcat目录结构

  • bin
      存放的是可执行的文件(一些启动关闭服务器等操作的命令),.bat/exe是Windows下可执行脚本文件,sh文件是Linux/Unix下可执行的脚本文件。

    • catalina.bat、catalina.sh
         用于启动和关闭tomcat服务器的脚本,是tomcat中最关键的脚本。
    • setclasspath.bat、setclasspath.sh
         设置classpath的脚本,在catalin.bat脚本中调用,可以设置java_home,jre_home等。
    • digest.bat、digest.sh
         是用指定的算法加密密码的脚本。
    • daemon.bat、daemon.sh
         tomcat以守护进程方式运行时的启动,停止脚本。
    • configtest.bat、configtest.sh
         tomcat检查配置文件语法是否正确的脚本。
    • startup.bat、startup.sh、shutdown.bat、shutdown.sh
         tomcat服务器的启动、停止脚本。
    • version.bat、version.sh
         查看tomcat以及JVM的版本信息脚本。
    • bootstrap.jar
         tomcat启动时所依赖的一个类。
    • tomcat-juli.jar
        juli=java.util.logging,Apache Tomcat由一个自己的实现了java.util.logging多个关键元素的实现。这个实现被称为“JULI”。实现的核心组件是定制化的LogManager,可以获取运行在Tomcat中的不同web应用(以及不同的class loader)。他支持为应用配置单独的日志配置。
    • commons-daemon.jar
        jsvc工具所依赖的java类。
    • commons-daemon-native.tar.gz
         jsvc工具。此工具可以使tomcat以守护进程方式运行。
    • tomcat-native.tar.gz
        使tomcat可以使用apache的apr运行库,以增强tomcat的性能,需单独编译安装。
    • catalina-tasks.xml
      定义tomcat载入的库文件,类文件。
  • conf
      存放Tomcat的各种配置文件。

    • web.xml
        配置所有Web应用信息(就是各个Web项目的默认信息)。
    • server.xml
        配置了服务器的相关信息。是一个四层的结构,Server->Service->Engine->Host->Context。
    • context.xml
        “存放了所有Web应用程序“,里面可以配置多个context,一个context代表一个应用程序。
    • tomcat-users.xml
         配置用户、角色等。
    • catalin.properties
         catalina配置文件主要用于配置tomcat的类加载设置、不需要扫描的类设置、字符缓存设置。
    • logging.properties
        Tomcat日志的配置文件。
    • catalina.policy
        catalina策略文件。
    • Catalina
         可在此目录下设置默认加载的项目。具体部署方式可以参考http://qsfwy.iteye.com/blog/466461
  • lib
      文件夹下面放的是tomcat提供的jar包,资源库文件。tomcat运行需要。
  • logs
      tomcat日志文件存放的默认目录。
  • temp
      tomcat存放临时文件的目录。
  • webapps
      放你的Web应用的地方(所有的Web应用都放在这个目录下),这个默认目录是可以在server.xml中进行配置的。在你的应用中可以放所有与Web资源相关的文件或文件夹,例如html、css、js源码,以及其它多媒体资源等
    • docs
        tomcat的相关文档。
    • examples
        tomcat自带的一个独立的web应用程序例子。一个简单的实现聊天功能的例子,想玩玩的可以看这篇博文http://blog.csdn.net/fumier/article/details/49278673
      • jsp
          应用程序所用到的相关资源
      • servlets
          应用程序所用到的相关资源
      • WEB-INF
          用于存放当前应用程序的私有资源。也就是不能直接通过浏览器的地址栏直接访问,需要要通过服务器访问,我们可以间接的去访问。此文件夹是非必须的,但是当有动态资源的时候,此文件件必须加上。
        • classes
            存放当前应用所需的class文件
        • lib
            存放当前应用程序依赖的jar包
        • web.xml
            当前应用程序的部署描述符文件,定义应用程序所要加载的serverlet类,以及该程序是如何部署的。
      • websocket
          WebSocket 是一种双向通信协议,在这里作用应该是实现这个例子的对话功能。具体内容我也还没查到相关的资料,如果大家有什么需要更正的可以在下方留言,谢谢啦。
      • websocket-deprecated
          这个文件加也应该是为了聊天功能服务的。
      • index.html
        tomcat自带的一个独立的web应用程序例子。
    • host-manager
      tomcat的主机管理应用程序。
    • manager
      tomcat的管理应用程序。
    • ROOT
      指tomcat的应用程序的根,如果应用程序部署在ROOT中,则可直接通过http://ip:port 访问到。
  • work
    存放jsp编译后的class文件。
  • LICENSE
    顾名思义就是许可证,里面记录了tomcat的一些条款等等。
  • NOTICE
    记录了tomcat的新的通知,公告。
  • RELEASE-NOTES
    记录的是发行版本的说明,一些捆绑的API,新特性等等。
  • RUNNING.txt
    记录了tomcat的运行环境以及怎样配置参数,变量,启动等等。

Tomcat的应用部署方式

第一种:将应用程序(工程)直接拷贝到webapps目录下,然后启动服务器,完成部署!。

第二种:打war包,然后先启动服务器,最后将war包拷贝到webapps目录下完成部署!。

1.如图所示,准备好要打包的应用(工程)!
  • 在这里,examples就是我们要打包的应用。

1.我们现在要吧examples这个应用(工程)打成war包

2.如图所示,用命令对应用(examples)进行打包!
  • 打包用的命令就是jar+空格+cvf+空格+(打包后的war包包名)+空格+(要进行打包的应用文件夹/*) 。
  • myapp.war就是打包后的war包包名。
  • examples/*就是把examples下所有的资源都打包。
  • 在打包之前要先进入需要打包的工程目录下(可以直接在文件目录下按shift+右键+点击“在此处打开命令窗口(W)”或者是用cd命令进入)。

2.用jar cvf 命令打war包

3.如图所示,war包打包完成!

3.打包完成

4.如图所示,myapp.war就是我们打包好的example的war包了!

4.打包完成后的文件

5.如图所示,用startup.bat脚本启动tomcat服务器!
  • 启动命令如图所示。
  • 在启动之前记得要进入到tomcat的bin目录下。

5.启动tomcat

6.如图所示,tomcat服务器启动完成!

6.tomcat启动完成

7.如图所示,我们将打包好的war包拷贝到tomcat的webapps目录下!

7.将war包拷贝到tomcat的webapps目录下

8.如图所示,tomcat自动解压了此war包,到此就完成了应用程序的部署了!

8.tomcat自动解压war包,完成部署!

注意:

1.如图所示,应用部署完成后不要将war包删除(服务器在运行的时候),war删除后应用也会自动删除!。
删除war包前:
删除war包前
删除war包后:
删除war包后

2.服务器关闭的时候删除war包没问题,应用程序依然还在。


Tomcat常见问题

Catalina是个什么鬼?

答:Catalina是一个包,里面包含了很多与服务器相关的类、是一个tomcat所有组件的顶层容器,主要是作为servlet和JSP的容器。
Catalina Package


Tomcat体系架构

转自:http://www.jianshu.com/p/62ec977996df,自己做了一些修改。

Server:

  Server表示整个的Catalina Servlet容器。Tomcat提供了Server接口的一个默认实现,这通常不需要用户自己去实现。在Server容器中,可以包含一个或多个Service组件。

Service:

  Service是存活在Server内部的中间组件,它由一个或者多个Connector组成以及一个Engine,负责处理所有Connector所获得的客户请求。Service也很少由用户定制,Tomcat提供了Service接口的默认实现,而这种实现既简单又能满足应用。

Connector:

  连接器(Connector)处理与客户端的通信,它负责接收客户请求,以及向客户返回响应结果。
  Tomcat有两个典型的Connector,一个直接侦听来自browser的http请求,一个侦听来自其它WebServer的请求。
  Coyote Http/1.1 Connector 在端口8080处侦听来自客户browser的http请求。
  Coyote JK2 Connector 在端口8009处侦听来自其它WebServer(Apache)的servlet/jsp代理请求。

Engine:

  在Tomcat中,每个Service只能包含一个Servlet引擎(Engine)。引擎表示一个特定的Service的请求处理流水线。作为一个Service可以有多个连接器,引擎从连接器接收和处理所有的请求,将响应返回给适合的连接器,通过连接器传输给用户。用户允许通过实现Engine接口提供自定义的引擎,但通常不需要这么做。
  Engine下可以配置多个虚拟主机Virtual Host,每个虚拟主机都有一个域名。当Engine获得一个请求时,它把此请求匹配到某个Host上,然后把该请求交给该Host来处理。
  Engine有一个默认虚拟主机,当请求无法匹配到任何一个Host上的时候,将交给该默认Host来处理。

Host:

  Host代表一个Virtual Host(虚拟主机),,一个引擎可以包含多个Host用户通常不需要创建自定义的Host,因为Tomcat给出的Host接口的实现(类StandardHost)提供了重要的附加功能。
  每个虚拟主机和某个网络域名Domain Name相匹配,每个虚拟主机下都可以部署(deploy)一个或者多个Web App,每个Web App对应于一个Context。
  当Host获得一个请求时,有一个Context path将把该请求匹配到某个Context上,然后把该请求交给该Context来处理匹配的方法是“最长匹配”,所以一个path==””的Context将成为该Host的默认Context所有无法和其它Context的路径名匹配的请求都将最终和该默认Context匹配。

Context:

  一个Context对应于一个Web Application,一个WebApplication由一个或者多个Servlet组成
Context在创建的时候将根据配置文件 CATALINAHOME/conf/web.xml WEBAPP_HOME/WEB-INF/web.xml载入Servlet类,当Context获得请求时,将在自己的映射表(mapping table)中寻找相匹配的Servlet类。如果找到,则执行该类,获得请求的回应,并返回。
Tomcat运行流程

假设来自客户的请求为:http://localhost:8080/test/index.jsp

请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得

Connector把该请求交给它所在的Service的Engine来处理,并等待Engine的回应

Engine获得请求localhost:8080/test/index.jsp,匹配它所有虚拟主机Host

Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机)

localhost Host获得请求/test/index.jsp,匹配它所拥有的所有Context

Host匹配到路径为/test的Context(如果匹配不到就把该请求交给路径名为”“的Context去处理)

path=”/test”的Context获得请求/index.jsp,在它的mapping table中寻找对应的servlet

Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类

构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法

Context把执行完了之后的HttpServletResponse对象返回给Host

Host把HttpServletResponse对象返回给Engine

Engine把HttpServletResponse对象返回给Connector

Connector把HttpServletResponse对象返回给客户browser


Tomcat的配置—未完待续

注意:
  • Tomcat容器在启动时会读取配置文件中的所有信息,在对Tomcat配置文件进行修改后得重新启动Tomcat配置文件中的内容才会生效。
  • Tomcat的主要版本是6.x和7.x(也就是Tomcat7和Tomcat6),在这两个版本之间一些问题的解决方式可能是不同的,所以大家在查找资料的时候一定要注意版本的问题,6.x及更早之前的版本就更不用说了。
  • Tomcat常见问题可以看这里https://wiki.apache.org/tomcat/FAQ。如果你英语跟我一样差得不要不要的可以用google浏览器,会自动帮你翻译,但是翻译出来的结果可能不会太好理解,但是总比纯英文的要好吧。
  • 参考的资料:
    http://www.cnblogs.com/chinafine/archive/2010/09/02/1815980.htmlWeb.xml - - Web.xml配置详解

server.xml配置


<Server port="8005" shutdown="SHUTDOWN">
<!-- 
    Server:表示一个服务器!
    port:服务器的端口号!
    shutdown:关闭服务器的命令!
 -->
 <!--
 Listener:表示监听器 !在服务器启动的时候已经加载到内存了,监听各种“动作”
  -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JasperListener" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
  <GlobalNamingResources>
  <!-- 
  GlobalNamingResources:全局的命名资源,暂时不管,用到的时候在查资料吧,感觉基本不怎么用到。
   -->
    <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>
  <Service name="Catalina">
  <!-- 
  Service:表示一个服务
  name:这个服务的名字
   -->
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
  <!-- 
  Connector:表示一个连接器!
  port:Connector监听的端口!
  protocol:设置处理请求的协议!
  connectionTimeout:连接超时的时间!
  redirectPort:如果Connector的配置是支持非SSL的请求,当一个SSL请求到来时,服务器会自动的将请求重定位到redirectPor!
  ~~具体内容可以看~~:http://write.blog.csdn.net/mdeditor#!postId=73692658 和 http://blog.csdn.net/shipeng22022/article/details/38316959
   -->
   <Engine name="Catalina" defaultHost="localhost">
   <!-- 
   Engine:代表一个引擎!
   name:引擎的名字!
   defaultHost:默认主机!
    -->
      <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      <!-- 
      Realm:认证方式!
      className:
      resourceName:
       -->
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
      <!-- 
      Host:代表一个主机!
      name:主机名!
      appBase:此主机的应用程序的根目录!
      unpackWAR:是否自动解压War包!
      autoDeploy:是否支持自动部署!
       -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log." suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>
    </Engine>
  </Service>
</Server>

tomcat-users.xml配置

<tomcat-users>
    <!-- role表示角色类型 -->
    <role rolename="tomcat"/>
    <role rolename="role1"/>
    <role rolename="角色类型名"/>
    <!-- user表示用户 -->
    <user username="tomcat" password="tomcat" roles="tomcat"/>
    <user username="both" password="tomcat" roles="tomcat,role1"/>
    <user username="用户名" password="密码" roles="角色类型"/>
</tomcat-users>

web.xml配置

    <!-- 配置一个servlet -->
    <servlet>
        <servlet-name>servelet名称</servlet-name>
        <servlet-class>此servlet对应的文件路径</servlet-class>
        <!-- servlet参数,利用init-param元素向servlet提供初始化参数 -->
        <init-param>
            <param-name>参数名</param-name>
            <param-value>参数值</param-value>
        </init-param>
        <!-- 
        load-on-startup标记容器是否在启动的时候就加载这个servlet。当值为0或者大于0时,表示容器在应用启动时就加载这个servlet,当是一个负数时或者没有指定时,则指示容器在该servlet被选择时才加载。正数的值越小,启动该servlet的优先级越高。
        -->
        <load-on-startup>3</load-on-startup>
    </servlet>
    <!-- servlet映射 -->
    <servlet-mapping>
        <servlet-name>servelet名称</servlet-name>
        <url-pattern>表示在浏览器中需要输入的url</url-pattern>
    </servlet-mapping>

    <!-- 会话的配置 -->
    <session-config><session-timeout>会话超时时间,单位是分钟</session-timeout></session-config>

    <!-- MIME扩展类型的映射 -->
    <mime-mapping><extension>扩展名</extension><mime-type>为此种扩展名分配的MIME类型</mime-type></mime-mapping>
<filter><>
    <!-- 欢迎界面的配置 -->
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

一些配置的应用

1.虚拟应用

就是将你的应用放在任何路径而不用非要放到webapps目录下。
该怎么做呢?
在server.xml目录下找到标签,在它里面加入一个标签,一个Context标签就代表一个应用。具体请看下图。
虚拟应用
path:代表虚拟路径,也就是在浏览器地址栏输入的路径。”/”必须有,它代表了服务器的根路径,也就是“http://localhost:8080”这样的东西。
docBase:物理路径,也就是应用在服务器的实际路径。
缺点:配置完后必须重启服务器才能生效。
虚拟应用还可以在conf\Catalina\localhost目录下配置,因为这个虚拟应用也不是很重要,就不在赘述了,想了解的可以自己查一下资料或者看官网文档。

2.欢迎(默认)页面

就是当用户在地址栏写入根路径(如“http://localhost:8080/”),而没有写具体应用的时候访问到的页面。具体请看下图。
欢迎界面配置
<welcome-file-list>:欢迎文件列表,地址栏当只写根路径时,服务器会自动去匹配。
<welcome-file>:欢迎文件,你想要让用户访问到的欢迎页面。

3.多个虚拟主机的配置

http://blog.csdn.net/u014799292/article/details/50550862


PS

这篇博客笔记是参考Tomcat的介绍文档和一些其他大神的博客内容写的,如果有什么看不懂的可以自行查看Tomcat官网提供的介绍文档:http://tomcat.apache.org/tomcat-7.0-doc/introduction.html#Introduction

本文所参考的博文:
http://blog.csdn.net/wutongxu/article/details/20399571 - - tomcatbin目录下的脚本
https://my.oschina.net/leamon/blog/209809 - - tomcat文件详解
http://grass51.blog.51cto.com/4356355/1123400 - - 构建一机多实例tomcat集群
http://grass51.blog.51cto.com/4356355/860953 - - linux上安装Java虚拟机–jdk,并且结合Tomcat,提供JSP架构的web服务器,并且为以后Tomcat连接Apache时的快速通信安装tomcat-native,最后为tomcat提供连接Mysql的jar文件,mysql-connector-java,最后配置Tomcat的虚拟主机应用,提供一个基于JSP开发的SNS网站JavaCenterHome

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值