基于Ubuntu的服務(wù)器搭建教程(Tomcat + Servlet組合)

最近有需求要搭建一個(gè)服務(wù)器赖舟,該服務(wù)器可以接收J(rèn)son并返回Json。再此之前從未接觸過服務(wù)器搭建的我夸楣,開始了瞎折騰宾抓。

一、瞎折騰第一步

安裝Ubuntu系統(tǒng)豫喧。這一步不需要多做解釋吧石洗。我安裝的系統(tǒng)是Ubuntu 18.04。如果不會(huì)安裝Ubuntu系統(tǒng)紧显,可自行查閱資料(其實(shí)就是去百度)讲衫。

二、瞎折騰第二步

安裝Tomcat鸟妙。
這一步折騰了我4個(gè)小時(shí)焦人!

1.下載Tomcat

因?yàn)閷?duì)于Ubuntu系統(tǒng)不熟悉挥吵,我是通過Windows下載之后,復(fù)制到Ubuntu中的花椭。版本是9.0.11忽匈。
下載鏈接:(此鏈接為2018-08-30記錄,可能會(huì)失效矿辽,如果失效請(qǐng)到tomcat官網(wǎng)下載新的版本)
Apache Tomcat 9.0.11

2.解壓Tomcat

下載后的文件名為apache-tomcat-9.0.11.tar.gz丹允,復(fù)制到的文件路徑在《/home/"Ubuntu當(dāng)前登陸用戶的用戶名"》下。使用《Ctrl + Alt + T》快捷鍵打開《Terminal》命令輸入終端袋倔。進(jìn)入終端時(shí)雕蔽,默認(rèn)的當(dāng)前路徑就是上述路徑。輸入指令進(jìn)行解壓宾娜。

tar -zxvf apache-tomcat-9.0.11.tar.gz

解壓后批狐,會(huì)在當(dāng)前目錄多出一個(gè)叫做 apache-tomcat-9.0.11 的文件夾

3.下載JDK

因?yàn)槭窃诰W(wǎng)上找的教程,所以沒仔細(xì)看前塔,到這一步之后才發(fā)現(xiàn)Tomcat需要安裝JDK才能正常使用嚣艇,所以又下載了JDK。(jdk 1.8.0_181)
下載鏈接:(此鏈接為2018-08-30記錄华弓,可能會(huì)失效食零,如果失效請(qǐng)到JDK官網(wǎng)下載新的版本)
jdk 1.8.0_181

4.解壓JDK

把jdk下載之后同樣放到跟上述Tomcat文件的解壓路徑,輸入命令開始解壓寂屏。下載后的jdk文件名為:jdk-8u181-linux-x64.tar.gz

tar -zxvf jdk-8u181-linux-x64.tar.gz

5.配置環(huán)境變量

跟Windows一樣贰谣,安裝好java還要配置環(huán)境變量,同時(shí)Tomcat也要配置環(huán)境變量迁霎。所以我就一起說(shuō)了吱抚。
在終端中輸入指令:

sudo vim /etc/profile

在打開的文件的最后加入環(huán)境變量配置:
將下方的"Ubuntu當(dāng)前登陸用戶的用戶名"替換成你系統(tǒng)上真實(shí)的用戶名。
這里我在配置java環(huán)境變量的同時(shí)也配置了tomcat的環(huán)境變量

#set jdk environment(配置JDK環(huán)境變量)
export JAVA_HOME=/home/"Ubuntu當(dāng)前登陸用戶的用戶名"/jdk1.8.0_181
export CLASSPATH=.:$JAVA_HOME/lib
#set tomcat environment(配置tomcat 環(huán)境變量)
export CATALINA_HOME=/home/"Ubuntu當(dāng)前登陸用戶的用戶名"/apache-tomcat-9.0.11
export PATH=$JAVA_HOME/bin:$CATALINA_HOME:$PATH

保存并退出編輯器欧引。在這里有一點(diǎn)一定要注意频伤,每一行最后一定不能有空格,等號(hào)的兩邊已不能有空格芝此,唯一有空格的地方只有export后面。
立刻使環(huán)境變量生效

source /etc/profile

測(cè)試java環(huán)境

java -version

如果有

java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

顯示因痛,則證明Java環(huán)境變量成功配置婚苹。

6.啟動(dòng)tomcat

回到終端初始目錄使用指令《cd ~》。注意:這里的波浪線也是命令的一部分,表示終端初始目錄

cd ~

進(jìn)入tomcat目錄

cd apache-tomcat-9.0.11

運(yùn)行tomcat目錄下鸵膏,bin文件夾中的startup.sh腳本文件膊升,啟動(dòng)tomcat

sudo ./bin/startup.sh

為了方便之后對(duì)tomcat的更改,需要先設(shè)置tomcat文件夾的權(quán)限

sudo chmod -R 775 ./*

輸入ifconfig查看當(dāng)前系統(tǒng)的IP地址

ifconfig
image.png

可以看到我當(dāng)前系統(tǒng)的IP地址是192.168.0.61谭企,打開局域網(wǎng)中的Windows電腦的瀏覽器廓译,在網(wǎng)址欄輸入192.168.0.61:8080,如果有網(wǎng)頁(yè)呈現(xiàn)评肆,說(shuō)明tomcat安裝成功。


image.png

因?yàn)槟J(rèn)使用的是http協(xié)議非区,谷歌瀏覽器提示不安全瓜挽。不過完全不用管這個(gè)問題。
下面才是重頭戲征绸。

三久橙、Tomcat的基本配置

1.進(jìn)入tomcat的配置文件的目錄

cd ~/apache-tomcat-9.0.11/conf

打開服務(wù)器配置文件

sudo vim server.xml

找到如下內(nèi)容所在行

 <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
    -->
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <!-- A "Connector" using the shared thread pool-->
    <!--
    <Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    -->

最中間的”Connector“后面的port等號(hào)后的值就是端口,如果想要更改端口管怠,在此處更改即可淆衷。

2.基本web服務(wù)器配置及使用。

這一步講的是僅僅將tomcat環(huán)境作為web服務(wù)器的使用方式渤弛。在tomcat中祝拯,默認(rèn)的網(wǎng)絡(luò)請(qǐng)求根目錄為webapps。所以可以在webapps目錄下建一個(gè)我們自己的目錄來(lái)存放自己的網(wǎng)頁(yè)她肯。

進(jìn)入webapps目錄

cd ~/apache-tomcat-9.0.11/webapps

創(chuàng)建自己的文件夾佳头,用于存放自己的網(wǎng)頁(yè)。

sudo mkdir myweb

上面的指令創(chuàng)建了一個(gè)叫做myweb的文件夾辕宏,進(jìn)入該文件夾畜晰,并創(chuàng)建一個(gè)html文件。

cd myweb
sudo vim index.html

接下來(lái)就是編輯該文件瑞筐,并寫入相關(guān)的html內(nèi)容凄鼻,使其能被解析并顯示出網(wǎng)頁(yè)來(lái)。我這里用于演示聚假,就只寫了個(gè)簡(jiǎn)單的HTML5網(wǎng)頁(yè)块蚌。

<html lang="zh-CN">
        <head>
                <meta charset="UTF-8"/>
                <title>成功</title>
        </head>
        <body>
                <h1>這是我的網(wǎng)頁(yè)</h1>
        </body>
</html>

保存之后,在瀏覽器中輸入192.168.0.61:8080/myweb/即可成功顯示網(wǎng)頁(yè)膘格。


image.png

如果只是進(jìn)行web服務(wù)器搭建峭范,到此處就已經(jīng)結(jié)束了。
通過這種方法瘪贱,就能建立自己想要進(jìn)行的網(wǎng)頁(yè)了纱控。tomcat不僅僅支持html文件,還支持htm及jsp文件菜秦。

如果還想進(jìn)行Servlet的聯(lián)合配置以進(jìn)行更多處理甜害,請(qǐng)繼續(xù)往下看。

四球昨、Servlet的配置

通過上述已經(jīng)知道tomcat的根目錄是webapps尔店。所以重新再新建一個(gè)目錄用于使用Servlet。

cd ~/apache-tomcat-9.0.11/webapps
sudo mkdir myservlet

進(jìn)入剛剛創(chuàng)建的目錄

cd myservlet

根據(jù)我?guī)讉€(gè)小時(shí)的研究以及官方文檔的說(shuō)明,使用Servlet必須要新建一個(gè)文件夾"WEB-INF"嚣州,所以鲫售,進(jìn)入這個(gè)目錄后,新建該目錄并進(jìn)入該目錄(這里的-是英文的短橫線该肴,也叫中劃線)

sudo mkdir WEB-INF
cd WEB-INF

在目錄下新建兩個(gè)必須的文件夾

sudo mkdir classes
sudo mkdir lib

classes文件夾用來(lái)存放java文件(主要是servlet的java文件以及在servlet中進(jìn)行的操作需要用到的其他java文件)情竹。
lib文件夾是用來(lái)存放java代碼中用到的第三方庫(kù)jar包之類的。
復(fù)制webapp/ROOT/WEB_INF目錄下的web.xml文件到當(dāng)前目錄

cp ../../ROOT/WEB-INF/web.xml ./

web.xml是用于配置Servlet的關(guān)鍵文件沙庐,如果沒有這個(gè)文件鲤妥,則無(wú)法使用Servlet。而復(fù)制webapp/ROOT/WEB_INF目錄下的web.xml文件的原因也很簡(jiǎn)單拱雏,這個(gè)目錄下的web.xml沒有配置任何Servlet數(shù)據(jù)參數(shù)棉安,但又有標(biāo)準(zhǔn)框架已經(jīng)被搭建好了砸狞,非常方便自己進(jìn)行Servlet的添加配置奏赘。

文件目錄已經(jīng)創(chuàng)建好了衣厘,剩下的就是Servlet的編寫與配置了吞彤。
以下是我的Servlet的java源碼的文件內(nèi)容。

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 用于測(cè)試的HttpServlet 
 */

/**
 * @author 噬神蒼龍
 *
 */
public class TestMyHttpServlet extends HttpServlet {

    /* (non-Javadoc)
     * @see javax.servlet.http.HttpServlet#doDelete(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doDelete...");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("<html><head><title>Hello</title></head><body><h1>request by Delete</h1></body></html>");
        out.flush();
        out.close();
    }

    /* (non-Javadoc)
     * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet...");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("<html><head><title>Hello</title></head><body><h1>request by Get</h1></body></html>");
        out.flush();
        out.close();
    }

    /* (non-Javadoc)
     * @see javax.servlet.http.HttpServlet#doHead(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doHead...");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("<html><head><title>Hello</title></head><body><h1>request by Head</h1></body></html>");
        out.flush();
        out.close();
    }

    /* (non-Javadoc)
     * @see javax.servlet.http.HttpServlet#doOptions(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doOptions...");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("<html><head><title>Hello</title></head><body><h1>request by Options</h1></body></html>");
        out.flush();
        out.close();
    }

    /* (non-Javadoc)
     * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doPost...");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("<html><head><title>Hello</title></head><body><h1>request by Post</h1></body></html>");
        out.flush();
        out.close();
    }

    /* (non-Javadoc)
     * @see javax.servlet.http.HttpServlet#doPut(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doPut...");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("<html><head><title>Hello</title></head><body><h1>request by Put</h1></body></html>");
        out.flush();
        out.close();
    }

    /* (non-Javadoc)
     * @see javax.servlet.http.HttpServlet#doTrace(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doTrace...");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("<html><head><title>Hello</title></head><body><h1>request by Trace</h1></body></html>");
        out.flush();
        out.close();
    }

    /* (non-Javadoc)
     * @see javax.servlet.http.HttpServlet#getLastModified(javax.servlet.http.HttpServletRequest)
     */
    @Override
    protected long getLastModified(HttpServletRequest req) {
        System.out.println("getLastModified...");
        return super.getLastModified(req);
    }

    /* (non-Javadoc)
     * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("service(HttpServletRequest req, HttpServletResponse resp)...");
        super.service(req, resp);
    }

    /* (non-Javadoc)
     * @see javax.servlet.http.HttpServlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
     */
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        System.out.println("service(ServletRequest req, ServletResponse res)...");
        super.service(req, res);
    }
}

將這個(gè)java文件編譯生成class文件旷痕,并將其復(fù)制到剛才創(chuàng)建的classes目錄下并淋。
注意了醋安,這里不是復(fù)制java文件刁憋,而是復(fù)制其編譯后的class文件滥嘴。

sudo cp ~/TestMyHttpServlet.class ~/apache-tomcat-9.0.11/webapps/myservlet/WEB_INF/classes/

編輯WEB-INF 目錄中的web.xml文件,將servlet配置到tomcat

sudo vim web.xml

在如下內(nèi)容

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
  version="4.0"
  metadata-complete="true">

  <display-name>Welcome to Tomcat</display-name>
  <description>
     Welcome to Tomcat
  </description>
  //在此處加入下方內(nèi)容
</web-app>
  <servlet>
      <servlet-name>test</servlet-name>
      <servlet-class>TestMyHttpServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>test</servlet-name>
      <url-pattern>/test</url-pattern>
  </servlet-mapping>

配置數(shù)據(jù)解釋:

  <servlet>
      <servlet-name>test</servlet-name>
      <servlet-class>TestMyHttpServlet</servlet-class>
  </servlet>

在這里表示配置一個(gè)servlet至耻,name中的文本可以隨便填主要用于之后引用若皱,class中的名字要跟java文件名一致。

<servlet-mapping>
      <servlet-name>test</servlet-name>
      <url-pattern>/test</url-pattern>
  </servlet-mapping>

在這里表示將一個(gè)servlet加入所有的servlet表中尘颓,name和上方配置的servlet要一致走触。也就是將之前配置為test的Servlet引用到這里進(jìn)行請(qǐng)求處理。pattern中包含的文本表示在這個(gè)Servlet要監(jiān)聽的請(qǐng)求路徑疤苹。
按上方的內(nèi)容配置完成后互广,Servlet的訪問路徑就是:

192.168.0.61:8080/myservlet/test

第一個(gè)/myservlet是我們?cè)趙ebapps下新建的文件夾名,第二個(gè)/test就是配置的時(shí)候分配的pattern路徑卧土。
如果想監(jiān)聽/myservlet下所有的請(qǐng)求路徑惫皱, <url-pattern>中只需要寫一個(gè)"/"即可。

如下圖所示:

<servlet>
      <servlet-name>test</servlet-name>
      <servlet-class>TestMyHttpServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>test</servlet-name>
      <url-pattern>/</url-pattern>
  </servlet-mapping>

完成后最終效果如圖:


image.png

從此之后尤莺,所有服務(wù)器的請(qǐng)求處理都可以先在servlet的Java文件中寫好逸吵,編譯成class之后,把class文件復(fù)制過來(lái)重新替換,新的功能就可以使用了缝裁。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子捷绑,更是在濱河造成了極大的恐慌韩脑,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粹污,死亡現(xiàn)場(chǎng)離奇詭異段多,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)壮吩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門进苍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人鸭叙,你說(shuō)我怎么就攤上這事觉啊。” “怎么了沈贝?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵杠人,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我宋下,道長(zhǎng)嗡善,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任学歧,我火速辦了婚禮罩引,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘枝笨。我一直安慰自己袁铐,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布伺帘。 她就那樣靜靜地躺著昭躺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪伪嫁。 梳的紋絲不亂的頭發(fā)上领炫,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音张咳,去河邊找鬼帝洪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛脚猾,可吹牛的內(nèi)容都是我干的葱峡。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼龙助,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼砰奕!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤军援,失蹤者是張志新(化名)和其女友劉穎仅淑,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體胸哥,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涯竟,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了空厌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片庐船。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖嘲更,靈堂內(nèi)的尸體忽然破棺而出筐钟,到底是詐尸還是另有隱情,我是刑警寧澤哮内,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布盗棵,位于F島的核電站,受9級(jí)特大地震影響北发,放射性物質(zhì)發(fā)生泄漏纹因。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一琳拨、第九天 我趴在偏房一處隱蔽的房頂上張望瞭恰。 院中可真熱鬧,春花似錦狱庇、人聲如沸惊畏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)颜启。三九已至,卻和暖如春浪讳,著一層夾襖步出監(jiān)牢的瞬間缰盏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工淹遵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留口猜,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓透揣,卻偏偏與公主長(zhǎng)得像济炎,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子辐真,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345