### Spymemcached Full Configuration Example
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-data/solon-cache-spymemcached/README.md
Provides a complete configuration example for Solon's cache with Spymemcached, including driver type, key header, default expiration, and server details.
```yaml
#完整配置示例
solon.cache1:
driverType: "memcached"
keyHeader: "demo" #默认为 ${solon.app.name} ,可不配置
defSeconds: 30 #默认为 30,可不配置
server: "localhost:11211"
user: "" #默认为空,可不配置
password: "" #默认为空,可不配置
#简配示例
solon.cache2:
server: "localhost:11211"
```
--------------------------------
### Solon Application Start
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-docs/solon-openapi2-knife4j/README.md
Basic Solon application startup code.
```java
public class App {
public static void main(String[] args) {
Solon.start(App.class, args);
}
}
```
--------------------------------
### SolonMain Annotation Example
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-tool/solon-gradle-plugin/README.md
Demonstrates how to use the @SolonMain annotation to mark the entry point of your Solon application, especially when multiple main methods exist.
```java
package org.noear.solon.annotation;
import java.lang.annotation.*;
/**
* Solon 主类(入口类)
*
*
{@code
* @SolonMain
* public class App{
* public static void main(String[] args){
* Solon.start(App.class, args);
* }
* }
* }
*
* @author noear
* @since 2.2
* */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SolonMain {
}
// 启动类上添加
@SolonMain
public class App {
public static void main(String[] args) {
Solon.start(App.class, args);
}
}
```
--------------------------------
### Solon-Flow WorkflowService Task Handling
Source: https://github.com/opensolon/solon/blob/main/UPDATE_LOG.md
Shows how to initialize and use WorkflowService for getting and posting tasks in Solon-flow.
```java
WorkflowService workflow = WorkflowService.of(engine, WorkflowDriver.builder()
.stateController(new ActorStateController())
.stateRepository(new InMemoryStateRepository())
.build());
//1. 取出任务
Task task = workflow.getTask(graph, context);
//2. 提交任务
workflow.postTask(task.getNode(), TaskAction.FORWARD, context);
```
--------------------------------
### Code-based Documentation Build
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-docs/solon-docs/README.md
Define documentation configurations programmatically using Java. This approach allows for dynamic setup of API documentation groups, including global response types, security headers, and API base packages.
```java
@Configuration
public class DocConfig {
@Inject
OpenApiExtensionResolver openApiExtensionResolver;
/**
* 基于代码构建
*/
@Managed("appApi")
public DocDocket appApi() {
//根据情况增加 "knife4j.setting" (可选)
return new DocDocket()
.vendorExtensions(openApiExtensionResolver.getExtension())
.groupName("app端接口")
.schemes(Scheme.HTTP)
.globalResult(Result.class)
.globalResponseInData(true)
.apis("com.swagger.demo.controller.app")
.securityDefinitionInHeader("token");
}
@Managed("adminApi")
public DocDocket adminApi() {
return new DocDocket()
.groupName("admin端接口")
.info(new ApiInfo().title("在线文档")
.description("在线API文档")
.termsOfService("https://gitee.com/noear/solon")
.contact(new Contact().name("demo")
.url("https://gitee.com/noear/solon")
.email("demo@foxmail.com"))
.version("1.0"))
.schemes(Scheme.HTTP, Scheme.HTTPS)
.globalResponseInData(true)
.globalResult(Result.class)
.apis("com.swagger.demo.controller.admin")
.securityDefinitionInHeader("token");
}
}
```
--------------------------------
### Solon ScopeLocal Example
Source: https://github.com/opensolon/solon/blob/main/UPDATE_LOG.md
Demonstrates the usage of ScopeLocal for managing thread-local scoped variables in Solon.
```java
public class Demo {
static ScopeLocal LOCAL = ScopeLocal.newInstance();
public void test(){
LOCAL.with("test", ()->{
System.out.println(LOCAL.get());
});
}
}
```
--------------------------------
### Implement Server-Side Web Service
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-web/solon-web-webservices/README.md
Define a Java class annotated with @WebService to expose a service. Ensure Solon is started.
```java
public class ServerTest {
public static void main(String[] args) {
Solon.start(ServerTest.class, args);
}
@WebService(serviceName = "HelloService", targetNamespace = "http://demo.solon.io")
public static class HelloServiceImpl {
public String hello(String name) {
return "hello " + name;
}
}
}
```
--------------------------------
### JavaScript WebSocket Stomp Client Setup
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-net/solon-net-stomp/src/test/resources/static/user1.html
Initializes and configures the Stomp.js client for WebSocket communication. Includes connection headers, debug logging, reconnection settings, and event handlers for connection and disconnection.
```javascript
var stompClient = null;
function setConnected(connected) {
document.getElementById('connect').disabled = connected;
document.getElementById('disconnect').disabled = !connected;
document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
$('#response').html();
}
function connect() {
//https://stomp-js.github.io/api-docs/latest/classes/Client.html
var stompConfig = {
connectHeaders: {
'connectedCallUri': 'www.baidu.com?test=123',
'disconnectedCallUri': 'www.baidu.com?test=321',
"resource": "pc-web",
"name": "web测试"
},
disconnectHeaders: {},
debug: function (str) {
console.log(str);
},
//等于0则不自动重连
reconnectDelay: 5000,
heartbeatIncoming: 0,
heartbeatOutgoing: 0,
stompVersions: {
protocolVersions: function () { return []; },
supportedVersions: function(){ return []; }
},
onConnect: function (frame) {
setConnected(true);
console.info('Connected', frame);
stompClient.subscribe('/topic/todoTask1/\*', function (response) {
showResponse(response.body);
//response.ack({"message-id": response.headers["message-id"]});
});
stompClient.subscribe('/app/todoTask1/\*', function (response) {
showResponse(response.body);
//response.ack({"message-id": response.headers["message-id"]});
});
stompClient.subscribe('/user/app/errors', function (response) {
showResponse(response.body);
//response.ack({"message-id": response.headers["message-id"]});
});
var subscription = stompClient.subscribe('/topic/todoTask2/\*', function (response) {
});
subscription.unsubscribe();
},
onWebSocketClose: function (frame) {
console.error("onWebSocketClose", frame);
setConnected(false);
}
}
var wsurl = $('#wsurl').val();
console.error("stompConfig", stompConfig);
stompClient = new StompJs.Client($.extend({ brokerURL: wsurl }, stompConfig));
stompClient.activate();
}
function disconnect(frame) {
if (stompClient != null) {
stompClient.deactivate();
}
stompClient = null;
setConnected(false);
}
```
--------------------------------
### Advanced JSON Formatting Customization
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-serialization/solon-serialization-snack4/README.md
Customize JSON serialization by adding converters for specific data types. This example shows how to format Date, LocalDate, and LocalDateTime objects before they are serialized.
```java
public class DemoApp {
public static void main(String[] args){
Solon.start(DemoApp.class, args, app->{
initMvcJsonCustom();
});
}
/**
* 初始化json定制(需要在插件运行前定制)
*/
private static void initMvcJsonCustom() {
//通过转换器,做简单类型的定制
SnackRenderFactory.global
.addConvertor(Date.class, s -> s.getTime());
SnackRenderFactory.global
.addConvertor(LocalDate.class, s -> s.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
SnackRenderFactory.global
.addConvertor(LocalDateTime.class, s -> s.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
SnackRenderFactory.global.add
}
}
```
--------------------------------
### Create Nami Client with Builder (Path and Upstream)
Source: https://github.com/opensolon/solon/blob/main/__release/nami-bundle/README.md
Configure a Nami client using the builder by providing the path and an upstream provider. This allows for more flexible endpoint configuration.
```java
public class Demo3{
IComplexModelService service = Nami.builder()
.encoder(SnackTypeEncoder.instance)
.path("/ComplexModelService/")
.upstream(()->"http://localhost:8080")
.create(IComplexModelService.class);
public void test(){
ComplexModel tmp = service.read(1);
service.save(tmp);
}
}
```
--------------------------------
### Configure SSL Keystore via Command Line
Source: https://github.com/opensolon/solon/blob/main/__hatch/solon-server-nettyhttp/README.md
Set SSL keystore and password configurations directly through Java system properties during application startup. This method is useful for overriding file configurations or for dynamic environments.
```shell
java -Dserver.ssl.keyStore=/demo.jks
-Dserver.ssl.keyPassword=demo
-jar demo.jar
```
--------------------------------
### Create Nami Client with Builder (URL)
Source: https://github.com/opensolon/solon/blob/main/__release/nami-bundle/README.md
Instantiate a Nami client using the builder pattern, specifying the full URL and encoder. This is useful for direct endpoint configuration.
```java
public class Demo2{
IComplexModelService service = Nami.builder()
.encoder(SnackTypeEncoder.instance)
.url("http://localhost:8080/ComplexModelService/")
.create(IComplexModelService.class);
public void test(){
ComplexModel tmp = service.read(1);
service.save(tmp);
}
}
```
--------------------------------
### Programmatically Add Static File Mappings in Java
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-web/solon-web-staticfiles/README.md
Add static file mappings using Java code within the Solon application startup. This allows for dynamic configuration of static resource locations.
```java
public class App {
public static void main(String[] args) {
Solon.start(App.class, args, app -> {
//添加静态目录映射
//1.添加扩展目录:${solon.extend}/static/
StaticMappings.add("/", new ExtendStaticRepository());
//2.添加本地绝对目录
StaticMappings.add("/", new FileStaticRepository("/data/sss/water/water_ext/"));
//3.添加资源路径
StaticMappings.add("/", new ClassPathStaticRepository("user"));
});
}
}
```
--------------------------------
### Configure Logging Appenders and Levels
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-logging/solon-logging/README.md
Set up different logging appenders (console, cloud, file) and their respective levels (TRACE, INFO).
```yaml
solon.logging.appender:
console:
level: TRACE
enable: true
cloud:
level: INFO
enable: true
file:
class: org.xxx.xxx.LogFileAppender
level: INFO
```
--------------------------------
### Build and Package with Solon Gradle Plugin
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-tool/solon-gradle-plugin/README.md
Execute Gradle tasks to build and package your Solon application as a JAR or WAR file.
```bash
gradle solonJar
gradle solonWar
```
--------------------------------
### Configuration-based Documentation Build
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-docs/solon-docs/README.md
Configure documentation discovery, routes, and authentication using YAML. This method is useful for defining remote and local API documentation endpoints, including security settings and API information.
```yaml
solon.docs:
discover: #(发现配置,需要引入 solon cloud 发现服务插件),可选
enabled: true
syncStatus: true #同步上下线状态
uriPattern: "swagger/v2?group={service}" #上游路径模式(要么带变量 {service},要么用统一固定值)
contextPathPattern: "/{service}"
basicAuth:
admin: "123456"
user: "654321"
excludedServices: #排除服务名
- "user-api"
includedServices: #包函服务名
- "order-api"
routes:
- id: appApi #(远程接口文档,即分布式服务或微服务),配置风格
groupName: "app端接口"
upstream:
target: "lb://app-api"
contextPath: "/app"
uri: "/xxx"
- id: adminApi #(本地接口文档),配置风格
groupName: "admin端接口"
globalResponseInData: true
basicAuth:
admin: "123456"
user: "654321"
apis:
- basePackage: "com.swagger.demo.controller.admin"
info: #可选
title: "在线文档"
description: "在线API文档"
termsOfService: "https://gitee.com/noear/solon"
version: 1.0
contact: #可选
name: "demo"
email: "demo@qq.com"
license: #可选
name: "demo"
url: "https://gitee.com/noear/solon/blob/master/LICENSE"
```
--------------------------------
### Enable Documentation in Solon App
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-docs/solon-swagger2-knife4j/README.md
Enables API documentation based on debug or file modes. This is the entry point for activating the documentation feature.
```java
public class App {
public static void main(String[] args) {
Solon.start(App.class, args, app -> {
//开发模式,或调试模式下才开启文档(或者自己定义配置控制)//或者一直开着(默认是开着的)
app.enableDoc(app.cfg().isDebugMode() || app.cfg().isFilesMode());
});
}
}
```
--------------------------------
### Previous Packaging Configuration with Maven Assembly Plugin
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-tool/solon-maven-plugin/README.md
This snippet demonstrates a previous packaging configuration using the maven-assembly-plugin. It includes settings for the compiler plugin and assembly plugin, specifying the main class and dependency packaging.
```xml
org.apache.maven.pluginsmaven-compiler-plugin${maven-compiler.version}-parameters${java.version}${java.version}UTF-8org.apache.maven.pluginsmaven-assembly-plugin${maven-assembly.version}${project.artifactId}falsejar-with-dependencieswebapp.DemoAppmake-assemblypackagesingle
```
--------------------------------
### Create Client-Side Web Service (Manual Mode)
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-web/solon-web-webservices/README.md
Use WebServiceHelper to create a client proxy for a remote web service. Requires the service interface definition.
```java
public class ClientTest {
public static void main(String[] args) {
String wsAddress = "http://localhost:8080/ws/HelloService";
HelloService helloService = WebServiceHelper.createWebClient(wsAddress, HelloService.class);
System.out.println("rst::" + helloService.hello("noear"));
}
@WebService(serviceName = "HelloService", targetNamespace = "http://demo.solon.io")
public interface HelloService {
@WebMethod
String hello(String name);
}
}
```
--------------------------------
### Configure Static File Mappings in YAML
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-web/solon-web-staticfiles/README.md
Define static file serving rules in the application.yaml file. Use 'path' to specify the URL prefix and 'repository' to indicate the source location.
```yaml
solon.mime.json: "application/json"
solon.staticfiles:
enabled: true
cacheMaxAge: 6000
mappings:
- path: "/img/"
repository: "/data/sss/app/" #表示磁盘目录地址
- path: "/"
repository: "classpath:user" #表示资源目录
- path: "/"
repository: ":extend" #表示扩展静态静态
solon.extend: "!jt_ext" #!开头,表示如果没有扩展目录则自动创建 //用于支持 ExtendStaticRepository
```
--------------------------------
### Dynamic Data Source Configuration
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-data/solon-data-dynamicds/README.md
Configure multiple data sources using YAML. Key properties include 'type' for the data source implementation, 'strict' for error handling when a data source is not found, and 'default' for the default data source within a dynamic configuration.
```yaml
demo.ds.db_user:
type: "com.zaxxer.hikari.HikariDataSource"
strict: true
default:
jdbcUrl: "xxx" #属性名要与 type 类的属性对上
username: "xxx"
paasword: "xxx"
driverClassName: "xx"
db_user_2:
jdbcUrl: "xxx" #属性名要与 type 类的属性对上
username: "xxx"
paasword: "xxx"
driverClassName: "xx"
```
--------------------------------
### Configuration Reference for Solon Stop
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-web/solon-web-stop/README.md
Configure the remote shutdown service using properties in your application.yml file. Key settings include enabling the feature, defining the command path, and specifying an IP whitelist.
```yaml
solon.stop:
enable: false #是否启用。默认为关闭
path: "/_run/stop/" #命令路径。默认为'/_run/stop/'
whitelist: "127.0.0.1" #白名单,`*` 表示不限主机。默认为`127.0.0.1`
```
--------------------------------
### Solon Docs Configuration
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-docs/solon-openapi2-knife4j/README.md
Configuration for Solon's documentation features, including discovery and route definitions.
```yaml
solon.docs:
discover: #(发现配置,需要引入 solon cloud 发现服务插件),可选
enabled: true
syncStatus: true #同步上下线状态
uriPattern: "swagger/v2?group={service}" #上游路径模式(要么带变量 {service},要么用统一固定值)
basicAuth:
admin: "123456"
user: "654321"
excludedServices: #排除服务名
- "user-api"
includedServices: #包函服务名
- "order-api"
routes:
- id: appApi #(远程接口文档,即分布式服务或微服务),配置风格
groupName: "app端接口"
upstream:
target: "lb://app-api"
contextPath: "/app"
uri: "/xxx"
- id: adminApi #(本地接口文档),配置风格
groupName: "admin端接口"
globalResponseInData: true
basicAuth:
admin: "123456"
user: "654321"
apis:
- basePackage: "com.swagger.demo.controller.admin"
info: #可选
title: "在线文档"
description: "在线API文档"
termsOfService: "https://gitee.com/noear/solon"
version: 1.0
contact: #可选
name: "demo"
email: "demo@qq.com"
license: #可选
name: "demo"
url: "https://gitee.com/noear/solon/blob/master/LICENSE"
```
--------------------------------
### Build Swagger2 Knife4j Docket from Configuration
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-docs/solon-swagger2-knife4j/README.md
Constructs a DocDocket bean from YAML configuration for API documentation, setting global results and security definitions.
```java
@Configuration
public class DocConfig {
/**
* 基于配置构建
*/
@Managed("adminApi")
public DocDocket adminApi(@Inject("${swagger.adminApi}") DocDocket docket) {
docket.globalResult(Result.class);
docket.securityDefinitionInHeader("token");
return docket;
}
}
```
--------------------------------
### Configure Solon Gradle Plugin in build.gradle
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-tool/solon-gradle-plugin/README.md
Add the Solon Gradle plugin dependency and apply the plugin in your build.gradle file. Configure the main class for Solon JAR and WAR packaging.
```groovy
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath 'org.noear:solon-gradle-plugin:x.y.z'
}
}
// 使用
apply plugin: 'org.noear.solon'
compileJava {
// 这两个配置可以不添加了,插件中会默认自动添加
options.encoding = "UTF-8"
options.compilerArgs << "-parameters"
}
// 配置启动文件名
solon {
mainClass = "com.example.demo.App"
}
// 也可以针对 jar包和 war包指定不同的 mainClass
solonJar{
mainClass = "com.example.demo.App"
}
// 使用 solonWar 需要添加 war 插件
solonWar{
mainClass = "com.example.demo.App"
}
```
--------------------------------
### Configure SSL Keystore in app.yml
Source: https://github.com/opensolon/solon/blob/main/__hatch/solon-server-nettyhttp/README.md
Specify the keystore file path and password in the application configuration file (app.yml) for SSL support. Supports .jks or .pfx formats. Can use file paths or classpath resources.
```yaml
server.ssl:
keyStore: "/demo.jks" #或者应用内资源文件 "classpath:demo.jks"
keyPassword: "demo"
```
--------------------------------
### Configure Solon Gradle Plugin in build.gradle.kts
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-tool/solon-gradle-plugin/README.md
Add the Solon Gradle plugin dependency and apply the plugin in your build.gradle.kts file. Configure the main class for Solon JAR and WAR packaging using Kotlin DSL.
```kotlin
buildscript {
repositories {
mavenLocal()
maven {
setUrl("https://maven.aliyun.com/repository/public")
}
mavenCentral()
}
dependencies {
classpath("org.noear:solon-gradle-plugin:x.y.z")
}
}
// 引用插件
apply(plugin = "org.noear.solon")
// 统一配置
extensions.configure(org.noear.solon.gradle.dsl.SolonExtension::class.java) {
mainClass.set("com.example.demo.App")
}
// 单独配置
tasks.withType {
mainClass.set("com.example.demo.App")
}
tasks.withType {
mainClass.set("com.example.demo.App")
}
```
--------------------------------
### Solon-Flow Graph Hardcoding and Modification
Source: https://github.com/opensolon/solon/blob/main/UPDATE_LOG.md
Illustrates how to define a graph using hardcoding and how to modify an existing graph in Solon-flow.
```java
//硬编码
Graph graph = Graph.create("demo1", "示例", spec -> {
spec.addStart("start").title("开始").linkAdd("01");
spec.addActivity("n1").task("@AaMetaProcessCom").linkAdd("end");
spec.addEnd("end").title("结束");
});
//修改
Graph graphNew = Graph.copy(graph, spec -> {
spec.getNode("n1").linkRemove("end").linkAdd("n2"); //移掉 n1 连接;改为 n2 连接
spec.addActivity("n2").linkAdd("end");
});
```
--------------------------------
### New Solon Maven Plugin Configuration
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-tool/solon-maven-plugin/README.md
This snippet shows the configuration for the new solon-maven-plugin. It preserves individual jar packages and avoids overwriting identical files.
```xml
org.noearsolon-maven-plugin
```
--------------------------------
### Spymemcached Bean Definition with @Managed
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-data/solon-cache-spymemcached/README.md
Demonstrates how to define Spymemcached cache beans using Solon's @Configuration and @Managed annotations.
```java
//构建 bean
@Configuration
public class Config {
@Managed(value = "cache1", typed = true) //默认
public CacheService cache1(@Inject("${solon.cache1}") MemCacheService cache){
return cache;
}
@Managed("cache2")
public CacheService cache2(@Inject("${solon.cache2}") CacheServiceSupplier supplier){
//CacheServiceSupplier 可自动识别类型
return supplier.get();
}
}
```
--------------------------------
### Solon-AI McpServerTool with CompletableFuture
Source: https://github.com/opensolon/solon/blob/main/UPDATE_LOG.md
Showcases a Solon-AI MCP server endpoint using STREAMABLE_STATELESS channel and CompletableFuture for asynchronous operations.
```java
@McpServerEndpoint(channel = McpChannel.STREAMABLE_STATELESS, mcpEndpoint = "/mcp1")
public class McpServerTool {
@ToolMapping(description = "查询天气预报", returnDirect = true)
public CompletableFuture getWeather(@Param(description = "城市位置") String location) {
return CompletableFuture.completedFuture("晴,14度");
}
}
```
--------------------------------
### Configure JVM for Serialization Permissions on JDK 17
Source: https://github.com/opensolon/solon/blob/main/__test/README.md
Use this JVM parameter on JDK 17 or later if serialization permission issues arise.
```shell
java --add-opens java.base/java.lang=ALL-UNNAMED -jar xxx.jar
```
--------------------------------
### Configuring Data Source Beans
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-data/solon-data-dynamicds/README.md
Define a DataSource bean for a specific dynamic data source configuration using Solon's dependency injection and managed annotations.
```java
@Configuration
public class Config {
@Managed("db_user")
public DataSource dsUser(@Inject("$demo.ds.db_user}") DynamicDataSource dataSource) {
return dataSource;
}
}
```
--------------------------------
### Build Swagger2 Knife4j Docket via Code (App API)
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-docs/solon-swagger2-knife4j/README.md
Programmatically builds a DocDocket for the app API, including vendor extensions, group name, schemes, and security definitions.
```java
@Configuration
public class DocConfig {
@Inject
OpenApiExtensionResolver openApiExtensionResolver;
/**
* 基于代码构建
*/
@Managed("appApi")
public DocDocket appApi() {
//根据情况增加 "knife4j.setting" (可选)
return new DocDocket()
.vendorExtensions(openApiExtensionResolver.getExtension())
.groupName("app端接口")
.schemes(Scheme.HTTP)
.globalResult(Result.class)
.globalResponseInData(true)
.apis("com.swagger.demo.controller.app")
.securityDefinitionInHeader("token");
}
@Managed("adminApi")
public DocDocket adminApi() {
return new DocDocket()
.groupName("admin端接口")
.info(new ApiInfo().title("在线文档")
.description("在线API文档")
.termsOfService("https://gitee.com/noear/solon")
.contact(new Contact().name("demo")
.url("https://gitee.com/noear/solon")
.email("demo@foxmail.com"))
.version("1.0"))
.schemes(Scheme.HTTP, Scheme.HTTPS)
.globalResponseInData(true)
.globalResult(Result.class)
.apis("com.swagger.demo.controller.admin")
.securityDefinitionInHeader("token");
}
}
```
--------------------------------
### Using Solon Cache Annotation in Controller
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-data/solon-cache-spymemcached/README.md
Shows how to apply the @Cache annotation to a method in a Solon controller for automatic caching.
```java
//应用
@Controller
public class DemoController {
@Cache
public String hello(String name) {
return String.format("Hello {0}!", name);
}
}
```
--------------------------------
### Configure JVM for Serialization Permissions on JDK 9-16
Source: https://github.com/opensolon/solon/blob/main/__test/README.md
Use this JVM parameter on JDK 9 through JDK 16 if serialization permission issues arise.
```shell
java --illegal-access=permit -jar xxx.jar
```
--------------------------------
### Configure Solon Serialization JSON
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-serialization/solon-serialization-jackson3/README.md
Configure Solon's JSON serialization settings using YAML. This includes date formatting, time zone, and how various data types (long, bool, null) are represented.
```yaml
solon.serialization.json:
dateAsFormat: 'yyyy-MM-dd HH:mm:ss' #配置日期格式(默认输出为时间戳)
dateAsTimeZone: 'GMT+8' #配置时区
dateAsTicks: false #将date转为毫秒数(和 dateAsFormat 二选一)
longAsString: true #将long型转为字符串输出 (默认为false)
boolAsInt: false #将bool型转为字符串输出 (默认为false)
nullStringAsEmpty: false
nullBoolAsFalse: false
nullNumberAsZero: false
nullArrayAsEmpty: false
nullAsWriteable: false #输出所有null值
```
--------------------------------
### Declare HTTP RPC Interface
Source: https://github.com/opensolon/solon/blob/main/__release/nami-bundle/README.md
Define the interface for your HTTP RPC service. This interface will be used by Nami to generate a client proxy.
```java
public interface IComplexModelService {
//持久化
void save(ComplexModel model);
//读取
ComplexModel read(Integer modelId);
}
```
--------------------------------
### Configure Swagger2 Knife4j via YAML
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-docs/solon-swagger2-knife4j/README.md
Defines Swagger2 Knife4j configurations using YAML for API documentation, including group name, authentication, and API base packages.
```yaml
swagger.adminApi:
groupName: "admin端接口"
globalResponseInData: true
basicAuth:
admin: "123456"
user: "654321"
apis:
- basePackage: "com.swagger.demo.controller.admin"
info: #可选
title: "在线文档"
description: "在线API文档"
termsOfService: "https://gitee.com/noear/solon"
version: 1.0
contact: #可选
name: "demo"
email: "demo@qq.com"
license: #可选
name: "demo"
url: "https://gitee.com/noear/solon/blob/master/LICENSE"
```
--------------------------------
### Configure Specific Logger Levels
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-logging/solon-logging/README.md
Define logging levels for specific packages like Apache ZooKeeper and Eclipse Jetty.
```yaml
solon.logging.logger:
"org.apache.zookeeper.*":
```
```yaml
level: "WARN"
"org.eclipse.jetty.*":
```
```yaml
level: "WARN"
```
--------------------------------
### Configure Web Service Path
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-web/solon-web-webservices/README.md
Specify a custom path segment for web services in the application configuration.
```yaml
server.webservices.path: "/ws/" #默认为 ws
```
--------------------------------
### Inject Nami Client with @NamiClient
Source: https://github.com/opensolon/solon/blob/main/__release/nami-bundle/README.md
Use the @NamiClient annotation to inject an instance of your service interface. This requires a LoadBalance component to be configured for the specified name.
```java
@Managed
public class Demo1{
@NamiClient(name="test", path="/ComplexModelService/")
IComplexModelService service;
public void test(){
ComplexModel tmp = service.read(1);
service.save(tmp);
}
}
```
```java
//构建一个test负载均衡组件
@Managed("test")
public class TestUpstream implements LoadBalance {
@Override
public String getServer() {
return "http://localhost:8080";
}
}
```
```java
//更改默认配置器的代理,将编码器换掉
NamiConfigurationDefault.proxy = (c,b)->b.encoder(SnackTypeEncoder.instance);
```
--------------------------------
### Inject Client-Side Web Service (Container Mode)
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-web/solon-web-webservices/README.md
Use @WebServiceReference annotation to inject a web service client into a Solon controller. Requires the service interface definition.
```java
//定义测试控制器
@Controller
public static class DemoController {
@WebServiceReference("http://localhost:8080/ws/HelloService")
private HelloService helloService;
@Mapping("/test")
public String test() {
return helloService.hello("noear");
}
}
//配置 WebService 接口
@WebService(serviceName = "HelloService", targetNamespace = "http://demo.solon.io")
public interface HelloService {
@WebMethod
String hello(String name);
}
//启动 Solon
public class ClientTest {
public static void main(String[] args) {
Solon.start(ClientTest2.class, args);
}
}
```
--------------------------------
### Add Solon Web Services Dependency
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-web/solon-web-webservices/README.md
Include the solon-web-webservices artifact in your project's dependencies.
```xml
org.noearsolon-web-webservices
```
--------------------------------
### Configure Solon Banner Plugin
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-config/solon-config-banner/README.md
Customize the banner's behavior by setting these properties in your Solon application configuration. The banner is enabled by default.
```yaml
#By default the banner is true
solon.banner.enable: true
#Where to print the banner , values console/log/both
solon.banner.mode: "console"
#Path to banner resource file
solon.banner.path: "banner.txt"
```
--------------------------------
### JavaScript WebSocket Connection and Subscription
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-net/solon-net-stomp/src/test/resources/static/user2.html
Establishes a WebSocket connection using StompJS, subscribes to various topics including user-specific and application-wide topics, and handles WebSocket close events.
```javascript
var stompClient = null; function setConnected(connected) { document.getElementById('connect').disabled = connected; document.getElementById('disconnect').disabled = !connected; document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden'; $('#response').html(); }
function connect() {
//https://stomp-js.github.io/api-docs/latest/classes/Client.html
var stompConfig = {
connectHeaders: {
'connectedCallUri': 'www.baidu.com?test=123',
'disconnectedCallUri': 'www.baidu.com?test=321',
"resource": "pc-web",
"name": "web测试"
},
disconnectHeaders: {},
debug: function (str) {
console.log(str);
},
//等于0则不自动重连
reconnectDelay: 5000,
heartbeatIncoming: 0,
heartbeatOutgoing: 0,
stompVersions: {
protocolVersions: function () { return []; },
supportedVersions: function(){ return []; }
},
onConnect: function (frame) {
setConnected(true);
console.info('Connected', frame);
stompClient.subscribe('/topic/todoTask1/\*', function (response) {
showResponse(response.body);
});
stompClient.subscribe('/app/todoTask1/\*', function (response) {
showResponse(response.body); //response.ack({"message-id": response.headers["message-id"]});
});
stompClient.subscribe('/user/app/errors', function (response) {
showResponse(response.body);
});
var subscription = stompClient.subscribe('/topic/todoTask2/\*', function (response) {
});
subscription.unsubscribe();
},
onWebSocketClose: function (frame) {
console.error("onWebSocketClose", frame);
setConnected(false);
}
}
var wsurl = $('#wsurl').val();
console.error("stompConfig", stompConfig);
stompClient = new StompJs.Client($.extend({ brokerURL: wsurl }, stompConfig));
stompClient.activate();
}
function disconnect(frame) {
if (stompClient != null) {
stompClient.deactivate();
}
stompClient = null;
setConnected(false);
}
```
--------------------------------
### Dynamic Data Source Switching with Annotations
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-data/solon-data-dynamicds/README.md
Use the @DynamicDs annotation to specify which data source to use for a method. The annotation can take a data source name as an argument, or if left empty, it uses the default data source within the configured dynamic data source.
```java
@ProxyComponent
public class UserService{
@Db("db_user")
UserMapper userMapper;
@DynamicDs //使用 db_user 动态源内的 默认源
public void addUser(){
userMapper.inserUser();
}
@DynamicDs("db_user_1") //使用 db_user 动态源内的 db_user_1 源
public void getUserList(){
userMapper.selectUserList();
}
public void getUserList2(){
DynamicDsHolder.set("db_user_2"); //使用 db_user 动态源内的 db_user_2 源
userMapper.selectUserList();
}
}
```
--------------------------------
### Maven Dependency for Solon Web Stop
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-web/solon-web-stop/README.md
Add this dependency to your Maven project to include the Solon web stop extension.
```xml
org.noearsolon-web-stop
```
--------------------------------
### JavaScript Stomp.js Message Sending Functions
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-net/solon-net-stomp/src/test/resources/static/user1.html
Provides functions to publish messages to different Stomp destinations. Includes options for message body, persistence, and acknowledgments.
```javascript
function send() {
if($('#message').val()){
stompClient.publish({
destination: "/topic/todoTask1/open",
body: $('#message').val(),
headers: {"openPersistence": "true", "openAck": "true"}
});
}
}
function send2() {
if($('#message').val()){
stompClient.publish({
destination: "/app/todoTask1/user",
body: $('#message').val(),
headers: {"openPersistence": "true", "openAck": "true", "user": "test001"}
});
}
}
function send3() {
if($('#message').val()){
stompClient.publish({
destination: "/app/todoTask1/self",
body: $('#message').val(),
headers: {"openPersistence": "true", "openAck": "true"}
});
}
}
function send4() {
if($('#message').val()){
stompClient.publish({
destination: "/app/todoTask1/error",
body: $('#message').val(),
headers: {"openPersistence": "true", "openAck": "true"}
});
}
}
```
--------------------------------
### Advanced JSON Formatting Customization with Snack3
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-serialization/solon-serialization-snack3/README.md
Customize JSON serialization by adding convertors for specific data types like Date, LocalDate, and LocalDateTime using SnackRenderFactory. This should be done before the plugin runs.
```java
public class DemoApp {
public static void main(String[] args){
Solon.start(DemoApp.class, args, app->{
initMvcJsonCustom();
});
}
/**
* 初始化json定制(需要在插件运行前定制)
*/
private static void initMvcJsonCustom() {
//通过转换器,做简单类型的定制
SnackRenderFactory.global
.addConvertor(Date.class, s -> s.getTime());
SnackRenderFactory.global
.addConvertor(LocalDate.class, s -> s.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
SnackRenderFactory.global
.addConvertor(LocalDateTime.class, s -> s.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")))
SnackRenderFactory.global.add
}
}
```
--------------------------------
### Add Solon Banner Dependency
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-config/solon-config-banner/README.md
Include this Maven dependency in your project to use the Solon Banner plugin.
```xml
org.noearsolon-banner
```
--------------------------------
### Solon-Flow FlowContext LastNodeId Usage
Source: https://github.com/opensolon/solon/blob/main/UPDATE_LOG.md
Demonstrates using FlowContext.lastNodeId() for interrupting and resuming flow execution in Solon-flow.
```java
flowEngine.eval(graph, context.lastNodeId(), context);
//...(从上一个节点开始执行)
flowEngine.eval(graph, context.lastNodeId(), context);
```
--------------------------------
### Beetl Template Rendering with Error
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-view/solon-view-beetl/src/test/resources/templates/beetl_out_error.htm
This snippet shows a Beetl template that attempts to render a non-existent object property, causing an error. It highlights the template's structure before and after the problematic rendering.
```html
${title} beetl模板引擎先渲染,再写入请求响应。 **之前** <% // entity.name 这是一个不存在的对象、属性,用于报错抛出 %> ${entity.name} **之后**
```
--------------------------------
### Remotely Shutting Down Service with Curl
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-web/solon-web-stop/README.md
Use the curl command to trigger the remote shutdown of the service. This is primarily for operational assistance.
```shell
curl http://127.0.0.1/_run/stop/
```
--------------------------------
### JavaScript Stomp.js Response Handling
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-net/solon-net-stomp/src/test/resources/static/user1.html
Appends received messages to the response area and scrolls to the bottom to show the latest message.
```javascript
function showResponse(message) {
var response = $('#response');
response.append(message + "");
var div = document.getElementById('response');
div.scrollTop = div.scrollHeight;
}
```
--------------------------------
### Advanced Fastjson Customization with Converters and Encoders
Source: https://github.com/opensolon/solon/blob/main/solon-projects/solon-serialization/solon-serialization-fastjson/README.md
Customize Fastjson serialization for specific data types like Date and LocalDate using global converters and encoders. This allows for fine-grained control over how these types are represented in JSON.
```java
public class DemoApp {
public static void main(String[] args){
Solon.start(DemoApp.class, args, app->{
initMvcJsonCustom();
});
}
/**
* 初始化json定制(需要在插件运行前定制)
* */
private static void initMvcJsonCustom(){
//通过转换器,做简单类型的定制
FastjsonRenderFactory.global.addConvertor(Date.class,
(JsonLongConverter) source -> source.getTime());
FastjsonRenderFactory.global.addConvertor(LocalDate.class,
(JsonStringConverter) source -> source.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
//通过编码器,做复杂类型的原生定制(基于框架原生接口)
FastjsonRenderFactory.global.addEncoder(Date.class, (ser, obj, o1, type, i) -> {
SerializeWriter out = ser.getWriter();
out.writeLong(((Date)obj).getTime());
});
}
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.