文档章节

Maven Archetypes Part 3: 怎样构建一个多模块工程?

石穿
 石穿
发布于 2017/07/25 17:12
字数 2234
阅读 23
收藏 0
点赞 1
评论 0

原文地址

源码传送门

###欢迎回来 如果你没有阅读前面章节,或对Maven archetypes不熟悉,你会看不懂,XD。

到目前为止,我们已经创建了一个archetype,可以生成能打包为jar且会say Hello word的工程,并且包含了一个单元测试类。另一个场景是你想要创建一个多模块的工程。举个栗子,你想要一个工程,包含一个model和一个webapp模块,或者一个client一个server模块能传输一个共有的类型对象。

为达到这个目的,并不会花费你太多精力。很多的工作我们在之前的例子中已经完成了。

###重温前情,然后添加一些新东西 让我们从上一节所创建的archetype工程结构开始:

$ tree
.
|____pom.xml
|____src
| |____main
| | |____resources
| | | |____archetype-resources
| | | | |____pom.xml
| | | | |____src
| | | | | |____main
| | | | | | |____java
| | | | | | | |______packageInPathFormat__
| | | | | | | | |____App.java
| | | | | |____test
| | | | | | |____java
| | | | | | | |______packageInPathFormat__
| | | | | | | | |____AppTest.java
| | | |____META-INF
| | | | |____maven
| | | | | |____archetype-metadata.xml

首先,我们需要将之前能够打包成jar的项目移动到下一层目录。我们的多模块项目的顶层目录装父项目,父项目提供一个pom。

$ mkdir src/main/resources/archetype-resources/__artifactId__-model
$ mv src/main/resources/archetype-resources/src src/main/resources/archetype-resources/__artifactId__-model/
$ mv src/main/resources/archetype-resources/pom.xml src/main/resources/archetype-resources/__artifactId__-model/

你应该注意到了__artifactId__-model。如果你记得第二节的内容,如果使用双下划线在参数的前面和后面,Maven将会将这个参数名替换成对应的参数内容。根据上面的目录结构,如果我们从archetype生成的项目的artifact id为sample-project,这个目录将创建为sample-project-model

###创建和重构pom文件 现在我们将根目录的内容移动到子目录去了,在根目录里还没有东西。我们需要创建一个pom,作为多模块项目的parent。现在新建一个文件src/main/resources/archetype-resources/pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  
  <modelVersion>4.0.0</modelVersion>
  
  <groupId>${groupId}</groupId>
  <artifactId>${artifactId}</artifactId>
  <version>${version}</version>
  <packaging>pom</packaging>
  <name>${artifactId}</name>
 
  <modules>
    <module>${artifactId}-model</module>
  </modules>
  
</project>

这个pom和第一节中的pom非常类似,除了与模块关联的列表。注意我们这里用了${artifactId}-model来和刚刚创建的模块对应。

我们也需要更新模块里的pom,来和parent做对应:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>${groupId}</groupId>
    <artifactId>${artifactId}</artifactId>
    <version>${version}</version>
  </parent>
  <artifactId>${artifactId}-model</artifactId>
  <packaging>jar</packaging>
  <name>${artifactId}-model</name>
 
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
          <encoding>UTF-8</encoding>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
 
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit-dep</artifactId>
      <version>4.10</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
 
</project>  

你可能注意到了,节点<version><groupId>已经被移除。父项目会让他的子模块继承这些值,所以在子模块中不必重复他们。

我们也可以进一步配置。首先,我们可以将build区块移动到父项目中,让所有子模块继承,这样所有子模块拥有同样的compile配置,我们也可以在依赖管理(dependency management)中定义将junit依赖让所有模块依赖版本一致。 在我们做了这些改变后,我们的父项目parent的pom(src/main/resources/archetype-resources/pom.xml)应该是下面这个样子:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
  <modelVersion>4.0.0</modelVersion>
 
  <groupId>${groupId}</groupId>
  <artifactId>${artifactId}</artifactId>
  <version>${version}</version>
  <packaging>pom</packaging>
  <name>${artifactId}</name>
 
  <modules>
    <module>${artifactId}-model</module>
  </modules>
 
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <inherited>true</inherited>
        <configuration>
          <encoding>UTF-8</encoding>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
 
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit-dep</artifactId>
        <version>4.10</version>
        <scope>test</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
 
</project>

我们的子模块的pom(src/main/resources/archetype-resources/artifactId-model/pom.xml)应该长这个样:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
  <modelVersion>4.0.0</modelVersion>
 
  <parent>
    <groupId>${groupId}</groupId>
    <artifactId>${artifactId}</artifactId>
    <version>${version}</version>
  </parent>
 
  <artifactId>${artifactId}-model</artifactId>
  <packaging>jar</packaging>
  <name>${artifactId}-model</name>
 
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit-dep</artifactId>
    </dependency>
  </dependencies>
 
</project>

###更新archetype的metadata 到现在为止,我们所有的更新都不会有什么结果,知道我们更新了archetype的metadata。现在就让我们来开启这神奇的一页:

<archetype-descriptor name="sample-archetype">
  <fileSets>
    <fileSet filtered="true">
      <directory></directory>
      <includes>
        <include>pom.xml</include>
      </includes>
    </fileSet>
    <fileSet filtered="true">
      <directory>__artifactId__-model</directory>
      <includes>
        <include>pom.xml</include>
      </includes>
    </fileSet>
    <fileSet filtered="true">
      <directory>__artifactId__-model/src/main/java</directory>
      <includes>
        <include>**/*.java</include>
      </includes>
    </fileSet>
    <fileSet filtered="true">
      <directory>__artifactId__-model/src/test/java</directory>
      <includes>
        <include>**/*.java</include>
      </includes>
    </fileSet>
  </fileSets>
</archetype-descriptor>

###创建webapp模块 我们已经添加了第一个模块。接下来,我们我们将创建第二个模块:

新建文件夹:

mkdir -p src/main/resources/archetype-resources/__artifactId__-webapp/src/main/java/__packageInPathFormat__

如果我们创建webapp,我们需要servlet api。让我们在parent pom中添加一个scope为provided的依赖。我们也需要添加一个带有version的model模块,这样,我们可在webapp里引入他的时候不用指定版本:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit-dep</artifactId>
      <version>4.10</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>${groupId}</groupId>
      <artifactId>${artifactId}-model</artifactId>
      <version>${version}</version>
    </dependency>
  </dependencies>
</dependencyManagement>

我们也需要添加webapp模块到我们parent项目pom的modules列表中:

<modules>
  <module>${artifactId}-model</module>
  <module>${artifactId}-webapp</module>
</modules>

现在,让我们来创建webapp模块的pom(src/main/resources/archetype-resources/artifactId-webapp/pom.xml)。我们将添加servlet-api的依赖,和我们第一个模块model的依赖,还有Maven Jetty plugin,这样我们可以在创建项目后从Maven启动它:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
  <modelVersion>4.0.0</modelVersion>
 
  <parent>
    <groupId>${groupId}</groupId>
    <artifactId>${artifactId}</artifactId>
    <version>${version}</version>
  </parent>
 
  <artifactId>${artifactId}-webapp</artifactId>
  <packaging>war</packaging>
  <name>${artifactId}-webapp</name>
 
  <build>
    <plugins>
      <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>maven-jetty-plugin</artifactId>
        <version>6.1.26</version>
      </plugin>
    </plugins>
  </build>
 
  <dependencies>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
    </dependency>
    <dependency>
        <groupId>${groupId}</groupId>
        <artifactId>${artifactId}-model</artifactId>
      </dependency>
  </dependencies>
 
</project>

我们还需要在src/main/webapp/WEB-INF路径中添加web.xml。让我们先创建web.xml所在目录:

mkdir -p src/main/resources/archetype-resources/__artifactId__-webapp/src/main/webapp/WEB-INF
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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-app_2_5.xsd">
 
  <servlet>
    <display-name>${artifactId}</display-name>
    <servlet-name>${artifactId}</servlet-name>
    <servlet-class>${package}.Servlet</servlet-class>
  </servlet>
 
  <servlet-mapping>
    <servlet-name>${artifactId}</servlet-name>
    <url-pattern>/${artifactId}</url-pattern>
  </servlet-mapping>
 
</web-app>

我们可以过滤并替换这个文件中的${artifactId}等参数。 我们也需要一个基础的servlet类去匹配在web.xml文件中的定义。在路径src/main/resources/archetype-resources/__artifactId__-webapp/src/main/java/__packageInPathFormat__/Servlet.java创建一个类,以下是Servlet.java中内容:

package ${package};
 
import java.io.IOException;
import java.io.PrintWriter;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class Servlet extends HttpServlet {
 
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
     
    response.setStatus(200);
    PrintWriter writer = response.getWriter();
    writer.write(App.message());
  }
 
}

###更新archetype的metadata 我们需要再一次更新src/main/resources/META-INF/maven/archetype-metadata.xml,将webapp模块的内容加入。这里是最终的archetype-metadata.xml文件的样子:

<archetype-descriptor name="sample-archetype">
  <fileSets>
    <fileSet filtered="true">
      <directory></directory>
      <includes>
        <include>pom.xml</include>
      </includes>
    </fileSet>
    <fileSet filtered="true">
      <directory>__artifactId__-model</directory>
      <includes>
        <include>pom.xml</include>
      </includes>
    </fileSet>
    <fileSet filtered="true">
      <directory>__artifactId__-model/src/main/java</directory>
      <includes>
        <include>**/*.java</include>
      </includes>
    </fileSet>
    <fileSet filtered="true">
      <directory>__artifactId__-model/src/test/java</directory>
      <includes>
        <include>**/*.java</include>
      </includes>
    </fileSet>
    <fileSet filtered="true">
      <directory>__artifactId__-webapp</directory>
      <includes>
        <include>pom.xml</include>
      </includes>
    </fileSet>
    <fileSet filtered="true">
      <directory>__artifactId__-webapp/src/main/java</directory>
      <includes>
        <include>**/*.java</include>
      </includes>
    </fileSet>
    <fileSet filtered="true">
      <directory>__artifactId__-webapp/src/main/webapp/WEB-INF</directory>
      <includes>
        <include>web.xml</include>
      </includes>
    </fileSet>
  </fileSets>
</archetype-descriptor>

让我们来最后审视项目结构,奏是这个造型:

$ tree
.
|____pom.xml
|____src
| |____main
| | |____resources
| | | |____archetype-resources
| | | | |______artifactId__-model
| | | | | |____pom.xml
| | | | | |____src
| | | | | | |____main
| | | | | | | |____java
| | | | | | | | |______packageInPathFormat__
| | | | | | | | | |____App.java
| | | | | | |____test
| | | | | | | |____java
| | | | | | | | |______packageInPathFormat__
| | | | | | | | | |____AppTest.java
| | | | |______artifactId__-webapp
| | | | | |____pom.xml
| | | | | |____src
| | | | | | |____main
| | | | | | | |____java
| | | | | | | | |______packageInPathFormat__
| | | | | | | | | |____Servlet.java
| | | | | | | |____webapp
| | | | | | | | |____WEB-INF
| | | | | | | | | |____web.xml
| | | | |____pom.xml
| | | |____META-INF
| | | | |____maven
| | | | | |____archetype-metadata.xml

###安装archetype,生成项目然后运行webapp 现在先install archetype,然后去要生成项目的目录,然后生成它:

$ mvn clean install
$ cd ..
$ mvn archetype:generate -DarchetypeCatalog=local
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] >>> maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom >>>
[INFO] 
[INFO] <<< maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom <<<
[INFO] 
[INFO] --- maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Interactive mode
[INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
Choose archetype:
1: local -> com.theotherian.archetype:sample-archetype (sample-archetype)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 1: 1
Define value for property 'groupId': : com.theotherian
Define value for property 'artifactId': : sample-project
Define value for property 'version':  1.0-SNAPSHOT: : 
Define value for property 'package':  com.theotherian: : 
Confirm properties configuration:
groupId: com.theotherian
artifactId: sample-project
version: 1.0-SNAPSHOT
package: com.theotherian
 Y: : 
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: sample-archetype:1.0-SNAPSHOT
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: com.theotherian
[INFO] Parameter: artifactId, Value: sample-project
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: com.theotherian
[INFO] Parameter: packageInPathFormat, Value: com/theotherian
[INFO] Parameter: package, Value: com.theotherian
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: groupId, Value: com.theotherian
[INFO] Parameter: artifactId, Value: sample-project
[WARNING] Don't override file /Users/isimpson/sample-projects/sample-project/pom.xml
[INFO] project created from Archetype in dir: /Users/isimpson/sample-projects/sample-project
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 14.574s
[INFO] Finished at: Sat May 12 22:14:07 MDT 2012
[INFO] Final Memory: 7M/81M
[INFO] ------------------------------------------------------------------------

帅呆了~我们有了一个项目,然后编译他!

$ cd sample-project
$ mvn clean install

现在artifacts已经安装,让我们来跑webapp

$ cd sample-project-webapp
$ mvn jetty:run-war

现在,如果一切正确,你将在浏览器中以地址http://localhost:8080/sample-project-webapp/sample-project看到“Hello world!”


一口气翻3篇,终于翻完了,第一次翻译,艾玛累死了。

© 著作权归作者所有

共有 人打赏支持
石穿
粉丝 0
博文 9
码字总数 6925
作品 0
高级程序员
在Eclipse中创建Maven多模块工程

如果,你需要创建多个项目,项目之间即独立又有关系,那么创建一个Maven多模块项目是个非常好的选择,也非常cool!怎么在Eclipse里面创建多模块工程,以及需要注意哪些地方,我在这里做个简单...

孟飞阳 ⋅ 2016/07/29 ⋅ 0

在Eclipse中创建Maven多模块工程的例子

如果,你需要创建多个项目,项目之间即独立又有关系,那么创建一个Maven多模块项目是个非常好的选择,也非常cool!怎么在Eclipse里面创建多模块工程,以及需要注意哪些地方,我在这里做个简单...

凯文加内特 ⋅ 2015/05/07 ⋅ 1

Maven提高篇系列之一——多模块 vs 继承

感谢无知者云的博客,写的很好的Maven提高篇的文章 http://www.davenkin.me/post/2013-08-03/create-multi-module-maven-project 通常来说,在Maven的多模块工程中,都存在一个pom类型的工程...

凯文加内特 ⋅ 2015/05/07 ⋅ 1

eclipse 配置Maven问题解决办法:新建maven工程时报错:Could not resolve archetype org.apache.maven.archetypes .

此文乃本作者配置maven,被其折磨n天,究极解决方案,好文要顶啊。欢迎致电: zhe-jiang.he@hp.com 首先各maven.archetypes下载地址: http://mirrors.ibiblio.org/maven2/org/apache/maven...

庞陆阳 ⋅ 2016/09/30 ⋅ 0

Maven单独构建多模块项目中的单个模块

说明: 1、可能存在的场景,多模块项目没有互相引用,那么此时可以单独构建单个项目,指定到子模块的pom.xml文件即可完成编译。 2、如果多模块项目各自都引用了,那么单独编译子模块的pom.x...

easonjim ⋅ 01/25 ⋅ 0

多模块Maven工程单独打包某一模块工程

在eclipse中,多模块项目中单独打包某个web工程时,选中 "resolve workspace artifacts" 会导致war包内依赖的其他模块的jar为空目录。正确的打包某个模块的方式是在parent工程上运行 Run As...

ccor ⋅ 2016/07/01 ⋅ 0

用Maven构建Hadoop项目

1). 用Maven创建一个标准化的Java项目 mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.jason.hadoop.example -DartifactId=hadoopExample -Dpackag......

z_jordon ⋅ 2016/02/17 ⋅ 0

Maven使用笔记(六)使用Maven进行多模块拆分

模块拆分是Maven经常使用的功能,简单梳理一下如何使用Maven进行多模块拆分, 只做归纳总结,网上资料很多,不再一步一步实际创建和部署。 建立Maven多模块项目 一个简单的Java Web项目,Mav...

范大脚脚 ⋅ 2017/11/14 ⋅ 0

eclipse ee(Luna)无法创建Maven项目

问题描述: 使用Eclipse自带的Maven插件创建Web项目时报错: Could not resolve archetypeorg.apache.maven.archetypes:maven-archetype-webapp:RELEASE from any of theconfigured reposito......

Sheamus ⋅ 2015/06/01 ⋅ 3

Maven创建Java Application工程(既jar包)

Maven在创建工程时使用的是archetype(原型)插件,而如果要创建具体的工程,比如Application这些,那么可以使用maven-archetype-quickstart(相当于一个子类型,用于创建Application工程)插...

easonjim ⋅ 2017/05/04 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Spring | IOC AOP 注解 简单使用

写在前面的话 很久没更新笔记了,有人会抱怨:小冯啊,你是不是在偷懒啊,没有学习了。老哥,真的冤枉:我觉得我自己很菜,还在努力学习呢,正在学习Vue.js做管理系统呢。即便这样,我还是不...

Wenyi_Feng ⋅ 今天 ⋅ 0

博客迁移到 https://www.jianshu.com/u/aa501451a235

博客迁移到 https://www.jianshu.com/u/aa501451a235 本博客不再更新

为为02 ⋅ 今天 ⋅ 0

win10怎么彻底关闭自动更新

win10自带的更新每天都很多,每一次下载都要占用大量网络,而且安装要等得时间也蛮久的。 工具/原料 Win10 方法/步骤 单击左下角开始菜单点击设置图标进入设置界面 在设置窗口中输入“服务”...

阿K1225 ⋅ 今天 ⋅ 0

Elasticsearch 6.3.0 SQL功能使用案例分享

The best elasticsearch highlevel java rest api-----bboss Elasticsearch 6.3.0 官方新推出的SQL检索插件非常不错,本文一个实际案例来介绍其使用方法。 1.代码中的sql检索 @Testpu...

bboss ⋅ 今天 ⋅ 0

informix数据库在linux中的安装以及用java/c/c++访问

一、安装前准备 安装JDK(略) 到IBM官网上下载informix软件:iif.12.10.FC9DE.linux-x86_64.tar放在某个大家都可以访问的目录比如:/mypkg,并解压到该目录下。 我也放到了百度云和天翼云上...

wangxuwei ⋅ 今天 ⋅ 0

PHP语言系统ZBLOG或许无法重现月光博客的闪耀历史[图]

最近在写博客,希望通过自己努力打造一个优秀的教育类主题博客,名动江湖,但是问题来了,现在写博客还有前途吗?面对强大的自媒体站点围剿,还有信心和可能型吗? 至于程序部分,我选择了P...

原创小博客 ⋅ 今天 ⋅ 0

IntelliJ IDEA 2018.1新特性

工欲善其事必先利其器,如果有一款IDE可以让你更高效地专注于开发以及源码阅读,为什么不试一试? 本文转载自:netty技术内幕 3月27日,jetbrains正式发布期待已久的IntelliJ IDEA 2018.1,再...

Romane ⋅ 今天 ⋅ 0

浅谈设计模式之工厂模式

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻...

佛系程序猿灬 ⋅ 今天 ⋅ 0

Dockerfile基础命令总结

FROM 指定使用的基础base image FROM scratch # 制作base image ,不使用任何基础imageFROM centos # 使用base imageFROM ubuntu:14.04 尽量使用官方的base image,为了安全 LABEL 描述作...

ExtreU ⋅ 昨天 ⋅ 0

存储,对比私有云和公有云的不同

导读 说起公共存储,很难不与后网络公司时代的选择性外包联系起来,但尽管如此,它还是具备着简单和固有的可用性。公共存储的名字听起来也缺乏专有性,很像是把东西直接堆放在那里而不会得到...

问题终结者 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部