tonglin0325的个人主页

如何使用Hexo搭建静态博客

介绍如何使用Hexo和Github搭建静态博客
使用的主题为Bootstrap
搭建的环境是ubuntu 14.04 LTS

<1>什么是Hexo

Hexo 是一款基于node 的静态博客网站生成器,作者:tommy351是一个台湾的在校大学生。 相比其他的静态网页生成器而言有着,生成静态网页最快,插件丰富(已经移植了大量Octopress插件)。 同其他很多轻量级博客如jekyll、octopress、jekyllbootstrap等一样,也是使用Markdown语法进行编辑博文,即编辑.md后缀的文件。

hexo的github主页地址: Hexo_Github
Markdown的中文语法: Hexo_Docs

全文 >>

Chrome使用笔记

1.开启debug模式

可以通过在启动命令中添加

1
2
--remote-debugging-port=9222

来开启chrome的debug端口,这样就可以通过这个端口来获取或者操作chrome,如下

macos

1
2
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222

linux

1
2
google-chrome --remote-debugging-port=9222

windows

1
2
3
右键点击 Chrome 的快捷方式图标,选择属性
在目标一栏,最后加上--remote-debugging-port=9222 注意要用空格隔开

可以打开另一个chrome浏览器B来监控开启了debug端口的chrome浏览器A

全文 >>

Glide和Govendor安装和使用

下面介绍几种go的包管理工具,推荐使用go mod

1.go mod

参考:go学习笔记——引入依赖

2.Glide

参考golang 依赖管理

/etc/profile

1
2
3
4
5
6
#Go
export GOROOT=/home/lintong/software/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
export GOPATH=/home/lintong/software/gopath
export GOBIN=$GOROOT/bin

Linux下安装

1
2
curl https://glide.sh/get | sh

Mac下安装

1
2
brew install glide

初始化

1
2
glide init

依赖下载

1
2
glide update

全文 >>

代理前端请求到本地服务

在开发过程中,有时候我们需要将前端的请求(当然也可以是部分请求)代理到我们的本地开发环境的服务中进行调试,下面借助whistle+SwitchyOmega来实现这个功能

1.安装whistle

1
2
3
4
5
6
7
8
9
npm install whistle -g --registry=https://registry.npmmirror.com

added 130 packages in 8s
npm notice
npm notice New major version of npm available! 9.1.2 -> 10.5.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.5.0
npm notice Run npm install -g npm@10.5.0 to update!
npm notice

启动

1
2
3
4
5
6
7
8
9
10
11
w2 start

[i] whistle@2.9.66 started
[i] 1. use your device to visit the following URL list, gets the IP of the URL you can access:
http://127.0.0.1:8899/
http://192.168.8.188:8899/
Note: If all the above URLs are unable to access, check the firewall settings
For help see https://github.com/avwo/whistle
[i] 2. set the HTTP proxy on your device with the above IP &amp; PORT(8899)
[i] 3. use Chrome to visit http://local.whistlejs.com/ to get started

启动后访问http://127.0.0.1:8899/界面如下

2.浏览器安装SwitchyOmega插件

将proxy设置成代理到whistle的8899端口,并将127.0.0.1的本地代理限制删掉

并将改proxy启动

3.代理前端请求

比如我们要代理https://xx.com/api/abc的接口代理到我们本地的http://127.0.0.1/api/v2/abc的服务上,这时我们应该如下配置

全文 >>

MySQL学习笔记——SQL注入

1.常见SQL注入的方法

假设我们使用goland的GORM框架写了以下面SQL

1
2
3
4
5
6
err := u.data.db.Raw("select id, username, email from user where username = '" + s + "'").Scan(&amp;user).Error
if err != nil {
u.log.Error(fmt.Sprintf("find user by id username fail, error: %v", err))
return nil, err
}

如果正常的查询参数的值为test123,请求如下接口传入该值

1
2
http://localhost:8080/api/v1/user?username=test123

接口输出的结果为

1
2
3
4
5
6
7
8
9
10
11
12
{
"Code": 200,
"Msg": "find user by username success",
"Data": [
{
"id": 18,
"username": "test123",
"email": "test@test123"
}
]
}

但是使用字符串拼接来实现查询逻辑的话,很容易被人使用SQL注入的方法进行攻击

1.Error-based

基于错误的SQL注入主要是用于获得数据的相关信息,方便进行后序的攻击,比如输入单引号 ‘

1
2
http://localhost:8080/api/v1/user?username='

此时从接口的返回值中就可以知道使用的是MySQL数据库

全文 >>

SpringMVC学习笔记——HelloWord Servlet

1.实现servlet打印日志

开发一个动态web资源,即开发一个Java程序向浏览器输出数据,需要完成以下2个步骤:

1.编写一个Java类,实现Servlet接口

开发一个动态web资源必须实现javax.servlet.Servlet接口,Servlet接口定义了Servlet引擎与Servlet程序之间通信的协议约定

以下是MyServlet.java文件中的代码(写的这个类的名字叫做MyServlet):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package org.MyServlet.MyServlet;

import java.io.IOException;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

//开发一个动态web资源必须实现javax.servlet.Servlet接口
//Servlet接口定义了Servlet引擎与Servlet程序之间通信的协议约定

//Q:MyServlet完成了一个动态网页程序,或者说是一个功能,如何让客户端能否准确得找到我们得这个Servlet服务
//A:服务器需要预先为我们预留出扩展接口,我们只需要按照一定的规则去提供相应的扩展功能

//Q:如何和服务器进行通讯
//A:web.xml就是服务器提供给我们的完成功能的地方
public class MyServlet implements Servlet{

@Override
public void destroy() {
// TODO Auto-generated method stub

}

@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}

@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}

@Override
public void init(ServletConfig arg0) throws ServletException {
// TODO Auto-generated method stub

}

//所有客户端请求会自动调用Service方法进行处理
//ServletRequest 是一个对象,封装所有HTTP请求信息
//ServletResponse 是一个对象,封装所有HTTP响应信息
//这两个对象是Tomcat服务器给我们的
@Override
public void service(ServletRequest arg0, ServletResponse arg1)
throws ServletException, IOException {
// TODO Auto-generated method stub

System.out.println("执行 MyServlet 的 service() 方法。。。。。");
}

}

关于其中的Service方法的一些Tip:  

1
2
3
4
5
6
7
//所有客户端请求会自动调用Service方法进行处理
//ServletRequest 是一个对象,封装所有HTTP请求信息
//ServletResponse 是一个对象,封装所有HTTP响应信息
//这两个对象是Tomcat服务器给我们的

此外,如果是只实现service方法,则称为适配器模式

以下是web.xml文件中的代码:



MyServlet

index.html
index.htm
index.jsp
default.html
default.htm
default.jsp


//定义一个Servlet服务
//Servlet服务的名字叫做aaa

aaa
org.MyServlet.MyServlet.MyServlet


//定义一个Servlet服务的映射关系
//Servlet服务的名字叫做aaa
//请求的路径是/myServlet.do

//1.服务器启动模式加载webapps下面所有的应用,加载web应用的时候会读取每个应用的web。xml文件
//2.客户单发送请求http://127.0.0.1:8080/MyServlet/myServlet.do
//3.请求就找到http://127.0.0.1:8080,找到MyServlet(Context)
//去mapping里面查找/myServlet.do,如果找到,定位到aaa
//4.去Servlet的定义里面查找Servlet-name是aaa的Servlet服务
//然后定位到org.MyServlet.MyServlet.MyServlet,执行该class的service方法

aaa
/myServlet.do

然后在浏览器中输入

1
2
http://127.0.0.1:8080/MyServlet/myServlet.do

全文 >>

Mybatis学习笔记——mybatis-generator

通用mabatis-generator可以由mysql表自动生成model类,mapper映射文件和mapper接口,参考:MyBatis通用Mapper和PageHelper

1.依赖

1
2
3
4
5
6
7
8
9
10
11
12
<!-- mybatis -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>3.3.9</version>
</dependency>

2.插件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!-- mybatis-generator -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.5</version>
<configuration>
<configurationFile>src/main/resources/generator-config.xml</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>3.3.9</version>
</dependency>
</dependencies>
</plugin>

3.在application.properties中配置数据库相关参数

1
2
3
4
5
6
# mysql
spring.datasource.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&amp;characterEncoding=utf-8&amp;useLegacyDatetimeCode=false&amp;serverTimezone=Hongkong&amp;zeroDateTimeBehavior=convertToNull
spring.datasource.username=root
spring.datasource.password=xxxx
spring.datasource.driver=com.mysql.jdbc.Driver

4.配置generator-config.xml,其中通用MyMapper参考:Mybatis学习笔记——通用mapper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
<!-- 引用外部配置文件-->
<properties resource="application.properties" />

<context id="context" targetRuntime="MyBatis3Simple">
<!-- MapperPlugin -->
<plugin type="tk.mybatis.mapper.generator.MapperPlugin">
<!-- 该配置会使生产的Mapper自动继承MyMapper -->
<property name="mappers" value="com.example.demo.core.mapper.MyMapper" />
<!-- caseSensitive默认false,当数据库表名区分大小写时,可以将该属性设置为true -->
<property name="caseSensitive" value="false"/>
</plugin>
<!-- 去掉生成出来的代码的注解 -->
<commentGenerator>
<property name="suppressAllComments" value="true" />
<property name="suppressDate" value="true" />
</commentGenerator>
<!-- 数据库信息 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="${spring.datasource.url}"
userId="root"
password="xxxx">
</jdbcConnection>
<!-- 生成Model类的包名和位置 -->
<javaModelGenerator targetPackage="com.example.demo.model" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- 生成Mapper映射文件的包名和位置 -->
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- 生成Mapper接口的包名和位置 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.example.demo.mapper" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 要生成代码的表 tableName=%时为所有表生成 表名字段名都有默认规则生成 -->
<table tableName="%">
<!-- 指定生成的主键属性名 生成SQL语句的类型 -->
<generatedKey column="id" sqlStatement="MySql"/>
</table>
</context>

</generatorConfiguration>

5.生成,点击plugin中的mabatis-generator:generate

全文 >>

SpringBoot学习笔记——Tomcat

SpringBoot默认的web容器是tomcat,在启动springboot应用的时候,会启动一个嵌入的apache tomcat实例。

当然springboot也支持其他的web容器,比如jetty

 

Spring Framework 从 Spring 3.0 开始支持嵌入式 Tomcat,但直到 Spring Boot 发布(2015年),嵌入式容器才成为一个真正普遍且简化的标准做法。对于Spring 3.0 之前的版本,仍然需要将应用打包成war包,部署在tomcat中。

将war包部署到tomcat中,可以参考:How-to-deploy-Spring-Boot-to-Apache-Tomcat

 

Tomcat目录结构

1
2
3
4
5
6
7
8
1.bin      存放启动和关闭Tomcat的脚本文件
2.conf      存放Tomcat服务器的各种配置文件
3.lib      存放Tomcat服务器的支持jar包
4.logs      存放Tomcat的日志文件
5.temp     存放Tomcat运行时产生的临时文件
6.webapps   web应用所在目录,即供外界访问的web资源的存放目录
7.work      Tomcat的工作目录

 

关于端口冲突

  1.HTTP的8080端口冲突,需要修改server.xml中端口的值

  2.启动多个Tomcat时端口冲突:Address in use: JVM_Bind

全文 >>

SpringBoot学习笔记——kaptcha

kaptcha是一个java验证码生成框架,可以和spring集成用于验证码服务

和spring集成的官方文档

1
2
https://code.google.com/archive/p/kaptcha/wikis/SpringUsage.wiki

1.依赖

1
2
3
4
5
6
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>

2.kaptcha生成验证码的配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;

@Configuration
public class KaptchaConfig {

/**
* 验证码生成器参数
*/
@Bean
public DefaultKaptcha captchaProducer() {
DefaultKaptcha captchaProducer = new DefaultKaptcha();
Properties properties = new Properties();
properties.setProperty(Constants.KAPTCHA_IMAGE_WIDTH, "100");
properties.setProperty(Constants.KAPTCHA_IMAGE_HEIGHT, "30");
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_SIZE, "22");
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "6");
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
properties.setProperty(Constants.KAPTCHA_BORDER_COLOR, "LIGHT_GRAY");
properties.setProperty(Constants.KAPTCHA_BACKGROUND_CLR_FROM, "WHITE");
properties.setProperty(Constants.KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");
properties.setProperty(Constants.KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_STRING, "0123456789");
properties.setProperty(Constants.KAPTCHA_SESSION_CONFIG_KEY, "checkCode");
Config config = new Config(properties);
captchaProducer.setConfig(config);
return captchaProducer;
}

}

配置的含义参考

1
https://code.google.com/archive/p/kaptcha/wikis/ConfigParameters.wiki

验证码图片生成接口

全文 >>

数据仓库建模的一些理论

1.数据分层

数据明细层:DWD(Data Warehouse Detail)

数据中间层:DWM(Data WareHouse Middle)

数据服务层:DWS(Data WareHouse Servce)

数据应用层:ADS(Application Data Service)

2.数仓建模方法

在数据仓库模型中,星型模型和雪花型模型是两个常用的设计模式。参考:数据仓库系列:星型模型和雪花型模型

1.星型模型

星型模型是一种简单的数据仓库模型,也是最常见的模型之一。在星型模型中,中心表(称为业务事实表)连接到几个维度表(称为业务维度表)。维度表中包含了业务的各个特征,如时间、区域、产品等。

在 SQL 中,我们可以使用以下语句来创建一个星型模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
CREATE TABLE fact_sales ( # 都是key
sales_id INT PRIMARY KEY,
date_key INT,
product_key INT,
store_key INT,
sales_amount DECIMAL(15,2)
);

CREATE TABLE dim_date (
date_key INT PRIMARY KEY,
date_full DATE,
year INT,
quarter INT,
month INT,
day_of_week CHAR(9),
holiday VARCHAR(32)
);

CREATE TABLE dim_product (
product_key INT PRIMARY KEY,
product_name VARCHAR(128),
category VARCHAR(32),
subcategory VARCHAR(32)
);

CREATE TABLE dim_store (
store_key INT PRIMARY KEY,
store_name VARCHAR(128),
city VARCHAR(32),
state VARCHAR(2),
country VARCHAR(64)
);

2.雪花型模型

雪花型模型是在星型模型基础上的扩展,因其形似雪花而得名。这种模型在星型模型的基础上,将维度表拆分成更小的表形式,形成多层表的结构。

全文 >>