本贴主要介绍了 Latke 的关键配置及其设计用意,所以无论你是 Latke 的 开发者 还是基于 Latke 开发的产品的 使用者,希望本贴能够帮助到你。

为了说明方便,我们会使用 Solo 博客系统作为主要的应用场景进行举例。

latke.properties

文件路径是 WEB-INF/classes/latke.properties,该配置文件是 必须的。通常情况其中的配置项比较少,最简化的情况是只需要配置 #### Server #### 部分的 3 个项,其他项都有默认值,不需要显示设置。

Server 部分

一些 Solo 用户在初始化时会遇到“配置错误”的问题,这是因为 latke.props 没有配置或配置不当造成的。该配置文件中 #### Server #### 部分的默认配置如下:

#### Server ####
# Browser visit protocol
serverScheme=http
# Browser visit domain name
serverHost=localhost
# Browser visit port, 80 as usual, THIS IS NOT SERVER LISTEN PORT!
serverPort=8080

这 3 个配置项需要配置为用户通过浏览器 访问时候 的值。换句话说,如果你的服务在本机启动,那么默认的配置是可以让你在本机通过 http://localhost:8080 访问时一切正常的;但非本机访问时(比如通过 http://domain-or-ip:8080) 就 不能 正常加载静态资源了。

解决方案:将这三个配置项的值调整为最终访问时候对应的样子。

比如我的博客域名是 myblog.com,该域名已经正常解析到服务器 IP,此时只需要将 serverHost 的值设置为 myblog.com 就可以通过 http://myblog.com:8080 访问了。要进一步消除后面的端口有两种方式:

  1. 前置 HTTP 服务器做反向代理(比如通过 NGINX
  2. 将 Solo 启动时监听端口调整为 80/443

推荐第一种方式,因为:Servlet 容器主要是 Java Web 应用的处理环境,主要处理的是动态请求。HTTPS 或者是静态资源请求应该交由更专业的 HTTP 处理引擎来做,这样能减少很多复杂的配置(比如配置 Java 的 SSL 证书),也能充分优化性能(比如静态资源由 NGINX 处理,配置 Cache、限流等)。

一个正确的配置 样例 如下:

#### Server ####
# Browser visit protocol
serverScheme=http
# Browser visit domain name
serverHost=myblog.com
# Browser visit port, 80 as usual, THIS IS NOT SERVER LISTEN PORT!
serverPort=

请注意其中 serverPort 项并没有赋值,因为这样就能够使用 HTTP 的浏览器默认端口 80 了,HTTPS 也可以这样留空。

Static Server 部分

该部分通常情况是没有显示配置的(比如 Solo 里面默认的配置文件就没有出现这部分),需要显示配置的情况是需要做 动静分离 的应用场景。

前面我们提到过可以通过 NGINX 作为前置服务器,将静态资源请求分离出来进行处理。其具体的分离规则可以按 path 或后缀。这个动静分离的层次是在具体服务器节点上的分离,是用户请求到达内部网络后的处理。

我们可以在用户浏览器请求时就进行动静分离,将静态资源请求分发到配置好的 CDN 服务上,这个 CDN 服务一般是一个域名地址。而 staticServerSchemestaticServerHoststaticServerPort这三项就是用来配置该地址的,如果没有显示配置,则这三项会分别使用 serverSchemeserverHostserverPort 的值。

其他配置项

下面这些配置项也是在某些场景才会用到,一般来说也不用单独配置的。

| 项 | 说明 | 默认值 | 备注 |
| ---- | ---- | ---- |
| runtimeMode | 运行模式,可选值 DEVELOPMENTPRODUCTION | PRODUCTION | 线上环境一定要使用 PRODUCTION |
| staticResourceVersion | 静态资源版本号,主要用于刷缓存 | 默认取服务启动的时间毫秒 | |
| contextPath | 容器上下文路径 | 自动获取部署上下文路径 | 会和 虚拟目录 的配置相关 |
| staticPath | 静态资源服务的上下文路径 | 同 contextPath | 显示配置的话一般都是留空 |

其中“上下文路径”是 Java Servlet 中的概念,指的是请求 URL 上第一层目录路径,比如对于 http://mydomain.com/solo/login,/solo 就是上下文路径,但该值也和部署目录相关,本例需要应用部署在 tomcat/webapps/solo 目录中,如果应用部署在 ROOT 目录下,那上下文路径就是空字符串。

顺便吐槽一下,“上下文路径”这个概念是 Java Servlet 规范里面特有的,是一个很奇葩的设计,标准的 HTTP 协议是没有这个设定的,并且 Servlet API 中定义的 Request URI 和 URI RFC 定义的完全不是一个东西,关于 URI 和 URL 的正解请看这里

local.properties

文件路径是 WEB-INF/classes/local.properties,该文件是 必须的,主要用于配置数据库。比如在 Solo 中默认的配置如下:

#### H2 runtime ####
runtimeDatabase=H2
jdbc.username=root
jdbc.password=
jdbc.driver=org.h2.Driver
jdbc.URL=jdbc:h2:~/solo_h2/db

#### MySQL runtime ####
#runtimeDatabase=MYSQL
#jdbc.username=root
#jdbc.password=
#jdbc.driver=com.mysql.jdbc.Driver
#jdbc.URL=jdbc:mysql://localhost:3306/solo?useUnicode=yes&characterEncoding=utf8

# The minConnCnt MUST larger or equal to 3
jdbc.minConnCnt=5
jdbc.maxConnCnt=10

# Be care to change the transaction isolation 
jdbc.transactionIsolation=REPEATABLE_READ

# The specific table name prefix
jdbc.tablePrefix=b3_solo

其中 #### H2 runtime ######## MySQL runtime #### 只能启用一种,该部分配置了使用哪一种数据库实现。

其他的配置项比较好识别,一般来说使用默认值就好。

H2

默认使用应用内嵌的 H2 数据库,其中 jdbc.URL 中可以配置数据持久化的文件路径,比如 jdbc:h2:~/solo_h2/db 使用的路径就是 操作系统用户 home (即 ~ )下的 solo_h2/db 目录,在 Java 中对于的系统变量是 ${user.home},如果你不大熟悉 Unix-like 的表示法,也可以将该路径配置成完整的绝对路径,比如 jdbc:h2:D:/solo_h2/db

mail.properties

文件路径是 WEB-INF/classes/mail.properties,该配置文件是可选的。在 Solo 中如果正确进行了配置,将会在有文章评论时发送邮件,下面是默认配置:

mail.user=b3log.solo@gmail.com
mail.password=
mail.debug=false
mail.smtp.host=smtp.gmail.com
mail.smtp.port=587
mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
mail.smtp.socketFactory.fallback=false
mail.smtp.socketFactory.port=465

和前面的配置项类似,邮件的配置也有一些隐式默认项:

说明 默认值
mail.smtp.auth 是否启用身份验证 true
mail.smtp.starttls.enable 是否启用 SSL 连接 true

static-resources.xml

文件路径是 WEB-INF/static-resources.xml,该配置文件是 必须的,用于配置静态资源路径。

每款 Servlet 容器都有一个“默认的 Servlet”来处理请求,并包括了对静态资源 IO 的优化实现,所以我们需要根据请求路径将静态资源请求分发到该 Servlet 上。

路径的匹配模式是 Ant-style 匹配,简单说来就是:

  • * 匹配多个字符
  • ? 匹配单个字符
  • ** 匹配多层目录

如果你需要 添加自己的静态资源(比如 HTML、MP3 等)就需要修改一下该文件。

Latke 对于“默认的 Servlet”支持如下:

  • Tomcat、Jetty、JBoss、GlassFish:default
  • Resin:resin-file
  • WebLogic:FileServlet
  • WebSphere:SimpleFileServlet

“恰到好处”的框架

在 HTTP 层,我们希望 Latke 是一个对 Servlet 的轻薄封装,这需要开发者对 Servlet 规范有一定了解,以最大的自由度来组合自己熟悉的工具库,比如:

  • 没有封装请求:数据格式、提交方式没有限制,开发者可以使用自己最擅长的方式进行参数处理
  • 适度封装响应:内置支持渲染 HTML、JSON(P)、图片等

在实体模型 / 持久化层,Latke 做了一个较创新的设计尝试,即使用 JSON 进行贯穿、无实体类。较理想的应用实现场景是前端提交的请求数据以 JSON 作为格式,该 JSON 在 Controller、Service 中做处理(校验、增减字段等)后就能直接保存到关系型数据库中,免去很多无谓的类型转换和复杂的 ORM。

除了实体模型,其他的类对象(控制器、服务、切面、事件、插件、定时任务、缓存等)都是使用 IoC 容器进行管理的,这一点和 Spring 核心原理一致。因为 IoC / AOP 确实有用,也是业界主流技术。

Latke 整体的设计理念是 在不影响开发效率的前提下,让开发者懂得 Java Web 的基本原理

框架只是辅助,原理才是根本。一个框架如果让开发者 知其然而不知其所以然 表面上是提高了生产效率,但本质上是在坑害它的使用者。Latke 并不是快餐,而是可以细细品味的粗茶淡饭。

  • Latke

    Latke 是一个类似 Spring 但以 JSON 为主的 Java Web 框架。

    37 引用 • 245 回帖 • 493 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    2281 引用 • 6677 回帖 • 1220 关注
  • Web
    93 引用 • 291 回帖 • 7 关注
  • 框架
    19 引用 • 167 回帖
感谢    赞同    分享    收藏    关注    反对    举报    ...