简介

大致流程
/*
1.开发人员每天把代码提交到Gitlab代码仓库
2.jenkins从gitlab中拉取项目源码,编译并打包成war包,然后构建Docker镜像,将镜像上传到Harbor私有仓库
3.jenkins发送ssh远程命令,让生产部署服务到Harbor私有仓库拉取镜像到本地,然后创建容器
4.最后,用户就可以访问到容器
*/

SpringCloud微服务源码概述

/*
项目架构: 前后端分离
后端技术栈: SpringBoot+SpringCloud+SpringDatajpa(Spring全家桶)
*/ /*
微服务项目结构
tensquare_parent: 父工程,存放基础配置
tensquare_common: 通用工程
tensquare_eureka_server: SpringCloud的Eureka注册中心
tensquare_zull: SpringCloud的网关服务
tensquare: 基础权限认证中心,负责用户认证(使用jwt认证)
tenquare_guathering: 一个简单的业务模块,活动微服务相关逻辑
*/ /*
数据库结构
tensquare_user: 用户认证数据库,存放用户账号数据,对应tensquare_admin_service微服务
tensquare_gathering: 活动微服务数据库,对应tensquare_gathering微服务
*/ /*
微服务配置分析
tensquare_eureka
tensquare_zuul
tensquare_admin_service
tensquare_gathering
*/

部署Docker

安装必要系统工具和软件源
# 安装一些必要的系统工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加软件源信息
# docker 官方源
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 阿里云源
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装并启动Docker-ce
# 安装前可以先更新 yum 缓存:
sudo yum makecache fast # CentOS7安装 Docker-ce
yum -y install docker-ce # CentOS 中安装
apt-get install docker-ce # Ubuntu 中安装
pacman -S docker # Arch 中安装
emerge --ask docker # Gentoo 中安装 # 如果想安装特定版本的Docker-ce版本,先列出repo中可用版本,然后选择安装
yum list docker-ce --showduplicates |sort -r
Loading mirror speeds from cached hostfile
Loaded plugins: fastestmirror
Installed Packages
docker-ce.x86_64 3:19.03.4-3.el7 docker-ce-stable
docker-ce.x86_64 3:19.03.4-3.el7 @docker-ce-stable
docker-ce.x86_64 3:19.03.3-3.el7 docker-ce-stable
docker-ce.x86_64 3:19.03.2-3.el7 docker-ce-stable
docker-ce.x86_64 3:19.03.1-3.el7 docker-ce-stable yum install docker-ce-<VERSION STRING>
# 选择安装 docker-ce-18.06.1.ce
yum install docker-ce-18.06.1.ce -y # Docker镜像加速
# 没有启动/etc/docker目录不存在,需要自己创建,docker启动也会自己创建
# 为了期望我们的镜像下载快一点,应该定义一个镜像加速器,加速器在国内
mkdir /etc/docker
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"]
} # 或者使用阿里云的
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://yj9iu9ne.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker # 启动Docker后台服务
systemctl start docker && systemctl enable docker
systemctl daemon-reload # 守护进程重启 # 通过运行hello-world镜像,验证是否正确安装了docker,或者通过查看版本
docker run hello-world
docker version
Client: Docker Engine - Community
Version: 19.03.4
API version: 1.40
Go version: go1.12.10
Git commit: 9013bf583a
Built: Fri Oct 18 15:52:22 2019
OS/Arch: linux/amd64
Experimental: false
docker使用

docker使用请看我前面写的docker blog

https://www.cnblogs.com/you-men/category/1789332.html

使用dockerfile制作微服务镜像

1.上传Eureka的微服务jar包到linux

2.编写Dockerfile

FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 10086
ENTRYPOINT ["java","-jar","/app.jar"]

3.构建镜像

docker build --build-arg JAR_FILE=tensquare_eureka_server-1.0-SNAPSHOT.jar -t eureka:v1 .

4.查看镜像是否创建成功

docker images

5.创建容器

docker run -i --name=eureka -p 10086:10086 eureka:v1

部署配置Harbor

安装docker-compose
curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 对二进制文件应用可执行权限:
sudo chmod +x /usr/local/bin/docker-compose
# 测试是否安装成功
docker-compose --version
解压安装配置harbor
# 解压
tar xf harbor-offline-installer-v1.9.2.tgz
mkdir /opt/harbor
mv harbor/* /opt/harbor
cd /opt/harbor # 配置
vim harbor.yml
hostname: 192.168.1.8
port: 88 # 安装
./install
启动访问harbor
# 启动
docker-compose up -d # 停止
docker-compose stop # 重新启动
docker-compose restart # 访问harbor
# IP:88
# 默认账户密码: admin/Harbor12345

创建项目
# Harbor的项目分为公有和私有的:
# 公有项目: 所有用户都可以访问,通常你存放公共镜像,默认有一个library公开项目
# 私有项目: 所有授权用户才可以访问,通常存放项目本身的镜像

创建用户

给项目分配用户

角色 权限说明
访客 对于指定项目拥有只读权限
开发人员 对于指定项目拥有读写权限
维护人员 对于指定项目拥有读写权限,创建Webhooks
项目管理员 除了读写权限,同时拥有用户管理/镜像扫描管理权限
以新用户登录Harbor

镜像上传Harbor

1. 给镜像打标签

docker tag nginx:latest 192.168.1.8/tensquare/nginx:v1

2. 将Harbor地址加入到Docker信任列表

vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://yj9iu9ne.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.1.8:88"]
}

3. 登录harbor推送镜像

 docker login -u wunai -p xxxxx 192.168.1.8:88

 docker push 192.168.1.8:88/tensquare/nginx:v1

从Harbor下载镜像

1.修改docker配置

vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"insecure-registries": ["192.168.1.8:88"]
}

2.先登录,再从Harbor下载镜像

 docker login -u wunai -p xxxxx 192.168.1.8:88
docker pull 192.168.1.8:88/tensquare/nginx:v1

从GitHub拉取代码

创建GitLab后端项目

创建前端项目

上传代码就不演示了

配置Jenkins后端拉取项目

jenkinsfile2

//git凭证ID
def git_auth = "d04c1647-902a-4d18-b5df-36e5a69af120"
//git的url地址
def git_url = "git@192.168.1.4:youmen/tensquare_back.git" node {
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
}

提交到SonarQube代码审查

jenkinsfile2

//git凭证ID
def git_auth = "d04c1647-902a-4d18-b5df-36e5a69af120"
//git的url地址
def git_url = "git@192.168.1.4:youmen/tensquare_back.git" node {
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
} stage('代码审查') {
//定义当前Jenkins的SonarQubeScanner工具
def scannerHome = tool 'sonar-scanner'
//引用当前JenkinsSonarQube环境
withSonarQubeEnv('sonarqube') {
sh """
cd ${project_name}
${scannerHome}/bin/sonar-scanner
"""
}
}
}

编译打包微服务工程

//git凭证ID
def git_auth = "d04c1647-902a-4d18-b5df-36e5a69af120"
//git的url地址
def git_url = "git@192.168.1.4:youmen/tensquare_back.git" node {
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
} stage('代码审查') {
//定义当前Jenkins的SonarQubeScanner工具
def scannerHome = tool 'sonar-scanner'
//引用当前JenkinsSonarQube环境
withSonarQubeEnv('sonarqube') {
sh """
cd ${project_name}
${scannerHome}/bin/sonar-scanner
"""
}
} stage('编译,安装公共子工程') {
sh "mvn -f tensquare_common clean install"
} stage('编译,打包微服务工程') {
sh "mvn -f ${project_name} clean package"
}
}

使用Dockerfile生成镜像

在每个微服务项目pom.xml加入dockerfile-maven-plugin插件
    <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.3.6</version>
<configuration>
<repository>${project.artifactId}</repository>
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
每个微服务项目根目录建立dockerfile文件
#FROM java:8
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 10086
ENTRYPOINT ["java","-jar","/app.jar"]
配置jenkinsfile
//git凭证ID
def git_auth = "d04c1647-902a-4d18-b5df-36e5a69af120"
//git的url地址
def git_url = "git@192.168.1.4:youmen/tensquare_back.git" node {
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
} stage('代码审查') {
//定义当前Jenkins的SonarQubeScanner工具
def scannerHome = tool 'sonar-scanner'
//引用当前JenkinsSonarQube环境
withSonarQubeEnv('sonarqube') {
sh """
cd ${project_name}
${scannerHome}/bin/sonar-scanner
"""
}
} stage('编译,安装公共子工程') {
sh "mvn -f tensquare_common clean install"
} stage('编译,打包微服务工程') {
sh "mvn -f ${project_name} clean package dockerfile:build"
}
}

上传Harbor镜像仓库并拉取发布应用

创建harbor凭证

# 创建完成后再点进去将里面ID复制出来,然后放到Jenkinsfile里面
1d961bbc-82a1-41a2-b146-52bcaffe44f7

将harbor用户名和密码通过凭证和pipline转换达到隐藏用户名和密码的功能

上传Harbor镜像
//git凭证ID
def git_auth = "d04c1647-902a-4d18-b5df-36e5a69af120" //git的url地址
def git_url = "git@192.168.1.4:youmen/tensquare_back.git" // 镜像版本号
def tag = "latest" // Harbor的url地址
def harbor_url="192.168.1.8:88" // 镜像库项目名称
def harbor_project = "tensquare" // Harbor的登陆凭证
def harbor_auth = "1d961bbc-82a1-41a2-b146-52bcaffe44f7" node {
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
} stage('代码审查') {
//定义当前Jenkins的SonarQubeScanner工具
def scannerHome = tool 'sonar-scanner'
//引用当前JenkinsSonarQube环境
withSonarQubeEnv('sonarqube') {
sh """
cd ${project_name}
${scannerHome}/bin/sonar-scanner
"""
}
} stage('编译,安装公共子工程') {
sh "mvn -f tensquare_common clean install"
} stage('编译,打包微服务工程,上传镜像') {
sh "mvn -f ${project_name} clean package dockerfile:build" // 定义镜像名称
def imageName = "${project_name}:${tag}" // 对镜像打标签
sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}" //把镜像推送到Harbor
withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) { //登录到Harbor
sh "docker login -u ${username} -p ${password} ${harbor_url}" //镜像上传
sh "docker push ${harbor_url}/${harbor_project}/${imageName}" sh "echo 镜像上传成功"
}
}
}

拉取镜像和发布应用

安装Publish Over SSH插件

做jenkins与生产部署服务器免密
# [root@jenkins-2 ~]# ssh-copy-id 192.168.1.6

配置微服务启动端口

配置jenkinsfile
//git凭证ID
def git_auth = "d04c1647-902a-4d18-b5df-36e5a69af120" //git的url地址
def git_url = "git@192.168.1.4:youmen/tensquare_back.git" // 镜像版本号
def tag = "latest" // Harbor的url地址
def harbor_url="192.168.1.8:88" // 镜像库项目名称
def harbor_project = "tensquare" // Harbor的登陆凭证
def harbor_auth = "1d961bbc-82a1-41a2-b146-52bcaffe44f7" node {
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
} stage('代码审查') {
//定义当前Jenkins的SonarQubeScanner工具
def scannerHome = tool 'sonar-scanner'
//引用当前JenkinsSonarQube环境
withSonarQubeEnv('sonarqube') {
sh """
cd ${project_name}
${scannerHome}/bin/sonar-scanner
"""
}
} stage('编译,安装公共子工程') {
sh "mvn -f tensquare_common clean install"
} stage('编译,打包微服务工程,上传镜像') {
sh "mvn -f ${project_name} clean package dockerfile:build" // 定义镜像名称
def imageName = "${project_name}:${tag}" // 对镜像打标签
sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}" //把镜像推送到Harbor
withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) { //登录到Harbor
sh "docker login -u ${username} -p ${password} ${harbor_url}" //镜像上传
sh "docker push ${harbor_url}/${harbor_project}/${imageName}" sh "echo 镜像上传成功"
} // 部署应用
sshPublisher(publishers: [sshPublisherDesc(configName: 'master_server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "/opt/jenkins_shell/deploy.sh $harbor_url $harbor_project $project_name $tag $port", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
配置部署脚本
[root@tomcat-6 ~]# cat /opt/jenkins_shell/deploy.sh
#! /bin/sh
#接收外部参数
harbor_url=$1
harbor_project_name=$2
project_name=$3
tag=$4
port=$5 imageName=$harbor_url/$harbor_project_name/$project_name:$tag echo "$imageName" #查询容器是否存在,存在则删除
containerId=`docker ps -a | grep -w ${project_name}:${tag} | awk '{print $1}'`
if [ "$containerId" != "" ] ; then
#停掉容器
docker stop $containerId #删除容器
docker rm $containerId echo "成功删除容器"
fi #查询镜像是否存在,存在则删除
imageId=`docker images | grep -w $project_name | awk '{print $3}'` if [ "$imageId" != "" ] ; then #删除镜像
docker rmi -f $imageId echo "成功删除镜像"
fi # 登录Harbor
docker login -u eric -p Eric123456 $harbor_url # 下载镜像
docker pull $imageName # 启动容器
docker run -di -p $port:$port $imageName echo "容器启动成功" # 记得加+x权限

访问查看

部署测试所有微服务

# src/main/resourcesapplication.yml 修改数据库地址

[root@tomcat-6 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
120baa66789c 192.168.1.8:88/tensquare/tensquare_gathering:latest "java -jar /app.jar" 3 minutes ago Up 3 minutes 0.0.0.0:9002->9002/tcp friendly_jones
29bb1c3156c3 192.168.1.8:88/tensquare/tensquare_zuul:latest "java -jar /app.jar" 8 minutes ago Up 8 minutes 0.0.0.0:10020->10020/tcp xenodochial_knuth
76113fb1c859 192.168.1.8:88/tensquare/tensquare_eureka_server:latest "java -jar /app.jar" 13 minutes ago Up 13 minutes 0.0.0.0:8080->8080/tcp, 10086/tcp peaceful_euler
7a84a0f6e3eb 192.168.1.8:88/tensquare/tensquare_admin_service:latest "java -jar /app.jar" 20 minutes ago Up 20 minutes 0.0.0.0:9001->9001/tcp sad_beaver

部署前端静态网站

安装配置nginx
yum -y install nginx
systemctl start nginx && systemctl enable nginx
# 查看nginx软件版本
nginx -v # 修改nginx端口 server {
listen 9090 default_server;
listen [::]:9090 default_server;
server_name _;
root /usr/share/nginx/html; # 重启服务使配置生效
systemctl restart nginx # 验证服务状态
[root@tomcat-6 ~]# curl -I localhost:9090
HTTP/1.1 200 OK
Server: nginx/1.16.1
安装NodeJS插件

配置全局工具Nodejs

Jenkins配置Nginx服务器

注意修改前端代码的里面地址为网关地址

'use strict'
module.exports = {
NODE_ENV: '"production"',
// BASE_API: '"http://192.168.207.131:7300/mock/5c0b42c85b4c7508d4dc568c/1024"'
BASE_API: '"http://192.168.1.6:10020"' // 管理员网关
}

// gitlab凭证
def git_auth = "181829c8-c8cd-4e85-aa93-89ad280a5e69" def git_url = "git@192.168.1.4:youmen/tensquare_front.git" node {
stage('拉取代码') {
checkout([$class: 'GitSCM', branch
es: [[name: "*/${branch}"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
} stage('打包,部署网站') {
// 使用NodeJS的npm进行打包
sh '''
npm install
nmp run build
'''
} // 项目部署
sshPublisher(publishers: [sshPublisherDesc(configName: 'master_server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/usr/share/nginx/html', remoteDirectorySDF: false, removePrefix: 'dist', sourceFiles: 'dist/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}

08 . Jenkins之SpringCloud微服务+Vue+Docker持续集成的更多相关文章

  1. 微服务下的持续集成-Jenkins自动化部署GitHub项目

    @ 目录 一.前言 二.DevOps概念 三.为什么要做持续集成 四.常见云服务 五.手动部署Jenkins 5.1 准备工作 5.2 下载 5.3 启动 5.4 配置 5.5 Jenkins 首页 ...

  2. 字节跳动内部微服务架构-Docker实战学习笔记分享 真香

    前言 基于 Spring Cloud 的微服务设计和开发,已经越来越多地得到了更多企业的推广和应用,而 Spring Cloud 社区也在不断的迅速发展壮大之中,近几年时间,Spring Cloud ...

  3. Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成(上)

    Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成(上) Jenkins+Docker+SpringCloud持续集成流程说明 大致流程说明: 1) 开发 ...

  4. Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成——部署方案优化

    Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成--部署方案优化 之前我们做的方案部署都是只能选择一个微服务部署并只有一台生产服务器,每个微服务只有一个 ...

  5. 十一、Docker搭建部署SpringCloud微服务项目Demo

    环境介绍 技术选型:SpringCloud&SpringCloud Alibaba&Docker 微服务模块划分: 员工模块:ems-employees 部门模块:ems-depart ...

  6. 使用Jenkins编译打包SpringCloud微服务中的个别目录

    意义说明: 使用Jenkins从Gogs拉取SpringCloud微服务,拉取的是整个仓库的内容,分好多个模块文件夹,但是使用maven编译打包的话只编译打包指定的模块文件夹 Gogs Webhook ...

  7. 小D课堂 - 新版本微服务springcloud+Docker教程_3-04 SpringCloud微服务核心组件Eureka介绍和闭源后影响

    笔记 4.SpringCloud微服务核心组件Eureka介绍和闭源后影响     简介:         SpringCloud体系介绍             官方地址:http://projec ...

  8. SpringCloud微服务治理技术入门(SCN)

    1.集群.分布式.微服务 首先先理解三个感念 什么是集群?: 同一个业务,部署在多个服务器上,目的是实现高可用,保证节点可用! 什么是分布式?: 一个业务分拆成多个子业务,部署在不同的服务器上,每个子 ...

  9. 【微服务】之二:从零开始,轻松搞定SpringCloud微服务系列--注册中心(一)

    微服务体系,有效解决项目庞大.互相依赖的问题.目前SpringCloud体系有强大的一整套针对微服务的解决方案.本文中,重点对微服务体系中的服务发现注册中心进行详细说明.本篇中的注册中心,采用Netf ...

随机推荐

  1. 2020,8种必备Selenium编写自动化用例的技巧

    在开始自动化时,您可能会遇到各种可能包含在自动化代码中的方法,技术,框架和工具.有时,与提供更好的灵活性或解决问题的更好方法相比,这种多功能性导致代码更加复杂.在编写自动化代码时,重要的是我们能够清楚 ...

  2. Python和Nose实现移动应用的自动化测试

    今天跟大家聊的是Python和Nose实现移动应用的自动化测试,希望对你们有帮助,有说的不好的地方,还请多多指教! 采用Appium进行自动化的功能性测试最酷的一点是,你可以使用具有最适合你的测试工具 ...

  3. PHP - 读取EXCEL内容 存入数据库

    <?php //设置请求头 header("Content-Type:text/html;charset=utf8"); header("Access-Contro ...

  4. Java开发之javaEE(java2EE)的介绍,java软件工程师初步阶段知识

    1. 为什么需要JavaEE 我们编写的JSP代码中,由于大量的显示代码和业务逻辑混淆在一起,彼此嵌套,不利于程序的维护和扩展.当业务需求发生变化的时候,对于程序员和美工都是一个很重的负担. 为了程序 ...

  5. Lua C API的正确用法

    http://blog.codingnow.com/2015/05/lua_c_api.html http://blog.csdn.net/oilcode/article/details/510861 ...

  6. 手写mybatis框架

    前言 很久没有更新mybatis的源码解析了,因为最近在将自己所理解的mybatis思想转为实践. 在学习mybatis的源码过程中,根据mybatis的思想自己构建了一个ORM框架 .整个代码都是自 ...

  7. MyBatis的逆向工程、Example类

    public void testFindUserByName(){ //通过criteria构造查询条件 UserExample userExample = new UserExample(); us ...

  8. selenium+python3+pycharm

    当使用selenium实现元素定位时,运行: 元素定位,常用8大方法.具体百度 在此以id定位进行解释 #from selenium import webdriver # driver=webdriv ...

  9. hacker101 CTF 学习记录(二)

    前言 无 Easy-Postbook 拿到功能有点多,先扫一遍目录 .Ds_Store没有啥东西,page是个静态页面 随便注册个账号,登录后已经有2篇文章,第一篇文章的id是1 自己创建文章,将ur ...

  10. Javaweb应用中配置错误跳转页面

    关于在Javaweb应用中配置错误跳转页面 应用场景,比如服务器的出现404错误,我们想让它返回跳转到我们自定义的错误页面 解决方法: 主要在web.xml文件中进行配置,这里玩的错误页面都单独放在e ...