Solon 詳解系列文章:
Solon 框架詳解(一)- 快速入門
Solon 框架詳解(二)- Solon的核心
Solon 框架詳解(三)- Solon的web開發
Solon 框架詳解(四)- Solon的事務傳播機制
Solon 框架詳解(五)- Solon擴展機制之Solon Plugin
Solon 框架詳解(六)- Solon的校驗框架使用、定制與擴展
Solon 框架詳解(七)- Solon Ioc 的注解對比Spring及JSR330
Solon 框架詳解(八)- Solon的緩存框架使用和定制
Solon 框架詳解(九)- 渲染控制之定制統一的接口輸出
Solon 框架詳解(十)- Solon 的常用配置
Solon 框架詳解(十一)- Solon Cloud 的配置說明
一、Web基礎配置
//資源路徑說明(不用配置;也不能配置)
resources/app.properties( 或 app.yml 或 application.properties 或 application.yml ) 為應用配置文件
resources/static/ 為靜態文件根目標
resources/WEB-INF/view/ 為視圖模板文件根目標(支持多視圖共存)
//調試模式:
啟動參數添加:-debug=1
1、訪問靜態資源
Solon 的默認靜態資源的路徑為:(這個沒得改,也不讓改;為了簡化套路)
resources/static/
在默放的處理規則下,所有請求,都會先執行靜態文件代理。靜態文件代理會檢測是否存在靜態文件,有則輸出,沒有則跳過處理。輸出的靜態文件會做304控制。
2、自定義攔截器
Solon里所有的處理,都屬於Handler。可以用handler 的模式寫,也可以用controller的模式寫(Action 也是 Handler)
// handler模式(前置處理)
//
Solon.global().before("/hello/", ctx->{
if(ctx.param("name") == null){
ctx.setHandled(true); //如果沒有name, 則終止處理
}
});
// controller模式
//
@Controller
public class HelloInterceptor {
//(申明前置處理)
@Mapping(value = "/hello/" , before = true)
public void handle(Context ctx, String name) {
if(name == null){
ctx.setHandled(true); //如果沒有name, 則終止處理
}
}
}
3、讀取外部的配置文件
@Configuration
public class Config{
@Inject("${classpath:user.yml}")
private UserModel user;
}
4、HikariCP DataSource的配置
HiKariCP是數據庫連接池的一個后起之秀,號稱性能最好,可以完美地PK掉其他連接池。作者特別喜歡它。
a.引入依賴
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
b.添加配置
test.db1:
schema: "rock"
jdbcUrl: "jdbc:mysql://localdb:3306/rock?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true"
driverClassName: "com.mysql.cj.jdbc.Driver"
username: "demo"
password: "UL0hHlg0Ybq60xyb"
maxLifetime: 1000000
c.配置HikariCP數據源
建議這種操作,都安排在 @Configuration 配置類里執行。
//注解模式
//
@Configuration
public class Config{
// 同時支持 name 和 類型 兩種方式注入(注入時沒有name,即為按類型注入)
//
@Bean(value = "db1", typed = true)
pubblic DataSource dataSource(@Inject("${test.db1}") HikariDataSource ds){
return ds;
}
}
//靜態類模式(或純手動模式)
//
//public class Config{
// pubblic static HikariDataSource dataSource = Solon.cfg().getBean("test.db1", HikariDataSource.class);
//}
之后就可以通過@Inject注解得到這個數據源了。一般會改用加強注解對數據源進行自動轉換;所有與solon對接的ORM框架皆采用這種方案。
6、數據庫操作框架集成
a.Weed3集成
Wee3是和Solon一樣輕巧的一個框架,配置起來自然是簡單的。
在pom.xml中引用weed3擴展組件
<dependency>
<groupId>org.noear</groupId>
<artifactId>weed3-solon-plugin</artifactId>
</dependency>
剛才的Config配置類即可復用。先以單數據源場景演示:
//使用示例
@Controller
public class DemoController{
//@Db 按類型注入 //或 @Db("db1") 按名字注入
//@Db是weed3在Solon里的擴展注解 //可以注入 Mapper, BaseMapper, DbContext
//
@Db
BaseMapper<UserModel> userDao;
@Mapping("/user/")
pubblic UserModel geUser(long puid){
return userDao.selectById(puid);
}
}
b.Mybatis集成
在pom.xml中引用mybatis擴展組件
<dependency>
<groupId>org.noear</groupId>
<artifactId>mybatis-solon-plugin</artifactId>
</dependency>
添加mybatis mappers及相關的屬性配置
mybatis.db1: #db1 要與數據源的bean name 對上
typeAliases: #支持包名 或 類名(.class 結尾)
- "webapp.model"
mappers: #支持包名 或 類名(.class 結尾)或 xml(.xml結尾);配置的mappers 會 mapperScan並交由Ioc容器托管
- "webapp.dso.mapper.UserMapper.class"
剛才的Config配置類即也可復用
//使用示例
@Controller
public class DemoController{
//@Db 是 mybatis-solon-plugin 里的擴展注解,可注入 SqlSessionFactory,SqlSession,Mapper
//
@Db
UserMapper userDao; //UserMapper 已被 db1 自動 mapperScan 並已托管,也可用 @Inject 注入
@Mapping("/user/")
pubblic UserModel geUser(long puid){
return userDao.geUser(puid);
}
}
7、使用事務
Solon中推薦使用@Tran注解來申明和管理事務。
@Tran 支持多數據源事務,且使用方便
a.Weed3的事務
//使用示例
@Controller
public class DemoController{
@Db //@Db("db1") 為多數據源模式
BaseMapper<UserModel> userDao;
@Tran
@Mapping("/user/add")
pubblic Long addUser(UserModel user){
return userDao.insert(user, true);
}
}
b.Mybatis的事務
@Controller
public class DemoController{
@Db
UserMapper userDao; //UserMapper 已被 db1 mapperScan並已托管,也可用 @Inject 注入
@Tran
@Mapping("/user/add")
pubblic Long addUser(UserModel user){
return userDao.addUser(user);
}
}
c.混合多源事務(這個時候,我們需要Service層參演了)
@Service
public class UserService{
@Db("db1") //數據庫1
UserMapper userDao;
@Tran
public void addUser(UserModel user){
userDao.insert(user);
}
}
@Service
public class AccountService{
@Db("db2") //數據庫2
AccountMapper accountDao;
@Tran
public void addAccount(UserModel user){
accountDao.insert(user);
}
}
@Controller
public class DemoController{
@Inject
AccountService accountService;
@Inject
UserService userService;
@Tran
@Mapping("/user/add")
pubblic Long geUser(UserModel user){
Long puid = userService.addUser(user); //會執行db1事務
accountService.addAccount(user); //會執行db2事務
return puid;
}
}
8、開始jsp支持(不建議用)
solon 的jsp支持,是基於視圖模板的定位去處理的。根據啟動器組件的不同,配置略有不同:
<!-- 添加 solon web 開發包 -->
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-web</artifactId>
<type>pom</type>
<exclusions>
<!-- 排除默認的 jlhttp 啟動器 -->
<exclusion>
<groupId>org.noear</groupId>
<artifactId>solon.boot.jlhttp</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 添加 jetty 或 undertow 啟動器 -->
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon.boot.jetty</artifactId>
</dependency>
<!-- 添加 jetty 或 undertow jsp 擴展支持包 -->
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon.extend.jetty.jsp</artifactId>
<type>pom</type>
</dependency>
<!-- 添加 jsp 視圖引擎 -->
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon.view.jsp</artifactId>
</dependency>
二、Web開發進階
1、Solon的MVC注解
a.@Controller
控制器,只有一個注解。會自動通過不同的返回值做不同的處理
@Controller
public class DemoController{
@Mapping("/test1/")
public void test1(){
//沒返回
}
@Mapping("/test2/")
public String test2(){
return "返回字符串並輸出";
}
@Mapping("/test3/")
public UseModel test3(){
return new UseModel(2, "noear"); //返回個模型,默認會渲染為json格式輸出
}
@Mapping("/test4/")
public ModelAndView test4(){
return new ModelAndView("view path", map); //返回模型與視圖,會被視圖引擎渲染后再輸出,默認是html格式
}
}
b.@Mapping(value, method, produces)
默認只需要設定value值即可,method默認為MethodType.HTTP,即接收所有的http方法請求。
@Mapping("/user/")
2、視圖模板開發
freemaerker 視圖
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>${title}</title>
</head>
<body>
<div>
${message}
</div>
</body>
</html>
控制器
@Controller
public class HelloworldController {
@Mapping("/helloworld")
public Object helloworld(){
ModelAndView vm = new ModelAndView("helloworld.ftl");
vm.put("title","demo");
vm.put("message","hello world!");
return vm;
}
}
3、模板調試模式(即:模板修改后,瀏覽器刷新即可)
//調試模式:
啟動參數添加:-deubg=1 或 --deubg=1
4、數據校驗
Solon校驗的是Context上的參數(即http傳入的參數),是在Action參數注入之前的預處理。這與Spring驗證框架區別是很大的。
@Valid //為控制器開啟校驗能力;也可以做用在一個基類上
@Controller
public class ValidationController {
@NoRepeatSubmit
@NotNull({"name", "icon", "mobile"})
@Mapping("/valid")
public void test(String name, String icon, @Pattern("13\\d{9}") String mobile) {
}
}
下面是更多的校驗注解,可以研究一下:
注解 | 作用范圍 | 說明 |
---|---|---|
Date | 參數 | 校驗注解的參數值為日期格式 |
DecimalMax(value) | 參數 | 校驗注解的參數值小於等於@ DecimalMax指定的value值 |
DecimalMin(value) | 參數 | 校驗注解的參數值大於等於@ DecimalMin指定的value值 |
參數 | 校驗注解的參數值為電子郵箱格式 | |
Length(min, max) | 參數 | 校驗注解的參數值長度在min和max區間內 |
Max(value) | 參數 | 校驗注解的參數值小於等於@Max指定的value值 |
Min(value) | 參數 | 校驗注解的參數值大於等於@Min指定的value值 |
NoRepeatSubmit | 控制器 或 動作 | 校驗本次請求沒有重復 |
NotBlank | 動作 或 參數 | 校驗注解的參數值不是空白 |
NotEmpty | 動作 或 參數 | 校驗注解的參數值不是空 |
NotNull | 動作 或 參數 | 校驗注解的參數值不是null |
NotZero | 動作 或 參數 | 校驗注解的參數值不是0 |
Null | 動作 或 參數 | 校驗注解的參數值是null |
Numeric | 動作 或 參數 | 校驗注解的參數值為數字格式 |
Pattern(value) | 參數 | 校驗注解的參數值與指定的正則表達式匹配 |
Whitelist | 控制器 或 動作 | 校驗本次請求在白名單范圍內 |
5、統一異常處理
Solon.start(source, args)
.onError(err->err.printStackTrace()); //或者記錄到日志系統
三、打包與部署
1、在pom.xml中配置打包的相關插件
Solon 的項目必須開啟編譯參數:-parameters
<build>
<finalName>${project.name}</finalName>
<plugins>
<!-- 配置編譯插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<compilerArgument>-parameters</compilerArgument>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- 配置打包插件(設置主類,並打包成胖包) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<finalName>${project.name}</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>webapp.DemoApp</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
2、運行 maven 的 package 指令完成打包(IDEA的右側邊界面,就有這個菜單)
3、終端運行:java -jar DemoApp.jar
即可啟動
附:Solon項目地址
- gitee: https://gitee.com/noear/solon
- github: https://github.com/noear/solon