2024-08-23



package main
 
import (
    "fmt"
    "github.com/gin-gonic/gin"
    "net/http"
)
 
// 自定义中间件
func MyMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        fmt.Println("中间件开始执行")
        // 在这里可以进行一些预处理操作
        // 调用下一个中间件或控制器
        c.Next()
        // 在这里可以进行一些后处理操作
        fmt.Println("中间件执行结束")
    }
}
 
// 自定义控制器
func CustomController(c *gin.Context) {
    name := c.Query("name")
    c.String(http.StatusOK, "Hello %s", name)
}
 
func main() {
    router := gin.Default() // 创建一个带有默认中间件的路由引擎
 
    // 使用自定义中间件
    router.Use(MyMiddleware())
 
    // 创建一个基本路由
    router.GET("/hello", CustomController)
 
    // 启动服务器
    router.Run(":8080")
}

这段代码定义了一个自定义的中间件MyMiddleware和一个自定义的控制器CustomController。在main函数中,我们创建了一个带有默认中间件的Gin路由引擎,并使用Use方法加入了自定义的中间件。然后,我们定义了一个基本的GET路由,并将自定义控制器绑定到该路由上。最后,我们启动服务器,监听8080端口的请求。

2024-08-23



const log4js = require('log4js');
 
// 配置log4js
log4js.configure({
  appenders: {
    console: { type: 'console' },
    access: { type: 'dateFile', filename: 'logs/access.log', pattern: 'yyyy-MM-dd', alwaysIncludePattern: true },
    app: { type: 'dateFile', filename: 'logs/app.log', pattern: 'yyyy-MM-dd', alwaysIncludePattern: true }
  },
  categories: {
    default: { appenders: ['console', 'app'], level: 'info' },
    http: { appenders: ['console', 'access'], level: 'info' }
  }
});
 
const logger = log4js.getLogger('http');
 
// Koa2日志记录中间件
const logMiddleware = () => {
  return async (ctx, next) => {
    const start = Date.now();
    await next();
    // 路径、状态码、响应时间
    logger.info(`${ctx.method} ${ctx.url} ${ctx.status} - ${Date.now() - start}ms`);
  };
};
 
module.exports = logMiddleware;

这段代码定义了一个Koa2中间件,用于记录每个HTTP请求的方法、URL、状态码和响应时间。它使用了log4js库来进行日志记录,并且将日志输出到控制台和文件中。这个例子展示了如何在实际应用中使用log4js进行日志管理。

2024-08-23



DELIMITER $$
 
CREATE TRIGGER `trigger_after_data_fowarding` AFTER INSERT ON `source_table`
FOR EACH ROW
BEGIN
    DECLARE v_source_id INT;
    DECLARE v_destination_id INT;
    -- 假设source_table有id字段,destination_table有source_id字段
    -- 获取新插入数据的id
    SELECT NEW.id INTO v_source_id;
    -- 假设data_forwarding_function是一个返回目的地表id的函数
    SET v_destination_id = data_forwarding_function(v_source_id);
    -- 假设destination_table有source_id和destination_id字段
    -- 插入数据到目的地表
    INSERT INTO destination_table (source_id, destination_id) VALUES (v_source_id, v_destination_id);
END$$
 
DELIMITER ;

这个示例代码创建了一个名为trigger_after_data_fowarding的触发器,它会在source_table上的每次插入操作之后执行。触发器会获取新插入行的id,然后调用一个假设的data_forwarding_function函数来获取目标表的destination_id,最后将源表的source_id和目标表的destination_id插入到目标表中。这个过程可以作为数据投递中间件的一个简单示例。

2024-08-23

在Node.js中,Express是一个非常流行的web开发框架,它提供了一种简单的方法来创建web服务器,并处理HTTP请求。

在第七章中,我们主要讨论了Express的路由和中间件。

路由:

路由是指确定应用程序如何响应客户端请求的过程。在Express中,我们可以使用app.get(), app.post(), app.use()等方法来定义路由。




const express = require('express');
const app = express();
 
app.get('/', (req, res) => {
  res.send('Hello World!');
});
 
app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

在上述代码中,我们定义了一个路由处理器,当客户端向根URL('/')发送GET请求时,服务器将响应'Hello World!'。

中间件:

中间件是一个函数,它可以访问请求对象(req)、响应对象(res)和next函数。在中间件函数内部,可以执行任何代码,并在必要时继续执行下一个中间件或路由处理器。




const express = require('express');
const app = express();
 
app.use((req, res, next) => {
  console.log('Incoming request');
  next();
});
 
app.get('/', (req, res) => {
  res.send('Hello World!');
});
 
app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

在上述代码中,我们定义了一个中间件,它会在控制台输出'Incoming request',然后继续执行下一个中间件或路由处理器。

错误处理中间件:

错误处理中间件是一种特殊的中间件,它用于处理在应用程序中发生的错误。




const express = require('express');
const app = express();
 
app.get('/', (req, res) => {
  // 制造一个错误
  throw new Error('Something went wrong');
});
 
app.use((err, req, res, next) => {
  console.error(err.message);
  res.status(500).send('Internal Server Error');
});
 
app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

在上述代码中,我们定义了一个错误处理中间件,它会捕获应用程序中发生的任何错误,并将错误的消息打印到控制台,同时向客户端返回500响应码和'Internal Server Error'。

以上就是Node.js中Express框架的路由和中间件的基本使用方法。

2024-08-23



package main
 
import (
    "github.com/gin-gonic/gin"
    "net/http"
)
 
// 局部中间件,仅应用于特定路由
func localMiddleware(c *gin.Context) {
    // 在调用下游处理器之前执行的逻辑
    c.Writer.Header().Set("X-Local-Middleware", "true")
    c.Next() // 调用下一个中间件或路由处理器
    // 在调用下游处理器之后执行的逻辑
}
 
// 全局中间件,应用于所有路由
func globalMiddleware(c *gin.Context) {
    // 在调用下游处理器之前执行的逻辑
    c.Writer.Header().Set("X-Global-Middleware", "true")
    c.Next() // 调用下一个中间件或路由处理器
    // 在调用下游处理器之后执行的逻辑
}
 
func main() {
    router := gin.Default() // 创建一个带有默认中间件的路由器
 
    // 全局注册中间件
    router.Use(globalMiddleware)
 
    // 创建一个分支路由,并注册局部中间件
    api := router.Group("/api")
    api.Use(localMiddleware)
    {
        api.GET("/hello", func(c *gin.Context) {
            c.String(http.StatusOK, "Hello from API")
        })
    }
 
    // 启动服务器
    router.Run(":8080")
}

这段代码演示了如何在Gin框架中定义和使用局部和全局中间件。首先定义了两个中间件函数localMiddlewareglobalMiddleware。然后在路由器中全局注册了globalMiddleware,并在特定分支路由上注册了localMiddleware。最后,在:8080端口启动了服务器。

2024-08-23

在Node.js中,中间件是一种用于处理HTTP请求和响应的函数,它可以访问请求对象(request)、响应对象(response)以及应用程序的请求-响应循环内的next函数。中间件的一个常见用途是日志记录、身份验证、会话处理、错误处理等。

以下是一个简单的中间件示例,它记录每个请求的路径,并调用next()函数以继续执行下一个中间件或路由处理程序:




function logRequestPath(req, res, next) {
    console.log('Requested path:', req.path);
    next(); // 调用下一个中间件或路由处理程序
}
 
// 使用中间件的示例
const express = require('express');
const app = express();
 
app.use(logRequestPath); // 注册中间件
 
app.get('/', (req, res) => {
    res.send('Hello World!');
});
 
app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

在这个例子中,当你访问 http://localhost:3000/ 时,你会在控制台看到输出 "Requested path: /",然后你会看到 "Hello World!" 响应。这是因为注册的中间件在请求到达路由处理程序之前执行,并且通过调用next()函数,请求-响应循环继续进行。

2024-08-23

通关步骤:

  1. 使用Burp Suite抓包修改请求,发送到weblogic模块。
  2. 使用Burp Suite的Repeater模块重发请求,注意修改Content-Length

具体操作:

  1. 打开Burp Suite并开始抓取流量。
  2. 使用浏览器访问http://your-ip:8080/iwebsec\_weblogic\_war\_exploded/,进入Web应用。
  3. 在Burp Suite中找到到达Tomcat服务器的流量,并将其发送到Repeater。
  4. 在Repeater中修改请求,例如修改Content-Length,确保请求长度与修改后的内容长度一致。
  5. 发送修改后的请求到Tomcat服务器,并查看响应。

注意:

  • 请确保在修改请求时保留原始请求的必要头信息,如HostUser-Agent等。
  • 修改Content-Length以匹配修改后的请求体长度。
  • 如果遇到问题,可以尝试不同的修改,并观察响应来确定是否成功。
2024-08-23

Redis的过期策略主要是通过定时任务和惰性删除相结合的方式来管理键的生命周期。

  1. 定时任务:Redis 会定期遍历一部分键,检查其是否过期,并删除过期键。
  2. 惰性删除:当一个键被访问(GET/SET)时,Redis 会检查它是否过期,如果过期就删除它。



// 伪代码示例:Redis 过期策略的核心函数
 
// 定时任务处理函数
void activeExpireCycle(void) {
    // 遍历数据库中的键,检查是否过期
    for (int i = 0; i < db->dict->size; i++) {
        dictEntry *de = dictGetRandomKey(db->dict);
        if (de) {
            dictEntry *expired = dbExpireIfNeeded(de);
            if (expired) {
                // 删除过期键
                deleteExpired(expired);
            }
        }
    }
}
 
// 检查键是否过期,如果过期返回1,否则返回0
int checkIfExpired(dictEntry *de) {
    // 检查键的过期时间
    if (de->expire) {
        if (mstime() > de->expire) {
            return 1;
        }
    }
    return 0;
}
 
// 惰性删除
void lazyExpire(dictEntry *de) {
    if (checkIfExpired(de)) {
        // 键过期,从数据库中删除
        deleteKey(db, de);
    }
}

注意:以上代码仅为示例,实际的 Redis 代码实现会更加复杂,包括对时间和资源的精细管理。

2024-08-23

Sharding-JDBC 是一款由当当网开源的分库分表中间件。以下是一个使用 Sharding-JDBC 进行分库分表的简单示例。

  1. 添加 Maven 依赖:



<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-core</artifactId>
    <version>最新版本</version>
</dependency>
  1. 配置分库分表规则。在 sharding-jdbc.yml 文件中配置数据源和分片规则:



shardingRule:
  tables:
    t_order:
      actualDataNodes: ds${0..1}.t_order_${0..1}
      databaseStrategy:
        standard:
          shardingColumn: user_id
          shardingAlgorithmName: database_inline
      tableStrategy:
        standard:
          shardingColumn: order_id
          shardingAlgorithmName: table_inline
  bindingTables:
    - t_order,t_order_item
  defaultDatabaseStrategy:
    standard:
      shardingColumn: user_id
      shardingAlgorithmName: database_inline
  defaultTableStrategy:
    none:
  shardingAlgorithms:
    database_inline:
      type: INLINE
      props:
        algorithm-expression: ds${user_id % 2}
    table_inline:
      type: INLINE
      props:
        algorithm-expression: t_order_${order_id % 2}
  dataSources:
    ds0:
      url: jdbc:mysql://localhost:3306/ds0
      username: root
      password:
    ds1:
      url: jdbc:mysql://localhost:3306/ds1
      username: root
      password:
  1. 使用 Sharding-JDBC 进行数据库操作:



// 配置数据源
DataSource dataSource = ShardingDataSourceFactory.createDataSource(yamlFile);
// 获取连接
Connection conn = dataSource.getConnection();
 
// 执行SQL
String sql = "INSERT INTO t_order (user_id, order_id) VALUES (?, ?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, 10);
pstmt.setInt(2, 1000);
pstmt.executeUpdate();
 
// 关闭连接
pstmt.close();
conn.close();

在这个例子中,我们配置了基于用户ID和订单ID的分库分表规则,并展示了如何使用 Sharding-JDBC 进行数据库操作。在实际应用中,你需要根据自己的数据库环境和需求进行相应的配置调整。

2024-08-23

MyCat 是一个开源的数据库分库分表中间件,用于实现 MySQL 数据库的高可用、高性能和伸缩性。

以下是一个简单的 MyCat 配置示例,用于展示如何配置 MyCat 以实现数据库的分库分表:




<mycat:schema xmlns:mycat="http://io.mycat/">
    <!-- 配置数据库服务器 -->
    <mycat:dataNode name="dn1" dataHost="localhost1" database="db1" />
    <mycat:dataNode name="dn2" dataHost="localhost2" database="db2" />
 
    <!-- 配置数据主机 -->
    <mycat:dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
                   writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
        <mycat:heartbeat>select user()</mycat:heartbeat>
        <mycat:writeHost host="hostM1" url="localhost:3306" user="user1" password="password1">
            <mycat:readHost host="hostS1" url="localhost:3306" user="user1" password="password1" />
        </mycat:writeHost>
    </mycat:dataHost>
 
    <!-- 配置分片规则 -->
    <mycat:table name="tb1" dataNode="dn1,dn2" rule="auto-sharding-long" />
</mycat:schema>

在这个配置中,我们定义了两个数据节点 dn1dn2,它们分别连接到两个不同的数据库服务器上。我们还定义了一个分片规则 auto-sharding-long,它会根据记录中的某个长型字段的值来决定记录应该存储在哪个数据节点上。

要注意的是,MyCat 配置非常灵活,可以根据实际需求进行更多复杂的配置。上述配置仅为一个简单的示例,实际使用时需要根据具体环境进行调整。