
前不久,老冀去上海参加了锤子科技新发布的坚果手机发布会,结果在预订的时间又过了一个多小时罗永浩才出来,后来才知道原来锤子科技的网站遭受了数十G的DDoS(分布式拒绝服务)攻击,致使本来准备在发布会后开始预售的网站陷入了瘫痪。由此可见DDoS对于互联网行业的巨大威胁。在这个高速发展的行业,即使网站停止运行一天甚至几个小时都是不可原谅的,甚至会造成巨大的经济损失。那么,互联网公司有没有什么好办法来防止这种致命的攻击呢?让1T的海量攻击消于无形9月17日,老冀在北京望京昆泰酒店,观看了一场关于DDoS的实战演练。其中,乐视云作为模拟攻击方,百度云加速与两家合作伙伴CloudFlare和中国电信云堤则是防守方。下午3时许,乐视云计算有限公司CEO、乐视战略项目副总裁吴亚洲一声令下,一场针对云加速3.0的大流量攻击发起了。第一波攻击来自乐视云海外节点,一开始就有数十G的流量,超过70G后百度云加速启动蓝色报警。而后,攻击流量逐渐增加至350G左右,云加速开始发出橙色报警。云加速启动合作伙伴CloudFlare的海外防御,通过Anycast进行流量分摊防御。第二波攻击则来自国内。在第一波海外攻击被压制无法取得效果的同时,攻击方又启动了新一波的国内攻击,攻击流量增加到了600G,再次对该网站发起疯狂的攻击。也几乎就在同时,云加速发出红色预警,云堤启动了近源压制,把攻击流量在攻击源头的省内进行了拦截,余下的数百G流量持续在云加速ADN中心进行清洗。看到两波攻击的效果都不理想,攻击方只好孤注一掷,攻击总流量突然升至1T以上,现场的媒体记者们都惊呆了,因为这已经刷新了全球的最高纪录,这个流量已经相当于12306春运期间,最高请求数的20倍,也是最高峰值带宽的83倍。再做个比较,一般国内中小城市的总带宽也就500G左右,如果此时的这个流量全部打到某个中小城市的IP上,整个城市就会断网。虽然只是短短的10分钟的实战演练,百度云安全总经理马杰的心却始终放不下来。倒不是对自己的百度云加速没有信心,而是担心瞬间这么大的异常流量会引起网监部门的注意,回头找他“喝茶”。不过,通过这么一次真刀真枪的演练,也确实让业界见识了百度云加速出色的防御能力。当检测到异常的大流量攻击的同时,百度自主研发的DDoS/CC清洗算法就会自动运行,并且与CloudFlare和云堤形成联动:云加速识别到来自国外的攻击流量,通过Anycast在路由层面分散到全球超级节点进行清洗;国内攻击流量则是云加速将攻击特征同步给云堤,由云堤进行近源清洗。整个攻防过程中,正常的访问得到回源,而攻击流量则被清洗掉。由于百度云加速的合作节点分布全球各地,1Tbps的流量打到云加速平台之后,会被瞬时分散到各个节点,并且受到了近源压制。所以对接入云加速的网站和用户造成的影响几乎没有。而且,像北京、上海等国家级网络节点的带宽非常高,经过初步清洗的流量就不会对网络产生很大的影响。因此,普通的网民也很难察觉出网络异常,但专业人士都能在网络上检测到当天有大流量经过。不只是加速这也是2015年4月百度收购安全宝之后的第一次大规模产品发布。通过这次收购,百度云安全的市场份额超过了30%,已经是国内拥有最多客户资源的企业网络应用安全保护平台。如今,作为安全宝创始人之一的马杰感觉信心满满:因为百度强大的资源支持,给新成立的百度云安全注入了强大的动力。其实,百度云加速3.0的功能远不止是加速。全新一代智能XDN——这是马杰对百度云加速3.0的定位,它“融合了全球覆盖的CDN网络,智慧安全的BDN网络,抗击超高流量的ADN网络,以及分布式防御DDN网络。但云加速3.0并不止于此,未来,我们还将融入更多个‘DN’,让用户的网站更快的到达全球用户;具备更高的优化和推广能力:建立更强大的抵御攻击的能力。百度云安全总经理马杰指出,百度云加速3.0的特点是:更高、更快、更强。更高指的是,把SEO(搜索引擎优化)作为更高的战略,因为对很多企业而言,防住安全隐患还不够,更重要的是版主他们把产品卖出去才叫安全;更快指的是,SEO要更快捷地实现,帮助企业把搜索结果推广到客户那里;更强则是指,百度有关键词服务,还有更强的防御能力。在发布会上,马杰再三强调百度云安全的中立性、开放性。“在百度内部,百度云安全部与百度云是独立的两个并行的部门,所以百度开放云也是我的客户。而且,他们跟其他云拿到的接口是一样的。在阿里云或者腾讯云,安全是云的一个子部门,是以服务自己的云为主要目的,而我们是唯一的完全一个独立的部门,所有的云都是我的伙伴。”也正是因为这样,现在百度云安全也能够与电信云、金山云、华为企业云、AWS中国、青云,又拍云、品高云等第三方云服务提供商进行紧密的合作。“所以在这件事情上,要让伙伴相信你,一定做到自己内部也是公平的。整个云的生态应该是一个更平衡的生态,对大家都更好。”马杰还表示,百度云安全会将自己的抗DDoS能力、CDN能力等各种能力都以接口的方式向合作伙伴分批开放,目的就是希望整个云的生态是一个平衡的生态,是一个百花齐放的生态。而百度云安全的目标,就是成为所有云的基础技术服务商。当大家都在公有云市场淘金的时候,百度云安全希望成为卖水卖工具的那个人。
苹果在MacBook系列下一共有三款产品,MacBook Air、MacBook Pro13寸和MacBook Pro16寸。虽然三款都价格不菲,但主打的方向还是有区别的。去年年底,苹果官网直接上架了16寸版MacBook Pro,提升了屏幕的屏占比,从原来的15.4英寸变成了16英寸,改掉了被人诟病已久的蝴蝶键盘,而且还提升了性价比,加量不加价。今年3月份,苹果又更新了MacBook Air,同样的套路,只是屏幕尺寸没变,升级到了10代英特尔CPU,不过性能仍然捉襟见肘,看来苹果对产品的定位还是非常严格的。到现在MacBook系列只剩下13寸版MacBook Pro没有更新了,相信还是有一大部分用户在等这款产品的。毕竟16寸MBP价格太高,而且面向的是专业人士,而MBA性能又太差,无法满足办公需求,也就只有13寸的MBP最适合大部分的职场人。如今我们终于迎来了这款产品的消息,4月7日,据外媒报道,推特上的知名爆料人JonProsser透露,苹果将在5月发布一款全新的13寸版MacBook Pro,代号J223。这款MacBook Pro与16寸的MacBook Pro设计差不多,提升了屏占比,屏幕大小升级到14英寸,因此以后可能要改名为MacBook Pro14了。并且键盘也回归到剪刀键盘,也就是取消了蝶式键盘,这一点也与MacBook Pro16寸相同。同时苹果也为新MacBook Pro准备了第十代英特尔酷睿处理器,关于MacBook Pro将搭载的10代CPU此前就有消息报道过,CPU和GPU性能均有大幅提升,特别是GPU提升近30%,这也让14寸MacBook Pro能承担更多工作。著名的苹果分析师郭铭錤曾预测苹果会在2020年第二季度更新剪刀式键盘的MacBook Pro和MacBook Air。而目前其余MacBook产品均已回归剪刀键盘,因此MacBook Pro13寸的更新已经是板上钉钉,只是对于发售时间仍存有疑惑。另外郭大师还预测今年年底苹果会推出mini LED屏幕的MacBook Pro,对于全新技术屏幕很多人都想尝试,而且一年更新两次对苹果来说也不是没发生过,去年15寸版MacBook Pro就在一年内更新了两次,所以导致很多人犹豫不决。不过同时苹果很可能也会在那时同时推出自己的基于ARM架构的A系列桌面级芯片,倒是可能产品会有新的问题出现,因此如果为了稳妥起见,我推荐大家还是期待一下四月份的MacBook Pro14寸吧。
测试代码# -*- coding: utf-8 -*- import time from concurrent.futures import ThreadPoolExecutor from flask import Flask, request executor = ThreadPoolExecutor() app = Flask(__name__) # 模拟耗时任务 def run_job(name): time.sleep(5) print('run_job complete', name) @app.route('/task') def run_task(): """ 同步执行 http://127.0.0.1:5000/task """ name = request.args.get('name') run_job(name=name) return {'ret': 'ok'} @app.route('/async_task') def run_async_task(): """ 异步执行 http://127.0.0.1:5000/async_task """ name = request.args.get('name') executor.submit(run_job, name=name) return {'ret': 'ok'} if __name__ == '__main__': app.run(debug=True)apache2-utils压力测试工具测试:# 使用说明: $ ab -n 请求数 -c 并发数 URL # 同步执行任务 $ ab -n 100 -c 10 http://127.0.0.1:5000/task Time taken for tests: 55.100 seconds # 异步执行任务 $ ab -n 100 -c 10 http://127.0.0.1:5000/async_task Time taken for tests: 0.097 seconds
1、淘宝API接口:文档:http://ip.taobao.com/instructions示例:GET http://ip.taobao.com/outGetIpInfo?ip=221.218.209.125&accessKey=alibaba-inc { data: { area: "", country: "中国", isp_id: "100026", queryIp: "221.218.209.125", city: "北京", ip: "221.218.209.125", isp: "联通", county: "", region_id: "110000", area_id: "", county_id: null, region: "北京", country_id: "CN", city_id: "110100" }, msg: "query success", code: 0 }2、IP-API接口:文档:https://ip-api.com/docs/api:json示例:GET http://ip-api.com/json/221.218.209.125?lang=zh-CN { status: "success", country: "中国", countryCode: "CN", region: "BJ", regionName: "北京市", city: "北京", zip: "", lat: 39.9285, lon: 116.385, timezone: "Asia/Shanghai", isp: "China Unicom Beijing Province Network", org: "", as: "AS4808 China Unicom Beijing Province Network", query: "221.218.209.125" }3、太平洋IP接口:文档:http://whois.pconline.com.cn/示例:GET http://whois.pconline.com.cn/ipJson.jsp?ip=221.218.209.125&json=true { ip: "221.218.209.125", pro: "北京市", proCode: "110000", city: "北京市", cityCode: "110000", region: "海淀区", regionCode: "110108", addr: "北京市海淀区 联通ADSL", regionNames: "", err: "" }参考免费IP归属地查询接口汇总
1、项目打包工具:distutils 是 Python 的一个标准库setuptools 是 distutils 增强版,不包括在标准库中distribute 是 setuptools 一个分支版本distutils2 废弃2、安装 setuptools文档: https://setuptools.readthedocs.io/方式一:源码安装https://pypi.org/project/setuptools/#files下载 zip 包解压$ python setup.py install方式二:通过引导程序安装$ wget http://peak.telecommunity.com/dist/ez_setup.py # 安装 $ python ez_setup.py # 更新,以下两种任选 $ python ez_setup.py –U setuptools $ pip install -U setuptools方式三: pip安装$ pip install --upgrade setuptools3、使用 easy_install安装完 setuptools 后,就有了easy_install 的第三方管理工具包的安装# 通过包名,从PyPI寻找最新版本,自动下载、编译、安装 $ easy_install pkg_name # 通过包名从指定下载页寻找链接来安装或升级包 $ easy_install -f http://pythonpaste.org/package_index.html # 指定线上的包地址安装 $ easy_install http://example.com/path/to/MyPackage-1.2.3.tgz # 从本地的 .egg 文件安装 $ easy_install xxx.egg # 在安装时你可以添加额外的参数 指定安装目录:--install-dir=DIR, -d DIR 指定用户安装:--user包的升级# 从 pypi 中搜索并升级包 $ easy_install --upgrade pkg_name # 指定版本进行升级 $ easy_install "SomePackage==2.0"包的删除$ easy_install -m pkg_name若要删除彻底,需要手动删除相关的 .egg 及 其他文件指定安装源~/.pydistutils.cfg[easy_install] index-url=http://mirrors.aliyun.com/pypi/simple/ find-links=http://mirrors.aliyun.com/pypi/simple/4、源码包与二进制包源码包常见后缀:.zip, .tar, .tar.gz, .tar.bz2, .tar.Z安装的过程,是先解压,再编译,最后才安装。安装速度较慢, 跨平台二进制包常见后缀:.egg, .whl安装过程:省去了编译的过程,直接进行解压安装。安装速度较快。5、setup.py 的编写简单的使用示例from setuptools import setup, find_packages setup( name="mytest", version="1.0", author="wangbm", author_email="wongbingming@163.com", description="Learn to Pack Python Module", # 项目主页 url="http://www.baidu.com/", # 你要安装的包,通过 setuptools.find_packages 找到当前目录下有哪些包 packages=find_packages() )6.setup 参数setup 函数常用的参数如下setup.cfg 文件提供 setup.py 的默认参数配置:https://docs.python.org/3/distutils/configfile.htmlclassifiers 分类信息参见:https://pypi.org/pypi?%3Aaction=list_classifiers示例:from setuptools import setup, find_packages setup( classifiers = [ # 发展时期,常见的如下 # 3 - Alpha # 4 - Beta # 5 - Production/Stable 'Development Status :: 3 - Alpha', # 开发的目标用户 'Intended Audience :: Developers', # 属于什么类型 'Topic :: Software Development :: Build Tools', # 许可证信息 'License :: OSI Approved :: MIT License', # 目标 Python 版本 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', ] )文件的分发from setuptools import setup, find_packages setup( name="mytest", version="1.0", author="wangbm", author_email="wongbingming@163.com", description="Learn to Pack Python Module", url="http://iswbm.com/", packages=find_packages(), # 安装过程中,需要安装的静态文件,如配置文件、service文件、图片等 data_files=[ ('', ['conf/*.conf']), ('/usr/lib/systemd/system/', ['bin/*.service']), ], # 希望被打包的文件 package_data={ '':['*.txt'], 'bandwidth_reporter':['*.txt'] }, # 不打包某些文件 exclude_package_data={ 'bandwidth_reporter':['*.txt'] } ) 还可以使用 MANIFEST.ininclude *.txt recursive-include examples *.txt *.py prune examples/sample?/build配置:https://docs.python.org/3.6/distutils/sourcedist.html依赖包下载安装from setuptools import setup, find_packages setup( ... # 表明当前模块依赖哪些包,若环境中没有,则会从pypi中下载安装 install_requires=['docutils>=0.3'], # setup.py 本身要依赖的包,这通常是为一些setuptools的插件准备的配置 # 这里列出的包,不会自动安装。 setup_requires=['pbr'], # 仅在测试时需要使用的依赖,在正常发布的代码中是没有用的。 # 在执行python setup.py test时,可以自动安装这三个库,确保测试的正常运行。 tests_require=[ 'pytest>=3.3.1', 'pytest-cov>=2.5.1', ], # 用于安装setup_requires或tests_require里的软件包 # 这些信息会写入egg的 metadata 信息中 dependency_links=[ "http://example2.com/p/foobar-1.0.tar.gz", ], # install_requires 在安装模块时会自动安装依赖包 # 而 extras_require 不会,这里仅表示该模块会依赖这些包 # 但是这些包通常不会使用到,只有当你深度使用模块时,才会用到,这里需要你手动安装 extras_require={ 'PDF': ["ReportLab>=1.2", "RXP"], 'reST': ["docutils>=0.3"], } )安装环境的限制setup( ... python_requires='>=2.7, <=3', ) 生成可执行文件from setuptools import setup, find_packages setup( name="mytest", version="1.0", author="wangbm", author_email="wongbingming@163.com", description="Learn to Pack Python Module", url="http://iswbm.com/", packages=find_packages(), # 用来支持自动生成脚本,安装后会自动生成 /usr/bin/foo 的可执行文件 # 该文件入口指向 foo/main.py 的main 函数 entry_points={ 'console_scripts': [ 'foo = foo.main:main' ] }, # 将 bin/foo.sh 和 bar.py 脚本,生成到系统 PATH中 # 执行 python setup.py install 后 # 会生成 如 /usr/bin/foo.sh 和 如 /usr/bin/bar.py scripts=['bin/foo.sh', 'bar.py'] )7.使用 setup.py 构建包构建源码发布包$ python setup.py sdist # 指定发布包格式 $ python setup.py sdist --formats=gztar,zip # 安装 $ easy_install xxx.tar.gz文档: https://docs.python.org/3.6/distutils/sourcedist.html构建二进制分发包# exe 包 $ python setup.py bdist_wininst # rpm 包 $ python setup.py bdist_rpm # egg 包 $ python setup.py bdist_egg # 生成多个格式的进制包 $ python setup.py bdist8、使用 setup.py 安装包# 将模块安装至系统全局环境 $ python setup.py install # 在系统环境中创建一个软链接指向包实际所在目录 $ python setup.py develop # 卸载 $ python setup.py develop --uninstall $ python setup.py develop -u9、发布包到 PyPi~/.pypirc 配置 PyPI 访问地址和账号[distutils] index-servers = pypi [pypi] username:xxx password:xxx # 信息注册 $ python setup.py register # 上传源码包 $ python setup.py upload也可以使用 twine 工具注册上传python setup.py sdist bdist_wheel && twine upload dist/*参考文章花了两天,终于把 Python 的 setup.py 给整明白了Python 库打包分发(setup.py 编写)简易指南setup.py里的几个require
JDK >= 6package com.demo.desktop; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; import java.io.IOException; import java.io.OutputStream; import java.net.InetSocketAddress; /** * 根据Java提供的API实现Http服务器 */ public class MyHttpServer { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { // 创建HttpServer服务器 HttpServer httpServer = HttpServer.create(new InetSocketAddress(8080), 10); //将 / 请求交给MyHandler处理器处理 httpServer.createContext("/", new MyHandler()); httpServer.start(); } } class MyHandler implements HttpHandler { public void handle(HttpExchange httpExchange) throws IOException { String content = "hello"; //设置响应头属性及响应信息的长度 httpExchange.sendResponseHeaders(200, content.length()); //获得输出流 OutputStream os = httpExchange.getResponseBody(); os.write(content.getBytes()); os.close(); } }请求: GET http://localhost:8080/ 返回: hello
完整配置settings.xml<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd"> <!-- 本地仓库配置:默认~/.m2/repository[店家推荐修改配置] --> <localRepository>${user.home}/.m2/repository</localRepository> <!-- 交互方式配置,读取用户输入信息[使用默认即可,很少修改] --> <interactiveMode>true</interactiveMode> <!-- 是否启用独立的插件配置文件,一般很少启用[默认即可,很少修改] --> <usePluginRegistry>false</usePluginRegistry> <!-- 是否启用离线构建模式,一般很少修改[如果长时间不能联网的情况下可以修改] --> <offline>false</offline> <!-- 是否启用插件groupId自动扫描[很少使用,配置插件时建议全信息配置] --> <pluginGroups> <pluginGroup>org.apache.maven.plugins</pluginGroup> </pluginGroups> <!--配置服务端的一些设置如身份认证信息(eg: 账号、密码) --> <servers> <!--服务器元素包含配置服务器时需要的信息 --> <server> <!--这是server的id(注意不是用户登陆的id) 该id与distributionManagement中repository元素的id相匹配。 --> <id>server_001</id> <!--身份鉴权令牌。鉴权/认证用户名和鉴权密码表示服务器认证所需要的登录名和密码。 --> <username>my_login</username> <!--身份鉴权密码 。鉴权/认证用户名和鉴权密码表示服务器认证所需要的登录名和密码--> <password>my_password</password> <!--鉴权/认证时使用的私钥文件位置。和前两个元素类似 私钥位置和私钥密码指定了一个私钥的路径(默认是${user.home}/.ssh/id_dsa)--> <privateKey>${usr.home}/.ssh/id_dsa</privateKey> <!--鉴权/认证时使用的私钥密码。 --> <passphrase>some_passphrase</passphrase> <!--文件被创建时的权限。如果在部署的时候会创建一个仓库文件或者目录,这时候就可以使用权限(permission)。这两个元素合法的值是一个三位数字,其对应了unix文件系统的权限,如664,或者775。 --> <filePermissions>664</filePermissions> <!--目录被创建时的权限。 --> <directoryPermissions>775</directoryPermissions> </server> </servers> <mirrors> <!-- 默认仓库配置给定的下载镜像位置 --> <mirror> <!-- 该镜像的唯一标识符。id用来区分不同的mirror元素。 --> <id>nexus aliyun</id> <!-- 镜像名称 --> <name>Nexus Aliyun</name> <!-- 该镜像的URL。构建系统会优先考虑使用该URL,而非使用默认的服务器URL。 --> <url>http://downloads.planetmirror.com/pub/maven2</url> <!-- 被镜像的服务器的id。 如果我们要设置了一个Maven中央仓库(http://repo.maven.apache.org/maven2/)的镜像 就需要将mirrorOf设置成central。 保持和中央仓库的id central一致。 这样就能替代中央仓库的功能了--> <mirrorOf>central</mirrorOf> </mirror> </mirrors> <proxies> <!--代理元素包含配置代理时需要的信息 --> <proxy> <!--代理的唯一定义符,用来区分不同的代理元素。 --> <id>myproxy</id> <!--该代理是否是激活的那个。true则激活代理。当我们声明了一组代理,而某个时候只需要激活一个代理的时候,该元素就可以派上用处。 --> <active>true</active> <!--代理的协议。 协议://主机名:端口,分隔成离散的元素以方便配置。 --> <protocol>http</protocol> <!--代理的主机名。协议://主机名:端口,分隔成离散的元素以方便配置。 --> <host>proxy.somewhere.com</host> <!--代理的端口。协议://主机名:端口,分隔成离散的元素以方便配置。 --> <port>8080</port> <!--代理的用户名,用户名和密码表示代理服务器认证的登录名和密码。 --> <username>proxyuser</username> <!--代理的密码,用户名和密码表示代理服务器认证的登录名和密码。 --> <password>somepassword</password> <!--不该被代理的主机名列表。该列表的分隔符由代理服务器指定;例子中使用了竖线分隔符,使用逗号分隔也很常见。 --> <nonProxyHosts>*.google.com|ibiblio.org</nonProxyHosts> </proxy> </proxies> <profiles> <profile> <!-- profile的唯一标识 --> <id>test</id> <!-- 自动触发profile的条件逻辑 --> <activation /> <!-- 扩展属性列表 --> <properties /> <!-- 远程仓库列表 --> <repositories /> <!-- 插件仓库列表 --> <pluginRepositories /> </profile> </profiles> <activeProfiles> <!-- 要激活的profile id --> <activeProfile>env-test</activeProfile> </activeProfiles> <activation> <!--profile默认是否激活的标识 --> <activeByDefault>false</activeByDefault> <!--当匹配的jdk被检测到,profile被激活。例如,1.4激活JDK1.4,1.4.0_2,而!1.4激活所有版本不是以1.4开头的JDK。 --> <jdk>1.5</jdk> <!--当匹配的操作系统属性被检测到,profile被激活。os元素可以定义一些操作系统相关的属性。 --> <os> <!--激活profile的操作系统的名字 --> <name>Windows XP</name> <!--激活profile的操作系统所属家族(如 'windows') --> <family>Windows</family> <!--激活profile的操作系统体系结构 --> <arch>x86</arch> <!--激活profile的操作系统版本 --> <version>5.1.2600</version> </os> <!--如果Maven检测到某一个属性(其值可以在POM中通过${name}引用),其拥有对应的name = 值,Profile就会被激活。如果值字段是空的,那么存在属性名称字段就会激活profile,否则按区分大小写方式匹配属性值字段 --> <property> <!--激活profile的属性的名称 --> <name>mavenVersion</name> <!--激活profile的属性的值 --> <value>2.0.3</value> </property> <!--提供一个文件名,通过检测该文件的存在或不存在来激活profile。missing检查文件是否存在,如果不存在则激活profile。另一方面,exists则会检查文件是否存在,如果存在则激活profile。 --> <file> <!--如果指定的文件存在,则激活profile。 --> <exists>${basedir}/file2.properties</exists> <!--如果指定的文件不存在,则激活profile。 --> <missing>${basedir}/file1.properties</missing> </file> </activation> <properties> <spring.Version>5.2.8</spring.Version> </properties> <repositories> <!--包含需要连接到远程仓库的信息 --> <repository> <!--远程仓库唯一标识 --> <id>codehausSnapshots</id> <!--远程仓库名称 --> <name>Codehaus Snapshots</name> <!--如何处理远程仓库里发布版本的下载 --> <releases> <!--true或者false表示该仓库是否为下载某种类型构件(发布版,快照版)开启。 --> <enabled>false</enabled> <!--该元素指定更新发生的频率。Maven会比较本地POM和远程POM的时间戳。这里的选项是:always(一直),daily(默认,每日),interval:X(这里X是以分钟为单位的时间间隔),或者never(从不)。 --> <updatePolicy>always</updatePolicy> <!--当Maven验证构件校验文件失败时该怎么做-ignore(忽略),fail(失败),或者warn(警告)。 --> <checksumPolicy>warn</checksumPolicy> </releases> <!--如何处理远程仓库里快照版本的下载。有了releases和snapshots这两组配置,POM就可以在每个单独的仓库中,为每种类型的构件采取不同的策略。例如,可能有人会决定只为开发目的开启对快照版本下载的支持。参见repositories/repository/releases元素 --> <snapshots> <enabled /> <updatePolicy /> <checksumPolicy /> </snapshots> <!--远程仓库URL,按protocol://hostname/path形式 --> <url>http://snapshots.maven.codehaus.org/maven2</url> <!--用于定位和排序构件的仓库布局类型-可以是default(默认)或者legacy(遗留)。Maven 2为其仓库提供了一个默认的布局;然而,Maven 1.x有一种不同的布局。我们可以使用该元素指定布局是default(默认)还是legacy(遗留)。 --> <layout>default</layout> </repository> </repositories> </settings>pom.xml<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <!-- 1、项目基本信息配置 --> <!--父项目的坐标。如果项目中没有规定某个元素的值,那么父项目中的对应值即为项目的默认值。 坐标包括group ID,artifact ID和 version。 --> <parent> <!--被继承的父项目的构件标识符 --> <artifactId /> <!--被继承的父项目的全球唯一标识符 --> <groupId /> <!--被继承的父项目的版本 --> <version /> <!--父项目的pom.xml文件的相对路径。相对路径允许你选择一个不同的路径。默认值是../pom.xml。Maven首先在构建当前项目的地方寻找父项目的pom,其次在文件系统的这个位置(relativePath位置),然后在本地仓库,最后在远程仓库寻找父项目的pom。 --> <relativePath /> </parent> <!--声明项目描述符遵循哪一个POM模型版本。模型本身的版本很少改变,虽然如此,但它仍然是必不可少的,这是为了当Maven引入了新的特性或者其他模型变更的时候,确保稳定性。 --> <modelVersion>4.0.0</modelVersion> <!--项目的全球唯一标识符,通常使用全限定的包名区分该项目和其他项目。并且构建时生成的路径也是由此生成, 如com.mycompany.app生成的相对路径为:/com/mycompany/app --> <groupId>asia.banseon</groupId> <!--构件的标识符,它和group ID一起唯一标识一个构件。换句话说,你不能有两个不同的项目拥有同样的artifact ID和groupID;在某个特定的group ID下,artifact ID也必须是唯一的。构件是项目产生的或使用的一个东西,Maven为项目产生的构件包括:JARs,源码,二进制发布和WARs等。 --> <artifactId>banseon-maven2</artifactId> <!--项目产生的构件类型,例如jar、war、ear、pom。插件可以创建他们自己的构件类型,所以前面列的不是全部构件类型 --> <packaging>jar</packaging> <!--项目当前版本,格式为:主版本.次版本.增量版本-限定版本号 --> <version>1.0-SNAPSHOT</version> <!--项目的名称, Maven产生的文档用 --> <name>banseon-maven</name> <!--项目主页的URL, Maven产生的文档用 --> <url>http://www.baidu.com/banseon</url> <!--项目的详细描述, Maven 产生的文档用。 当这个元素能够用HTML格式描述时(例如,CDATA中的文本会被解析器忽略,就可以包含HTML标签), 不鼓励使用纯文本描述。如果你需要修改产生的web站点的索引页面,你应该修改你自己的索引页文件,而不是调整这里的文档。 --> <description>A maven project to study maven.</description> <!--项目创建年份,4位数字。当产生版权信息时需要使用这个值。 --> <inceptionYear /> <!--项目相关邮件列表信息 --> <mailingLists> <!--该元素描述了项目相关的所有邮件列表。自动产生的网站引用这些信息。 --> <mailingList> <!--邮件的名称 --> <name>Demo</name> <!--发送邮件的地址或链接,如果是邮件地址,创建文档时,mailto: 链接会被自动创建 --> <post>Demo@126.com</post> <!--订阅邮件的地址或链接,如果是邮件地址,创建文档时,mailto: 链接会被自动创建 --> <subscribe>Demo@126.com</subscribe> <!--取消订阅邮件的地址或链接,如果是邮件地址,创建文档时,mailto: 链接会被自动创建 --> <unsubscribe>Demo@126.com</unsubscribe> <!--你可以浏览邮件信息的URL --> <archive>http://localhost:8080/demo/dev/</archive> </mailingList> </mailingLists> <!--项目开发者列表 --> <developers> <!--某个项目开发者的信息 --> <developer> <!--SCM里项目开发者的唯一标识符 --> <id>HELLO WORLD</id> <!--项目开发者的全名 --> <name>youname</name> <!--项目开发者的email --> <email>youname@qq.com</email> <!--项目开发者的主页的URL --> <url /> <!--项目开发者在项目中扮演的角色,角色元素描述了各种角色 --> <roles> <role>Project Manager</role> <role>Architect</role> </roles> <!--项目开发者所属组织 --> <organization>demo</organization> <!--项目开发者所属组织的URL --> <organizationUrl>http://www.xxx.com/</organizationUrl> <!--项目开发者属性,如即时消息如何处理等 --> <properties> <dept>No</dept> </properties> <!--项目开发者所在时区, -11到12范围内的整数。 --> <timezone>+8</timezone> </developer> </developers> <!--项目的其他贡献者列表 --> <contributors> <!--项目的其他贡献者。参见developers/developer元素 --> <contributor> <name /> <email /> <url /> <organization /> <organizationUrl /> <roles /> <timezone /> <properties /> </contributor> </contributors> <!--该元素描述了项目所有License列表。 应该只列出该项目的license列表,不要列出依赖项目的 license列表。如果列出多个license,用户可以选择它们中的一个而不是接受所有license。 --> <licenses> <!--描述了项目的license,用于生成项目的web站点的license页面,其他一些报表和validation也会用到该元素。 --> <license> <!--license用于法律上的名称 --> <name>Apache 2</name> <!--官方的license正文页面的URL --> <url>http://www.xxxx.com/LICENSE-2.0.txt</url> <!--项目分发的主要方式: repo,可以从Maven库下载 manual, 用户必须手动下载和安装依赖 --> <distribution>repo</distribution> <!--关于license的补充信息 --> <comments>A business-friendly OSS license</comments> </license> </licenses> <!--SCM(Source Control Management)标签允许你配置你的代码库,供Maven web站点和其它插件使用。 --> <scm> <!--SCM的URL,该URL描述了版本库和如何连接到版本库。欲知详情,请看SCMs提供的URL格式和列表。该连接只读。 --> <connection> scm:svn:http://svn.xxxx.com/maven/xxxxx-maven2-trunk(dao-trunk) </connection> <!--给开发者使用的,类似connection元素。即该连接不仅仅只读 --> <developerConnection> scm:svn:http://svn.xxxx.com/maven/dao-trunk </developerConnection> <!--当前代码的标签,在开发阶段默认为HEAD --> <tag /> <!--指向项目的可浏览SCM库(例如ViewVC或者Fisheye)的URL。 --> <url>http://svn.xxxxx.com/</url> </scm> <!--描述项目所属组织的各种属性。Maven产生的文档用 --> <organization> <!--组织的全名 --> <name>demo</name> <!--组织主页的URL --> <url>http://www.xxxxxx.com/</url> </organization> <!-- 2、项目构建环境配置 --> <!--描述了这个项目构建环境中的前提条件。 --> <prerequisites> <!--构建该项目或使用该插件所需要的Maven的最低版本 --> <maven /> </prerequisites> <!--项目的问题管理系统(Bugzilla, Jira, Scarab,或任何你喜欢的问题管理系统)的名称和URL,本例为 jira --> <issueManagement> <!--问题管理系统(例如jira)的名字, --> <system>jira</system> <!--该项目使用的问题管理系统的URL --> <url>http://jira.xxxx.com/xxxx</url> </issueManagement> <!--项目持续集成信息 --> <ciManagement> <!--持续集成系统的名字,例如continuum --> <system /> <!--该项目使用的持续集成系统的URL(如果持续集成系统有web接口的话)。 --> <url /> <!--构建完成时,需要通知的开发者/用户的配置项。包括被通知者信息和通知条件(错误,失败,成功,警告) --> <notifiers> <!--配置一种方式,当构建中断时,以该方式通知用户/开发者 --> <notifier> <!--传送通知的途径 --> <type /> <!--发生错误时是否通知 --> <sendOnError /> <!--构建失败时是否通知 --> <sendOnFailure /> <!--构建成功时是否通知 --> <sendOnSuccess /> <!--发生警告时是否通知 --> <sendOnWarning /> <!--不赞成使用。通知发送到哪里 --> <address /> <!--扩展配置项 --> <configuration /> </notifier> </notifiers> </ciManagement> <!--模块(有时称作子项目) 被构建成项目的一部分。列出的每个模块元素是指向该模块的目录的相对路径 --> <modules /> <!--构建项目需要的信息 --> <build> <!--该元素设置了项目源码目录,当构建项目的时候,构建系统会编译目录里的源码。该路径是相对于pom.xml的相对路径。 --> <sourceDirectory /> <!--该元素设置了项目脚本源码目录,该目录和源码目录不同:绝大多数情况下,该目录下的内容 会被拷贝到输出目录(因为脚本是被解释的,而不是被编译的)。 --> <scriptSourceDirectory /> <!--该元素设置了项目单元测试使用的源码目录,当测试项目的时候,构建系统会编译目录里的源码。该路径是相对于pom.xml的相对路径。 --> <testSourceDirectory /> <!--被编译过的应用程序class文件存放的目录。 --> <outputDirectory /> <!--被编译过的测试class文件存放的目录。 --> <testOutputDirectory /> <!--使用来自该项目的一系列构建扩展 --> <extensions> <!--描述使用到的构建扩展。 --> <extension> <!--构建扩展的groupId --> <groupId /> <!--构建扩展的artifactId --> <artifactId /> <!--构建扩展的版本 --> <version /> </extension> </extensions> <!--当项目没有规定目标(Maven2 叫做阶段)时的默认值 --> <defaultGoal /> <!--这个元素描述了项目相关的所有资源路径列表,例如和项目相关的属性文件,这些资源被包含在最终的打包文件里。 --> <resources> <!--这个元素描述了项目相关或测试相关的所有资源路径 --> <resource> <!--描述了资源的目标路径。该路径相对target/classes目录(例如${project.build.outputDirectory})。举个例子,如果你想资源在特定的包里(org.apache.maven.messages),你就必须该元素设置为org/apache/maven/messages。然而,如果你只是想把资源放到源码目录结构里,就不需要该配置。 --> <targetPath /> <!--是否使用参数值代替参数名。参数值取自properties元素或者文件里配置的属性,文件在filters元素里列出。 --> <filtering /> <!--描述存放资源的目录,该路径相对POM路径 --> <directory /> <!--包含的模式列表,例如**/*.xml. --> <includes /> <!--排除的模式列表,例如**/*.xml --> <excludes /> </resource> </resources> <!--这个元素描述了单元测试相关的所有资源路径,例如和单元测试相关的属性文件。 --> <testResources> <!--这个元素描述了测试相关的所有资源路径,参见build/resources/resource元素的说明 --> <testResource> <targetPath /> <filtering /> <directory /> <includes /> <excludes /> </testResource> </testResources> <!--构建产生的所有文件存放的目录 --> <directory /> <!--产生的构件的文件名,默认值是${artifactId}-${version}。 --> <finalName /> <!--当filtering开关打开时,使用到的过滤器属性文件列表 --> <filters /> <!--子项目可以引用的默认插件信息。该插件配置项直到被引用时才会被解析或绑定到生命周期。给定插件的任何本地配置都会覆盖这里的配置 --> <pluginManagement> <!--使用的插件列表 。 --> <plugins> <!--plugin元素包含描述插件所需要的信息。 --> <plugin> <!--插件在仓库里的group ID --> <groupId /> <!--插件在仓库里的artifact ID --> <artifactId /> <!--被使用的插件的版本(或版本范围) --> <version /> <!--是否从该插件下载Maven扩展(例如打包和类型处理器),由于性能原因,只有在真需要下载时,该元素才被设置成enabled。 --> <extensions /> <!--在构建生命周期中执行一组目标的配置。每个目标可能有不同的配置。 --> <executions> <!--execution元素包含了插件执行需要的信息 --> <execution> <!--执行目标的标识符,用于标识构建过程中的目标,或者匹配继承过程中需要合并的执行目标 --> <id /> <!--绑定了目标的构建生命周期阶段,如果省略,目标会被绑定到源数据里配置的默认阶段 --> <phase /> <!--配置的执行目标 --> <goals /> <!--配置是否被传播到子POM --> <inherited /> <!--作为DOM对象的配置 --> <configuration /> </execution> </executions> <!--项目引入插件所需要的额外依赖 --> <dependencies> <!--参见dependencies/dependency元素 --> <dependency>......</dependency> </dependencies> <!--任何配置是否被传播到子项目 --> <inherited /> <!--作为DOM对象的配置 --> <configuration /> </plugin> </plugins> </pluginManagement> <!--使用的插件列表 --> <plugins> <!--参见build/pluginManagement/plugins/plugin元素 --> <plugin> <groupId /> <artifactId /> <version /> <extensions /> <executions> <execution> <id /> <phase /> <goals /> <inherited /> <configuration /> </execution> </executions> <dependencies> <!--参见dependencies/dependency元素 --> <dependency>......</dependency> </dependencies> <goals /> <inherited /> <configuration /> </plugin> </plugins> </build> <!--在列的项目构建profile,如果被激活,会修改构建处理 --> <profiles> <!--根据环境参数或命令行参数激活某个构建处理 --> <profile> <!--构建配置的唯一标识符。即用于命令行激活,也用于在继承时合并具有相同标识符的profile。 --> <id /> <!--自动触发profile的条件逻辑。Activation是profile的开启钥匙。profile的力量来自于它 能够在某些特定的环境中自动使用某些特定的值;这些环境通过activation元素指定。activation元素并不是激活profile的唯一方式。 --> <activation> <!--profile默认是否激活的标志 --> <activeByDefault /> <!--当匹配的jdk被检测到,profile被激活。例如,1.4激活JDK1.4,1.4.0_2,而!1.4激活所有版本不是以1.4开头的JDK。 --> <jdk /> <!--当匹配的操作系统属性被检测到,profile被激活。os元素可以定义一些操作系统相关的属性。 --> <os> <!--激活profile的操作系统的名字 --> <name>Windows XP</name> <!--激活profile的操作系统所属家族(如 'windows') --> <family>Windows</family> <!--激活profile的操作系统体系结构 --> <arch>x64</arch> <!--激活profile的操作系统版本 --> <version>6.1.7100</version> </os> <!--如果Maven检测到某一个属性(其值可以在POM中通过${名称}引用),其拥有对应的名称和值,Profile就会被激活。如果值 字段是空的,那么存在属性名称字段就会激活profile,否则按区分大小写方式匹配属性值字段 --> <property> <!--激活profile的属性的名称 --> <name>mavenVersion</name> <!--激活profile的属性的值 --> <value>2.0.3</value> </property> <!--提供一个文件名,通过检测该文件的存在或不存在来激活profile。missing检查文件是否存在,如果不存在则激活 profile。另一方面,exists则会检查文件是否存在,如果存在则激活profile。 --> <file> <!--如果指定的文件存在,则激活profile。 --> <exists>/usr/local/xxxx/xxxx-home/tomcat/maven-guide-zh-to-production/workspace/ </exists> <!--如果指定的文件不存在,则激活profile。 --> <missing>/usr/local/xxxx/xxxx-home/tomcat/maven-guide-zh-to-production/workspace/ </missing> </file> </activation> <!--构建项目所需要的信息。参见build元素 --> <build> <defaultGoal /> <resources> <resource> <targetPath /> <filtering /> <directory /> <includes /> <excludes /> </resource> </resources> <testResources> <testResource> <targetPath /> <filtering /> <directory /> <includes /> <excludes /> </testResource> </testResources> <directory /> <finalName /> <filters /> <pluginManagement> <plugins> <!--参见build/pluginManagement/plugins/plugin元素 --> <plugin> <groupId /> <artifactId /> <version /> <extensions /> <executions> <execution> <id /> <phase /> <goals /> <inherited /> <configuration /> </execution> </executions> <dependencies> <!--参见dependencies/dependency元素 --> <dependency>......</dependency> </dependencies> <goals /> <inherited /> <configuration /> </plugin> </plugins> </pluginManagement> <plugins> <!--参见build/pluginManagement/plugins/plugin元素 --> <plugin> <groupId /> <artifactId /> <version /> <extensions /> <executions> <execution> <id /> <phase /> <goals /> <inherited /> <configuration /> </execution> </executions> <dependencies> <!--参见dependencies/dependency元素 --> <dependency>......</dependency> </dependencies> <goals /> <inherited /> <configuration /> </plugin> </plugins> </build> <!--模块(有时称作子项目) 被构建成项目的一部分。列出的每个模块元素是指向该模块的目录的相对路径 --> <modules /> <!--发现依赖和扩展的远程仓库列表。 --> <repositories> <!--参见repositories/repository元素 --> <repository> <releases> <enabled /> <updatePolicy /> <checksumPolicy /> </releases> <snapshots> <enabled /> <updatePolicy /> <checksumPolicy /> </snapshots> <id /> <name /> <url /> <layout /> </repository> </repositories> <!--发现插件的远程仓库列表,这些插件用于构建和报表 --> <pluginRepositories> <!--包含需要连接到远程插件仓库的信息.参见repositories/repository元素 --> <pluginRepository> <releases> <enabled /> <updatePolicy /> <checksumPolicy /> </releases> <snapshots> <enabled /> <updatePolicy /> <checksumPolicy /> </snapshots> <id /> <name /> <url /> <layout /> </pluginRepository> </pluginRepositories> <!--该元素描述了项目相关的所有依赖。 这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的仓库中下载。要获取更多信息,请看项目依赖机制。 --> <dependencies> <!--参见dependencies/dependency元素 --> <dependency>......</dependency> </dependencies> <!--不赞成使用. 现在Maven忽略该元素. --> <reports /> <!--该元素包括使用报表插件产生报表的规范。当用户执行“mvn site”,这些报表就会运行。 在页面导航栏能看到所有报表的链接。参见reporting元素 --> <reporting>......</reporting> <!--参见dependencyManagement元素 --> <dependencyManagement> <dependencies> <!--参见dependencies/dependency元素 --> <dependency>......</dependency> </dependencies> </dependencyManagement> <!--参见distributionManagement元素 --> <distributionManagement>......</distributionManagement> <!--参见properties元素 --> <properties /> </profile> </profiles> <!-- 3、项目仓库管理配置 --> <!--发现依赖和扩展的远程仓库列表。 --> <repositories> <!--包含需要连接到远程仓库的信息 --> <repository> <!--如何处理远程仓库里发布版本的下载 --> <releases> <!--true或者false表示该仓库是否为下载某种类型构件(发布版,快照版)开启。 --> <enabled /> <!--该元素指定更新发生的频率。Maven会比较本地POM和远程POM的时间戳。这里的选项是:always(一直),daily(默认,每日),interval:X(这里X是以分钟为单位的时间间隔),或者never(从不)。 --> <updatePolicy /> <!--当Maven验证构件校验文件失败时该怎么做:ignore(忽略),fail(失败),或者warn(警告)。 --> <checksumPolicy /> </releases> <!--如何处理远程仓库里快照版本的下载。有了releases和snapshots这两组配置,POM就可以在每个单独的仓库中,为每种类型的构件采取不同的策略。例如,可能有人会决定只为开发目的开启对快照版本下载的支持。参见repositories/repository/releases元素 --> <snapshots> <enabled /> <updatePolicy /> <checksumPolicy /> </snapshots> <!--远程仓库唯一标识符。可以用来匹配在settings.xml文件里配置的远程仓库 --> <id>banseon-repository-proxy</id> <!--远程仓库名称 --> <name>banseon-repository-proxy</name> <!--远程仓库URL,按protocol://hostname/path形式 --> <url>http://10.10.10.123:8080/repository/</url> <!--用于定位和排序构件的仓库布局类型-可以是default(默认)或者legacy(遗留)。Maven 2为其仓库提供了一个默认的布局;然而,Maven 1.x有一种不同的布局。我们可以使用该元素指定布局是default(默认)还是legacy(遗留)。 --> <layout>default</layout> </repository> </repositories> <!--发现插件的远程仓库列表,这些插件用于构建和报表 --> <pluginRepositories> <!--包含需要连接到远程插件仓库的信息.参见repositories/repository元素 --> <pluginRepository>......</pluginRepository> </pluginRepositories> <!-- 4、项目依赖管理配置 --> <!--继承自该项目的所有子项目的默认依赖信息。这部分的依赖信息不会被立即解析,而是当子项目声明一个依赖(必须描述group ID和artifact ID信息),如果group ID和artifact ID以外的一些信息没有描述,则通过group ID和artifact ID匹配到这里的依赖,并使用这里的依赖信息。 --> <dependencyManagement> <dependencies> <!--参见dependencies/dependency元素 --> <dependency>......</dependency> </dependencies> </dependencyManagement> <!--该元素描述了项目相关的所有依赖。 这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的仓库中下载。要获取更多信息,请看项目依赖机制。 --> <dependencies> <dependency> <!--依赖的group ID --> <groupId>org.apache.maven</groupId> <!--依赖的artifact ID --> <artifactId>maven-artifact</artifactId> <!--依赖的版本号。 在Maven 2里, 也可以配置成版本号的范围。 --> <version>3.8.1</version> <!--依赖类型,默认类型是jar。它通常表示依赖的文件的扩展名,但也有例外。一个类型可以被映射成另外一个扩展名或分类器。类型经常和使用的打包方式对应,尽管这也有例外。一些类型的例子:jar,war,ejb-client和test-jar。如果设置extensions为 true,就可以在plugin里定义新的类型。所以前面的类型的例子不完整。 --> <type>jar</type> <!--依赖的分类器。分类器可以区分属于同一个POM,但不同构建方式的构件。分类器名被附加到文件名的版本号后面。例如,如果你想要构建两个单独的构件成JAR,一个使用Java 1.4编译器,另一个使用Java 6编译器,你就可以使用分类器来生成两个单独的JAR构件。 --> <classifier></classifier> <!--依赖范围。在项目发布过程中,帮助决定哪些构件被包括进来。欲知详情请参考依赖机制。 - compile :默认范围,用于编译 - provided:类似于编译,但支持你期待jdk或者容器提供,类似于classpath - runtime: 在执行时需要使用 - test: 用于test任务时使用 - system: 需要外在提供相应的元素。通过systemPath来取得 - systemPath: 仅用于范围为system。提供相应的路径 - optional: 当项目自身被依赖时,标注依赖是否传递。用于连续依赖时使用 --> <scope>test</scope> <!--仅供system范围使用。注意,不鼓励使用这个元素,并且在新的版本中该元素可能被覆盖掉。该元素为依赖规定了文件系统上的路径。需要绝对路径而不是相对路径。推荐使用属性匹配绝对路径,例如${java.home}。 --> <systemPath></systemPath> <!--当计算传递依赖时, 从依赖构件列表里,列出被排除的依赖构件集。即告诉maven你只依赖指定的项目,不依赖项目的依赖。此元素主要用于解决版本冲突问题 --> <exclusions> <exclusion> <artifactId>spring-core</artifactId> <groupId>org.springframework</groupId> </exclusion> </exclusions> <!--可选依赖,如果你在项目B中把C依赖声明为可选,你就需要在依赖于B的项目(例如项目A)中显式的引用对C的依赖。可选依赖阻断依赖的传递性。 --> <optional>true</optional> </dependency> </dependencies> <!-- 5、项目报表信息配置 --> <!--以值替代名称,Properties可以在整个POM中使用,也可以作为触发条件(见settings.xml配置文件里activation元素的说明)。格式是<name>value</name>。 --> <properties /> <!--不赞成使用. 现在Maven忽略该元素. --> <reports></reports> <!--该元素描述使用报表插件产生报表的规范。当用户执行“mvn site”,这些报表就会运行。 在页面导航栏能看到所有报表的链接。 --> <reporting> <!--true,则,网站不包括默认的报表。这包括“项目信息”菜单中的报表。 --> <excludeDefaults /> <!--所有产生的报表存放到哪里。默认值是${project.build.directory}/site。 --> <outputDirectory /> <!--使用的报表插件和他们的配置。 --> <plugins> <!--plugin元素包含描述报表插件需要的信息 --> <plugin> <!--报表插件在仓库里的group ID --> <groupId /> <!--报表插件在仓库里的artifact ID --> <artifactId /> <!--被使用的报表插件的版本(或版本范围) --> <version /> <!--任何配置是否被传播到子项目 --> <inherited /> <!--报表插件的配置 --> <configuration /> <!--一组报表的多重规范,每个规范可能有不同的配置。一个规范(报表集)对应一个执行目标 。例如,有1,2,3,4,5,6,7,8,9个报表。1,2,5构成A报表集,对应一个执行目标。2,5,8构成B报表集,对应另一个执行目标 --> <reportSets> <!--表示报表的一个集合,以及产生该集合的配置 --> <reportSet> <!--报表集合的唯一标识符,POM继承时用到 --> <id /> <!--产生报表集合时,被使用的报表的配置 --> <configuration /> <!--配置是否被继承到子POMs --> <inherited /> <!--这个集合里使用到哪些报表 --> <reports /> </reportSet> </reportSets> </plugin> </plugins> </reporting> <!-- 6、项目部分分发配置 --> <!--项目分发信息,在执行mvn deploy后表示要发布的位置。有了这些信息就可以把网站部署到远程服务器或者把构件部署到远程仓库。 --> <distributionManagement> <!--部署项目产生的构件到远程仓库需要的信息 --> <repository> <!--是分配给快照一个唯一的版本号(由时间戳和构建流水号)?还是每次都使用相同的版本号?参见repositories/repository元素 --> <uniqueVersion /> <id>xxx-maven2</id> <name>xxx maven2</name> <url>file://${basedir}/target/deploy</url> <layout /> </repository> <!--构件的快照部署到哪里?如果没有配置该元素,默认部署到repository元素配置的仓库,参见distributionManagement/repository元素 --> <snapshotRepository> <uniqueVersion /> <id>xxx-maven2</id> <name>xxx-maven2 Snapshot Repository</name> <url>scp://svn.xxxx.com/xxx:/usr/local/maven-snapshot</url> <layout /> </snapshotRepository> <!--部署项目的网站需要的信息 --> <site> <!--部署位置的唯一标识符,用来匹配站点和settings.xml文件里的配置 --> <id>banseon-site</id> <!--部署位置的名称 --> <name>business api website</name> <!--部署位置的URL,按protocol://hostname/path形式 --> <url> scp://svn.baidu.com/xxx:/var/www/localhost/web </url> </site> <!--项目下载页面的URL。如果没有该元素,用户应该参考主页。使用该元素的原因是:帮助定位那些不在仓库里的构件(由于license限制)。 --> <downloadUrl /> <!--如果构件有了新的group ID和artifact ID(构件移到了新的位置),这里列出构件的重定位信息。 --> <relocation> <!--构件新的group ID --> <groupId /> <!--构件新的artifact ID --> <artifactId /> <!--构件新的版本号 --> <version /> <!--显示给用户的,关于移动的额外信息,例如原因。 --> <message /> </relocation> <!--给出该构件在远程仓库的状态。不得在本地项目中设置该元素,因为这是工具自动更新的。有效的值有:none(默认),converted(仓库管理员从Maven 1 POM转换过来),partner(直接从伙伴Maven 2仓库同步过来),deployed(从Maven 2实例部署),verified(被核实时正确的和最终的)。 --> <status /> </distributionManagement> </project>
H5、微信、App唤端相关一、微信分享二、浏览器H5跳转到APP三、微信H5跳转到APP一、条件说明二、文档三、重要的设置四、注意点五、样式设置一、微信分享参看:微信分享:后端参数获取PHP实现二、浏览器H5跳转到APPuser-agent.js/** * 判断设备类型 */ function isClient(clientName) { return ( window.navigator.userAgent .toLowerCase() .indexOf(clientName.toLowerCase()) > -1 ); } function isiPhone() { return isClient("iPhone"); } function isAndroid() { return isClient("Android"); } function isWeixin() { return isClient("MicroMessenger"); } // 安卓和ios的跳转路径和下载地址 const configs = { Android: { scheme: "AndroidScheme://path", download: "https://www.demo.com/app-release.apk", }, iPhone: { scheme: "iOSScheme://path", download: "https://itunes.apple.com/cn/app/app-id", }, } // 通过环境判断获取配置 window.location.href = config.scheme let downloader = window.setTimeout(() => { // 2s超时后跳转到app下载 window.location.href = config.download; }, 2500); document.addEventListener( "visibilitychange webkitvisibilitychange", function () { // 如果页面隐藏,推测打开scheme成功,清除下载任务 if (document.hidden || document.webkitHidden) { clearTimeout(downloader); } } ); window.addEventListener("pagehide", function () { clearTimeout(downloader); });三、微信H5跳转到APP接口代码配置并不复杂,最麻烦的是准备账号一、条件说明微信内访问网页时跳转到 APP条件:服务号已认证开放平台账号已认证服务号与开放平台账号同主体翻译一下就是:微信公众平台 注册一个【服务号】并微信认证(¥300)微信开放平台注册一个账号,并完成开发者资质认证(¥300)最关键的是需要【服务号】和【开放平台账号】认证主体一致!不然前面的钱就打水漂了二、文档官方文档很详细,这里不做赘述微信内网页跳转APP功能微信开放标签说明文档App获取开放标签中的extinfo数据三、重要的设置1、微信公众平台设置IP白名单该IP地址获取access_token开发->基本配置->公众号开发信息->IP白名单2、微信公众平台绑定安全域名设置->公众号设置->功能设置->JS接口安全域名3、微信开放平台绑定所需要跳转的App这里也需要设置安全域名管理中心 -> 公众帐号 -> 接口信息 -> 网页跳转移动应用 -> 关联设置中绑定所需要跳转的App四、注意点1、Android和iOS需要做好设置,才能拉起成功2、几个重要参数的获取开发者ID(AppID) 来自 微信公众平台开发者密码(AppSecret) 来自 微信公众平台移动应用Appid 来自微信开放平台配置示例:wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印 appId: '<开发者ID(AppID)>', // 必填,公众号的唯一标识 timestamp: '', // 必填,生成签名的时间戳 nonceStr: '', // 必填,生成签名的随机串 signature: '',// 必填,签名 jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData'], // 必填,需要使用的JS接口列表 openTagList: ['wx-open-launch-app'] // 可选,需要使用的开放标签列表,例如['wx-open-launch-app'] });<wx-open-launch-app id="launch-btn" appid="<移动应用Appid>" extinfo="your-extinfo" > <template> <style>.btn { padding: 12px }</style> <button class="btn">App内查看</button> </template> </wx-open-launch-app>五、样式设置首先明确几点:wx-open-launch-app标签外部样式和内部样式是隔离的wx-open-launch-app这个标签可以加样式style所以,如果在页面中使用这个拉起标签,这个地方的样式和周围的不一样。设置样式:外层span标签设置相对定位;wx-open-launch-app设置绝对定位,里边放一个空的元素,并设置高度和宽度,遮罩住底层标签;打开APP 处的span标签就可以使用外层样式了<span style="position:relative;"><span>打开APP</span><wx-open-launch-app id="launch-btn" appid="APPID" extinfo='{"name": "Tom", "age": 18}' style="position:absolute;top:0;left:0;right:0;bottom:0;" > <template> <style> .wx-btn{ width:100%%; height:20px; } </style> <div class="wx-btn"></div> </template> </wx-open-launch-app></span>参考微信开放标签 wx-open-launch-app 样式设置技巧
代码如下<html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <script> function createNotify(title, options) { var PERMISSON_GRANTED = "granted"; var PERMISSON_DENIED = "denied"; var PERMISSON_DEFAULT = "default"; // 如果用户已经允许,直接显示消息,如果不允许则提示用户授权 if (Notification.permission === PERMISSON_GRANTED) { notify(title, options); } else { Notification.requestPermission(function (res) { if (res === PERMISSON_GRANTED) { notify(title, options); } }); } // 显示提示消息 function notify($title, $options) { var notification = new Notification($title, $options); console.log(notification); notification.onshow = function (event) { console.log("show : ", event); }; notification.onclose = function (event) { console.log("close : ", event); }; notification.onclick = function (event) { console.log("click : ", event); // 当点击事件触发,打开指定的url window.open(event.target.data) notification.close(); }; } } createNotify("新的消息", { body: "你有一个奖品待领取", icon: "https://www.baidu.com/favicon.ico", data: "https://www.baidu.com/" }); /* 依次打印 * show: Event Object(事件对象),事件的type为"show" * click: Event Object(事件对象),事件的type为"click"。点击消息后消息被关闭,跳到close事件。 * close: Event Object(事件对象),事件的type为"close" */ </script> </body> </html> 各浏览器的支持不是很统一https://www.caniuse.com/?search=Notification文件直接打开没有效果,需要由后台服务提供页面参考Notification 浏览器的消息推送
pom.xml配置了包名<build> <!--生成war包的名称--> <finalName>mobile</finalName> </build>将mobile.war放入tomcat的webapps目录下,页面可以访问http://localhost:8080/mobile/不过发现静态文件都无法访问/static/img/icon.png静态地址是以绝对路径/static开头的,tomcat部署了多个项目,它也不知道你要访问那个项目下的静态资源,如果加上mobile 就可以访问到/mobile/static/img/icon.png可是我总不能在每个文件都加这么一个前缀吧其实通过Nginx转发一下就能实现了location / { proxy_pass http://127.0.0.1:8080/mobile/; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }这样一来所有路径都做了转发/ => /mobile/ /static/img/icon.png => /mobile/static/img/icon.png
项目中使用了async/awaitVue报错:Error in v-on handler: "ReferenceError: regeneratorRuntime is not defined"原因:项目中没有使用transform-runtime将es6换成es5解决方法:安装transform-runtimenpm i babel-plugin-transform-runtime -D配置:.babelrc"plugins": [ "transform-runtime" ]参考Vue报错:Error in v-on handler: “ReferenceError: regeneratorRuntime is not defined”
项目准备$ vue init webpack-simple vue-demo $ cd vue-demo && cnpm i cnpm i element-ui axios -S 前端代码如下<template> <div id="app"> <el-upload ref="upload" action="action" :show-file-list="false" :http-request="uploadFile"> <el-button>上传</el-button> </el-upload> <img v-if="imageUrl" :src="imageUrl" alt=""> </div> </template> <script> import axios from "axios"; export default { name: "app", data() { return { imageUrl: "", }; }, methods: { async uploadFile(params) { let form = new FormData(); form.append("file", params.file); const res = await axios.post("http://127.0.0.1:5000/upload", form); console.log(res); this.imageUrl = res.data; }, }, }; </script> file对象可以直接上传到服务器使用Flask写的临时的文件上传后台服务代码如下# -*- coding: utf-8 -*- import os from urllib.parse import urljoin from flask import Flask, request, send_from_directory from flask_cors import CORS import uuid app = Flask(__name__) CORS(app, supports_credentials=True) ###################### # 配置文件 ###################### UPLOAD_FOLDER = 'uploads' if not os.path.isdir(UPLOAD_FOLDER): os.mkdir(UPLOAD_FOLDER) app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER # 允许的扩展名 ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'} # 1M app.config['MAX_CONTENT_LENGTH'] = 1 * 1024 * 1024 # 检查后缀名是否为允许的文件 def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS # 获取文件名 def random_filename(filename): ext = os.path.splitext(filename)[-1] return uuid.uuid4().hex + ext # 上传文件 @app.route("/upload", methods=['POST']) def upload(): file = request.files.get('file') if file and allowed_file(file.filename): print(file.filename) filename = random_filename(file.filename) filepath = os.path.join(UPLOAD_FOLDER, filename) file.save(os.path.join(app.root_path, filepath)) file_url = urljoin(request.host_url, filepath) return file_url return "not allow ext" # 获取文件 @app.route('/uploads/<path:filename>') def get_file(filename): return send_from_directory(app.config['UPLOAD_FOLDER'], filename) if __name__ == '__main__': app.run(debug=True)
NPM CDN : https://www.jsdelivr.com/一、发布一个Vue组件1、使用webpack-simple 模板项目初始化vue init webpack-simple moment-ui cd moment-ui cnpm i2、新建组件将新建的组件放在plugin文件夹中src/plugin/Button.vue<template> <div>Button</div> </template> <script> export default { name: "MoButton", }; </script> <style lang="scss" scoped> </style>3、注册组件src/plugin/index.jsimport Button from "./Button.vue"; const components = [Button]; // 注册组件 const install = function (Vue, options) { components.forEach((component) => { Vue.component(component.name, component); }); }; /* 支持使用标签的方式引入 Vue是全局变量时,自动install */ if (typeof window !== "undefined" && window.Vue) { install(window.Vue); } export default { install, ...components, }; 4、修改配置项webpack.config.jsmodule.exports = { // 根据不同的执行环境配置不同的入口 entry: process.env.NODE_ENV == "development" ? "./src/main.js" : "./src/plugin/index.js", output: { path: path.resolve(__dirname, "./dist"), publicPath: "/dist/", filename: "moment-ui.js", library: 'moment-ui', // 指定的就是你使用require时的模块名 // CMD只能在 Node 环境执行,AMD 只能在浏览器端执行,UMD 同时支持两种执行环境 libraryTarget: 'umd', // 指定输出格式 umdNamedDefine: true // 会对 UMD 的构建过程中的 AMD 模块进行命名。否则就使用匿名的 define }, // 此处省略其他默认配置 }5、修改package.json// 设置为公开包 "private": false, // 检索路径 "main": "dist/moment-ui.js", 6、发布到npm如果没有账号注册 https://www.npmjs.com/# 登录 npm login # 发布 npm publish主页:https://www.npmjs.com/package/moment-ui二、使用示例1、CDN方式使用<html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/moment-ui@1.0.2/dist/moment-ui.js"></script> </head> <body> <div id="app"> <mo-button></mo-button> </div> <script> new Vue({ el: "#app", }); </script> </body> </html> 2、Vue项目中使用# 创建测试项目 vue init webpack-simple vue-demo-test cd vue-demo-test cnpm -i # 下载测试, 淘宝等镜像可能没有及时同步,使用npm地址 npm install moment-ui --savesrc/main.js// src/main.js import Vue from 'vue' import MomentUI from 'moment-ui' import App from './App.vue' // 注册 Vue.use(MomentUI) new Vue({ el: '#app', render: h => h(App) }) src/App.vue<template> <div id="app"> <mo-button /> </div> </template> <script> export default { name: "app", }; </script> <style> </style> 参考vue组件篇(2)—封装组件并发布到npm
两个测试所需文件public class Hello{ public void sayHello(){ System.out.println("Hello"); } }public class Demo{ public static void main(String[] args) { Hello Hello = new Hello(); Hello.sayHello(); } }同目录下javac编译执行$ ls Demo.java Hello.java $ javac Demo.java $ java Demo引入不同目录依赖编译执行$ ls Demo.java libs/ Hello.java $ javac -classpath ./libs Demo.java $ java -classpath .:libs Demo引入jar包将Hello.java打成jar包$ cd libs $ javac Hello.java $ jar -cvf hello.jar Hello.class引入jar包执行$ ls Demo.java libs/ hello.jar $ javac -classpath ./libs/hello.jar Demo.java $ java -classpath .:./libs/hello.jar Demo优化$ javac -encoding UTF-8 -classpath ./libs -d classes Demo.java # 参数说明 -encoding UTF-8 定源文件使用的字符编码 -classpath ./libs 指定查找用户类文件和注释处理程序的位置 -d classes 指定放置生成的类文件的位置,必须存在 Demo.java source files $ cd classes $ java Demo
阿里云ECS磁盘在线扩容1、安装工具$ yum install -y cloud-utils-growpart2、检查云盘大小# 2.1、查看磁盘实际大小 $ fdisk -l # 2.2、查看磁盘分区大小 $ df -h3、使用growpart工具扩容分区# 3、给系统盘的第一个分区扩容 $ growpart /dev/vda 1 # 3.1、如果报错 $ unexpected output in sfdisk --version [sfdisk,来自 util-linux 2.23.2] # 3.2、切换ECS实例的字符编码类型,回到第3步 $ LANG=en_US.UTF-84、使用resize2fs工具扩容文件系统# 4、检查文件系统 $ blkid /dev/vda1 # 4.2、为扩容系统盘的/dev/vda1分区文件系统 # ext4格式 $ resize2fs /dev/vda1 # xfs格式 二选一 后面参数是挂载目录 $ xfs_growfs /5、检查扩容结果# 列出所有可用块设备的信息 $ lsblk $ df -h问题问题1在线扩容CentOS 8系统盘报“xfs_growfs:is not a mounted XFS filesystem”错误新版的xfs_growfs命令后面的参数需要为【文件系统挂载点】,而非文件系统本身。系统盘默认挂载点为根目录,因此,执行以下命令即可$ xfs_growfs /在线扩容CentOS 8系统盘报“xfs_growfs:is not a mounted XFS filesystem”错误参考阿里云Linux热扩容云盘(growpart和resize2fs工具)解决阿里云ECS磁盘在线扩容不生效
浏览器Header和cookie字符串形式转Json,没发放图片,下载试试看吧,飞的需要50个字吗,我先说下这个软件的功能,再说下这个软件是用java写的,需要安装java环境原始header转换后的header下载地址:CSDN(需要积分/C币) https://download.csdn.net/download/mouday/12315489Github: https://github.com/mouday/coder
1、ssh登录阿里云服务器报错Permission denied (publickey,gssapi-keyex,gssapi-with-mic)2、通过web登录报错loogin incorrect解决:新开的服务器没有配置ssh登录密码,所以报错,在实例管理中重置密码就可以正常登录如果不行就重启实例参考:阿里云 无法登录 Login Incorrect
开机启动顺序1、加载内核 2、启动 init(/etc/inittab) pid=1 3、系统初始化 /etc/rc.d/rc.sysinit 4、运行开机启动 /etc/rc.d/rc*.d #软链指向 /etc/init.d/ 通过 chkconfig 命令配置 5、非系统服务启动项 /etc/rc.d/rc.local(就是 /etc/rc.local) 6、等待用户登录 /sbin/mingetty 自启动脚本1、每个用户 /etc/profile(/etc/profile.d)登录时都执行 # 环境变量 /etc/bashrc 运行bash shell时执行此文件 2、特定用户 ~/.bash_profile 登录时 ~/.profile(Debian) ~/.bashrc 登录时以及每次打开新的 shell 时 ~/.bash_logout 每次退出系统(退出bash shell)时,执行该文参考Linux 开机(脚本)启动顺序Linux开机自动加载的几种方法(1)编辑文件 /etc/rc.localvim /etc/rc.local#!/bin/sh #This script will be executed after all the other init scripts. #You can put your own initialization stuff in here if you don't #want to do the full Sys V style init stuff. touch /var/lock/subsys/local /etc/init.d/mysqld start #mysql开机启动 /etc/init.d/nginx start #nginx开机启动 /etc/init.d/php-fpm start #php-fpm开机启动 /etc/init.d/memcached start #memcache开机启动 # 在文件末尾(exit 0之前)加上你开机需要启动的程序或执行的命令即可 # (执行的程序需要写绝对路径,添加到系统环境变量的除外),如: /usr/local/thttpd/sbin/thttpd -C /usr/local/thttpd/etc/thttpd.conf(2)自己写一个shell脚本将写好的脚本(.sh文件)放到目录 /etc/profile.d/ 下,系统启动后就会自动执行该目录下的所有shell脚本。(3)通过chkconfig命令设置将启动文件cp到 /etc/init.d/或者/etc/rc.d/init.d/(前者是后者的软连接)下vim 启动文件,文件前面务必添加如下三行代码,否侧会提示chkconfig不支持#!/bin/sh 告诉系统使用的shell,所以的shell脚本都是这样 #chkconfig: 35 20 80 分别代表运行级别,启动优先权,关闭优先权,此行代码必须 #description: http server(自己随便发挥)//两行都注释掉!!!,此行代码必须chkconfig --add 脚本文件名 # 操作后就已经添加了例如/etc/init.d/rds_start.sh#!/bin/sh #chkconfig: 2345 80 90 #description:rds_start.sh cd /home/softs/rds/bin/ nohup ./rds_start.sh &说明:2345表示系统运行级别是2,3,4或者5时都启动此服务,20,是启动的优先级,80是关闭的优先级,如果启动优先级配置的数太小时如0时,则有可能启动不成功,因为此时可能其依赖的网络服务还没有启动,从而导致自启动失败。chmod +x /etc/init.d/auto_start.sh chkconfig --add rds_start.sh # 添加到系统服务 chkconfig rds_start.sh on # 设置开机启动其他命令chkconfig --list # 列出服务 chkconfig rds_start.sh off # 关闭服务
2022年01月