Stuartd's Blog


  • 首页

  • 分类

  • 归档

Git多人协作

发表于 2019-03-15 | 分类于 Git

Git多人协作

每次项目都是使用的git,整理下多人协作时git的流程。以一个在Gitlab上的TestProject作为例子

首先创建远程库

在对应的Git代码管理平台上创建一个项目,比如Gitlab,就new出一个项目

阅读全文 »

Jenkins 自动化部署

发表于 2019-03-09 | 分类于 Jenkins

Jenkins 自动化部署

久仰Jenkins大名,特前来做个Demo以此来学习Jenkins自动化部署

一. 使用场景

使用Jenkins + Git + Maven 在Ubuntu下自动化部署SpringBoot项目,将SpringBoot项目上传至Git的master分支上,然后Jenkins就将Git上的分支拉过来,使用Maven构建,并在服务器上运行

二. 部署步骤

1. 安装Jenkins

在官网上(https://jenkins.io/) 点击Download 之后,选择所要部署的服务器发行版,我的服务器用的阿里云(Ubuntu 16.0.4)所以选择 Ubuntu/Debian系列。进入之后按照官方提示操作

阅读全文 »

Jenkins + Gitlab 自动化部署

发表于 2019-03-09 | 分类于 Jenkins

Jenkins + Gitlab 自动化部署

前面用自己的服务器搭了个Jenkins + Github + Maven部署SpringBoot项目,上面所有都在一台机子上完成。但是很快,由于工作室的需要,因此这种全部集成在一台机子上的部署是行不通的,因此考虑使用远程连接服务器部署

之前描述的是Jenkins + Github + Maven在一台机子上部署SpringBoot项目,也就是说Jenkins在A服务器上,Maven在A服务器上,从Github拉取的源码在A服务器上,打包好的Jar包也在A服务器上,这种是最基础的自动化部署,同时也是不用怎么进行网络传输的部署方式。但是你想,如果一个初创企业,服务器只够买几台云服务器,而一些云服务器空间不大,大概也就是一台机部署一个项目的这样子,那要是按照上面说的单机部署,服务器肯定吃不消,而且一个企业内部商业项目也不太可能放到Github上,一般企业都是搭建自己的Gitlab服务器的,所以从安全性,可扩展性,以及内存争用问题上看,应该选择 Jenkins + Gitlab + Maven 自动化远程部署SpringBoot项目

阅读全文 »

Ubuntu下部署Gitlab并汉化

发表于 2019-03-08 | 分类于 Linux

Ubuntu下部署Gitlab并汉化

因为工作室原来的Gitlab挂了,服务器不再续费,所以重新部署Gitlab并且汉化

首先先看下官方文档,里面记录了一些主要步骤,但是由于环境因素,所以有些步骤不太适用

1. 安装并配置必要的依赖项

1
2
sudo apt-get update
sudo apt-get install -y curl openssh-server ca-certificates

安装Postfix以发送通知电子邮件

1
sudo apt-get install -y postfix

安装postfix过程中,选择“Internet Site”并按Enter键。使用服务器的外部DNS作为“邮件名称”,然后按Enter键。如果出现其他屏幕,请继续按Enter键接受默认值。(官网上的描述,照抄)

阅读全文 »

Spring中多线程事务处理

发表于 2019-02-20 | 分类于 项目杂谈

SpringMVC中绑定复杂数据

SpringMVC中可以实现将前端传过来的数据封装好。在此之前一直都是对一个实体的封装,但在青芒项目里,遇到两个关于SpringMVC数据绑定的问题

  1. SpringMVC一个请求绑定多个不同实体
  2. SpringMVC绑定实体里复杂的数据结构

SpringMVC一个请求绑定多个不同实体

场景:

接口中要保存活动信息,活动报名表,活动展示,活动的问答,其中活动的问答传过来是一串数组,而活动报名表里有一些复杂的数据结构

接口里的实体

解决办法:

对于一串数组,平日里传的话,就直接传,然后就会绑定到参数里了,就如同下面一样

1
2
@PostMapping(value = "/publish)
public void test(List<String> testString) {}

但是在多实体的情况下这样就不管用了,多实体的话,SpringMVC不知道这是数组啊,所以要使用@InitBinder去绑定

这里使用@InitBinder主要就是用以区分前端传过来的数据,使用WebDataBinder.setFieldDefaultPrefix()设置前缀用以区分,这里要特别留意一下:@InitBinder后面跟着的是某个类的类名的驼峰命名,如:Activity,@InitBinder(“activity”);ActivityRegister,@InitBinder(“activityRegister”)等等,而在webDataBinder.setFieldDefaultPrefix()中的字符串参数则是自己定义的,前端传数据过来带上这个前缀就知道哪个是哪个了,如下图

SpringMVC绑定实体里复杂的数据结构

场景:

同上,上面还有几个问题没有解决,就是活动QA就是以一串数组传过来的嘛,然后上面解决了如何区分多个实体,但却没有解决如何封装这些数组,以及一些复杂的数据结构

解决办法:

SpringMVC在多实体的情况下,貌似不能直接以List去封装的:

1
2
3
// 貌似在SpringMVC里这样是不可以的,数据绑定不到qaList上
@PostMapping(value = "/publish)
public void test(Activity activity, List<ActivityQA> qaList, ActivityShow show) {}

这样不行,我们换个法子,用一个实体来封装这些数据结构,这个实体应该叫VO吧,用来封装前端传过来的数据

QAListVO

这里也有个注意的地方就是前端传的时候,如果不加任何别名的话,应该是这样的

QAList

前缀 + 属性名[index] + QA里的属性名

如上 前缀 -> “activityQA.”,而ActivityQAListModel里的List属性名 activityQAList,所以以 activityQA.activityQAList[index] 去封装数据,index为索引

这样就解决了SpringMVC在多实体情况下绑定实体数组

但是这里的实例是List,List倒是明白了,Java里面有List,Map等数据结构,那又怎么办?同样还是一样的招数,只不过传的时候形式有点变化。

如下ActivityRegister, ActivityRegisterFormList,ActivityRegisterForm所示

ActivityRegister:

ActivityRegister

ActivityRegisterFormList:

ActivityRegisterFormList

ActivityRegisterForm:

ActivityRegisterForm

可以看到ActivityRegister中Map包含了ActivityRegisterFormList,List里用ActivityRegisterForm做元素,所展示出来大概就如下面一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
form: {
person: {
formList: [
{
title: 姓名,
type: 0,
ifNecessary: true,
ifChoice: false,
choice: null
},
{...},
{...}
]
}
}

这时Map中有List,对于List的数据绑定,前面已经介绍过了,直接 formList[0].title = 姓名,formList[0].type = 0,formList[0].ifNecessary = true这样,那么Map又如何?

Map的话,由于其是key-value结构,而List是索引-value结构,那么这样对比一下,List中的索引相对于Map的key,应该是有共通之处,所以,数据绑定的时候,招数是一样的,形式不同而已

ActivityRegister

直接以指定的字符串作为内容,后面接着List的格式,代表value就是一个List,那么整理一下格式就可以概括为:

map[key].list[index].属性名

拓展

上面介绍了List,Map<String, List>的情况,那么如果是List<Map<String, List>>这样的呢

像List<Map<String, List>>这样的,同理

list[index].map[key].list[index]这样

注意一点!!!就是Map<String, Map<String, String>>或者Map<String, Map<String, List>>这样的,直接套用上面的方法是不行的,这时建议审视数据结构,重新规划一下,因为本人就是一开始使用Map<String, Map<String, List>>这样的,发现无论怎样都不能比较方便直接地转换过来,这时重新审查自己的数据结构,结合业务,然后洗个澡,就把这个问题给解决了,重新建立了数据模型,在不影响业务需求的情况下,更好地进行访问,也不用再恶心地使用什么json字段,设置application/json这样的请求类型,传入不好校验,极其不安全的参数。

总结

  • 在多实体数据绑定情况下,使用@InitBinder + webdataBinder.setFieldDefaultPerfix()设置前缀去区分
  • List数据结构在多实体数据绑定情况下,使用一个VO去包装这个List,前端传过来,在不加别名的情况下,按照List的属性名传
  • List,Map数据结构的组合,基本掌握 List的数据传输格式为 list[index],Map的数据传输格式为 map[key] 这两种基本就可以了,同时注意Map中Map数据结构本人暂时没有办法解决,若有晓得的,可以告知我一下

##

Spring中多线程事务处理

发表于 2019-02-19 | 分类于 项目杂谈

Spring中多线程事务处理

在青芒第三次迭代时,一个活动模块需要同时处理多个实体的业务,而彼此业务间没有关联,但存在事务性,考虑再三,决定尝试使用多线程处理多个业务

在了解了Spring事务处理之后,使用 编程式事务处理 更为灵活,由于有多个线程,而每个线程对应一个数据库连接,所以在多线程环境中,事务不止一个,同理事务状态也不止一个,因此这里的解决办法就是 将所有线程的事务状态保存到一个同步集合(多线程环境下使用同步集合,保证线程安全),若某个线程出现错误,遍历所有线程的事务状态,循环回滚

阅读全文 »

笔记 - 关于继承与可重入锁

发表于 2019-01-20 | 分类于 Java多线程

继承与可重入锁

可重入锁在继承情况下super锁住的是谁。关于这个问题,设计了一个Demo

阅读全文 »

笔记 - 私有构造器捕获模式

发表于 2019-01-18 | 分类于 Java多线程

笔记 - 私有构造器捕获模式

看到一个比较有意思的东西–私有构造器捕获模式。

下面代码可以看到在testA处有个编译错误:Cannot reference ‘PrivateConstructor.testA’ before supertype constructor has been called。此处是说不能在超类构造器调用之前引用testA

错误实例

尝试解释一下,由于PrivateConstructor这个类继承自Parent,然后在构造的时候,先从Parent构造起来,由于PrivateConstructor构造器指明调用父类的带参数构造器,调用Parent的一个带参数的构造器。但是因为在PrivateConstructor构造器中,调用了还没被初始化的testA,所以报出了编译错误。

阅读全文 »

Linux下的ssr配置

发表于 2018-12-17 | 分类于 Linux

Linux下ssr配置

Linux下配置ssr,对于刚从Window转过来的小白用户实在是折腾,还好是看了同事的博客,教小白如何傻瓜式操作ssr配置,才慢慢懂得。Linux的知识实在是太欠缺了,去拜读一下鸟哥先。

服务端配置

  1. 下载ssr
1
wget http://www.texfox.com/ssr
  1. 将ssr移动到/usr/local/bin文件下
1
sudo mv ssr /usr/local/bin
  1. 修改文件的权限
1
sudo chmod 766 /usr/local/bin/ssr
  1. ssr install
1
ssr install
  1. ssr config,将从运营商获取的配置json信息填入里面
1
ssr config

这个操作会调起一个gedit的文本编辑器,将节点json信息配置到里面去就ok

  1. 开启ssr
1
ssr start

客户端配置

讲完服务端的配置,接下来就要说下客户端配置,例子将会在google上进行配置

  1. 下载google插件:SwitchyOmega

安装代理插件

  1. 将插件插入google中,直接拖动下载的文件到google浏览器的扩展程序中,就会识别
  2. 设置switchyomega
  • 第一步:配置auto switch

配置auto switch

首先设置情景模式为 proxy,如上图的第一个箭头,然后将 https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt这个url复制粘贴到规则列表地址上,这是被墙的url列表。当代理检测到你要访问里面的url时,认定你将要翻墙。最后点击立即更新情景模式

  • 第二步:配置proxy

配置proxy

这里配置的是proxy项,代理服务器填127.0.0.1,代理端口是1080,当然代理端口看运营方给你的端口设置。

到这里基本配置是完了,接下来的可能因每个人的Linux发行版不同而有所差别,笔者用的是 稍微有点低级的deepin(小白用户专用),所以接下来配置跟主流Linux发行版不太一样。

配置ssr自启动

deepin:

其他Linux发行版中 /etc下是应该有rc.local文件的,直接在rc.local文件上配置就行了,但是deepin呢就比较奇葩,他在最新版本没有rc.local,因此得另找门路

不过,根据官网的wiki deepin自启动程序里面介绍到,直接在/etc下创建个rc.local文件,然后配上以下代码

1
2
3
4
5
6
#!/bin/bash
# rc.local config file created by use

sudo ssr start

exit 0

然后修改下文件权限 sudo chmod +x /etc/rc.local ,然后重启,就会发现可以了。

Manjaro:

  1. 在/usr/lib/systemd/system下创建rc-local.service
1
sudo touch /usr/lib/systemd/system/rc-local.service
  1. 配置内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Unit]
Description="/etc/rc.local Compatibility"
ConditionPathExists=/etc/rc.local
After=network.target


[Service]
Type=forking
ExecStart=/etc/rc.local
TimeoutSec=0
#StandardInput=tty
RemainAfterExit=yes
SysVStartPriority=99

[Install]
WantedBy=multi-user.target
  1. 使该文件生效:
1
systemctl enable rc-local.service
  1. 在/etc下创建rc.local,并编辑,同时赋予权限
1
2
sudo touch rc.local
sudo vi rc.local
1
2
3
4
5
6
#!/bin/bash
# rc.local config file created by use

sudo ssr start

exit 0
1
sudo chmod +x /etc/rc.local
  1. 使得该rc.local生效
1
systemctl enable rc-local.service

Ubuntu换镜像源

发表于 2018-12-17 | 分类于 Linux

Ubuntu换镜像源

由于在deepin下过渡的时间够长了,也基本适应了win转Linux了,所以打算考完试换下系统,特地记录一下一些必要的操作

1. 备份原来的镜像源

1
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

2. 修改镜像源

1
sudo gedit /etc/apt/sources.list
阅读全文 »
12…4

Stuartd

不定时更新一些技术上的坑或者吐槽之类的

34 日志
11 分类
© 2019 Stuartd
|
主题 — NexT.Gemini v5.1.4
本站总访问量次