采集节点主要安装Filebeat组件即可,Filebeat可以很简单运行在Windows/Linux操作系统上,不需要其余环境。下载Filebeat压缩包:https://www.elastic.co/downloads/past-releases/filebeat-6-2-4根据操作系统选择对应的版本下载解压修改目录下filebeat.yml文件,具体配置下图:上图为filebeat的输入端配置,指定监听文件上图为filebeat的输出端配置,指定输出到本机的Logstash中Filebeat启动(cd$FILEBEAT_HOME):./filebeat-e-cfilebeat.yml后台启动可使用nohup命令nohup./filebeat-e-cfilebeat.yml-d"publish">logs/filebeat.log2>&1&
一、FastDFS介绍1.1介绍FastDFS是一个C语言实现的开源轻量级分布式文件系统,支持Linux、FreeBSD、AID等Unix系统,解决了大数据存储和读写负载均衡等问题,适合存储4KB~500MB之间的小文件,如图片网站、短视频网站、文档、app下载站等,UC、京东、支付宝、迅雷、酷狗等都有使用,其中UC基于FastDFS向用户提供网盘、广告和应用下载的业务的存储服务FastDFS与MogileFS、HDFS、TFS等都不是系统级的分布式文件系统,而是应用级的分布式文件存储服务。1.2架构FastDFS服务有三个角色:跟踪服务器(TrackerServer)、存储服务器(storageserver)和客户端(client)TrackerServer:跟踪服务器,主要做调度工作,起到均衡的作用;负责管理所有的storageserver和group,每个storage在启动后会连接Tracker,告知自己所属group等信息,并保持周期性心跳,Tracker根据storage心跳信息,建立group--->[storageserverlist]的映射表;tracker管理的元数据很少,会直接存放在内存;tracker上的元信息都是由storage汇报的信息生成的,本身不需要持久化任何数据,tracker之间是对等关系,因此扩展tracker服务非常容易,之间增加tracker服务器即可,所有tracker都接受stroage心跳信息,生成元数据信息来提供读写服务(与其他Master-Slave架构的优势是没有单点,tracker也不会成为瓶颈,最终数据是和一个可用的StorageServer进行传输的)StorageServer:存储服务器,主要提供容量和备份服务;以group为单位,每个group内可以包含多台storageserver,数据互为备份,存储容量空间以group内容量最小的storage为准;建议group内的storageserver配置相同;以group为单位组织存储能够方便的进行应用隔离、负载均衡和副本数定制;缺点是group的容量受单机存储容量的限制,同时group内机器坏掉,数据恢复只能依赖group内其他机器重新同步(坏盘替换,重新挂载重启fdfs_storaged即可)1.3Group存储策略多个group之间的存储方式有3种策略:roundrobin(轮询)、loadbalance(选择最大剩余空间的组上传文件)、specifygroup(指定group上传)group中storage存储依赖本地文件系统,storage可配置多个数据存储目录,磁盘不做raid,直接分别挂载到多个目录,将这些目录配置为storage的数据目录即可storage接受写请求时,会根据配置好的规则,选择其中一个存储目录来存储文件;为避免单个目录下的文件过多,storage第一次启时,会在每个数据存储目录里创建2级子目录,每级256个,总共65536个,新写的文件会以hash的方式被路由到其中某个子目录下,然后将文件数据直接作为一个本地文件存储到该目录中1.4工作流程1.4.1上传FastDFS向使用者提供基本文件访问接口,比如upload、download、append、delete等,以客户端库的方式提供给用户使用。StorageServer会定期的向TrackerServer发送自己的存储信息。当TrackerServerCluster中的TrackerServer不止一个时,各个Tracker之间的关系是对等的,所以客户端上传时可以选择任意一个Tracker。当Tracker收到客户端上传文件的请求时,会为该文件分配一个可以存储文件的group,当选定了group后就要决定给客户端分配group中的哪一个storageserver。当分配好storageserver后,客户端向storage发送写文件请求,storage将会为文件分配一个数据存储目录。然后为文件分配一个fileid,最后根据以上的信息生成文件名存储文件。FastDFS上传时序图:1.4.2同步写文件时,客户端将文件写至group内一个storageserver即认为写文件成功,storageserver写完文件后,会由后台线程将文件同步至同group内其他的storageserver。每个storage写文件后,同时会写一份binlog,binlog里不包含文件数据,只包含文件名等元信息,这份binlog用于后台同步,storage会记录向group内其他storage同步的进度,以便重启后能接上次的进度继续同步;进度以时间戳的方式进行记录,所以最好能保证集群内所有server的时钟保持同步。storage的同步进度会作为元数据的一部分汇报到tracker上,tracke在选择读storage的时候会以同步进度作为参考。1.4.3下载客户端uploadfile成功后,会拿到一个storage生成的文件名,接下来客户端根据这个文件名即可访问到该文件。跟uploadfile一样,在downloadfile时客户端可以选择任意trackerserver。tracker发送download请求给某个tracker,必须带上文件名信息,tracke从文件名中解析出文件的group、大小、创建时间等信息,然后为该请求选择一个storage用来服务读请求。FastDFS下载时序图:二、FastDFS安装2.1下载安装libfastcommon下载libfastcommonwgethttps://github.com/happyfish100/libfastcommon/archive/V1.0.38.tar.gz解压tar-zxvfV1.0.38.tar.gzcdlibfastcommon-1.0.38编译安装./make.sh./make.shinstall2.2安装fastDFS下载wgethttps://github.com/happyfish100/fastdfs/archive/V5.10.tar.gz解压tar-zxvfV5.10.tar.gzcdfastdfs-5.10编译安装./make.sh./make.shinstallFastdfs的文件目录A、服务脚本:/etc/init.d/fdfs_storaged/etc/init.d/fdfs_trackerdB、配置文件模板:/etc/fdfs/client.conf.sample/etc/fdfs/storage.conf.sample/etc/fdfs/tracker.conf.sample2.3配置跟踪器(Tracker)进入/etc/fdfs,复制FastDFS跟踪器样例配置文件tracker.conf.sample,并重命名为tracker.conf。cd/etc/fdfscptracker.conf.sampletracker.confvimtracker.conf编辑tracker.conf,加粗的需要修改下,其它的默认即可。#配置文件是否不生效,false为生效disabled=false#提供服务的端口port=22122#Tracker数据和日志目录地址(根目录必须存在,子目录会自动创建)base_path=/home/data/fastdfs/trackerhttp.server_port=80创建tracker基础数据目录,即base_path对应的目录mkdir-p/home/data/fastdfs/tracker防火墙中打开跟踪端口(默认的22122)vim/etc/sysconfig/iptables最下面添加一行:-AINPUT-mstate--stateNEW-mtcp-ptcp--dport22122-jACCEPT重启iptables:serviceiptablesrestart启动Tracker初次成功启动,会在/home/data/fdfsdfs/tracker/(配置的base_path)下创建data、logs两个目录。可以用这种方式启动:/etc/init.d/fdfs_trackerdstartservicefdfs_trackerdstart查看FastDFSTracker是否已成功启动,22122端口正在被监听,则算是Tracker服务安装成功。netstat-unltp|grepfdfs关闭Tracker命令:servicefdfs_trackerdstop2.4配置存储(Storage)进入/etc/fdfs目录,复制FastDFS存储器样例配置文件storage.conf.sample,并重命名为storage.conf#cd/etc/fdfs#cpstorage.conf.samplestorage.conf#vimstorage.conf编辑storage.conf,加粗的需要修改,其它的默认即可。#配置文件是否不生效,false为生效disabled=false#指定此storageserver所在组(卷)group_name=group1#storageserver服务端口port=23000#心跳间隔时间,单位为秒(这里是指主动向trackerserver发送心跳)heart_beat_interval=30#Storage数据和日志目录地址(根目录必须存在,子目录会自动生成)base_path=/home/data/fastdfs/storage#存放文件时storageserver支持多个路径。这里配置存放文件的基路径数目,通常只配一个目录。store_path_count=1#逐一配置store_path_count个路径,索引号基于0。#如果不配置store_path0,那它就和base_path对应的路径一样。store_path0=/home/data/fastdfs/file#FastDFS存储文件时,采用了两级目录。这里配置存放文件的目录个数。#如果本参数只为N(如:256),那么storageserver在初次运行时,会在store_path下自动创建N*N个存放文件的子目录。subdir_count_per_path=256#tracker_server的列表,会主动连接tracker_server#有多个trackerserver时,每个trackerserver写一行tracker_server=192.168.1.161:22122#允许系统同步的时间段(默认是全天)。一般用于避免高峰同步产生一些问题而设定。sync_start_time=00:00sync_end_time=23:59#访问端口http.server_port=80创建Storage基础数据目录,对应base_path目录mkdir-p/home/data/fastdfs/storage这是配置的store_path0路径mkdir-p/home/data/fastdfs/file防火墙中打开存储器端口(默认的23000)vim/etc/sysconfig/iptables添加如下端口行:-AINPUT-mstate--stateNEW-mtcp-ptcp--dport23000-jACCEPT重启防火墙:serviceiptablesrestart启动Storage启动Storage前确保Tracker是启动的。初次启动成功,会在/home/data/fastdfs/storage目录下创建data、logs两个目录。可以用这种方式启动/etc/init.d/fdfs_storagedstartservicefdfs_storagedstart查看Storage和Tracker是否在通信:/usr/bin/fdfs_monitor/etc/fdfs/storage.conf
下载破解文件JetbrainsIdesCrack-3.4.jar将下载的文件复制到WebStorm安装文件夹下的bin文件夹下(在桌面上WebStorm快捷方式上右键【打开文件所在的位置】可直接进入)双击打开WebStorm进入激活页面,点选【Evaluateforfree】试用30天,进入应用界面在菜单【Help】->【EditcustomVMoptions..】点击打开配置文件.在配置文件最下方加入一行:-javaagent:D:\software\WebStorm2019.1.3\bin\JetbrainsIdesCrack-3.4.jar这里的文件路径具体指向到刚才复制的破解文件路径下在菜单【Help】->【Register...】点击打开激活页面,选择【licenseserver】激活方式,在下面输入框中填写:https://fls.jetbrains-agent.com点击【Activate】激活后,重启WebStorm生效.
Centos安装ApacheHadoop2.7.7准备文件:hadoop-2.7.7.tar.gz一、安装JDK安装Hadoop之前需要保证JDK8成功安装java-version二、上传Hadoop压缩包上传成功后解压文件:tar-zxvfhadoop-2.7.7.tar.gz假设解压后的Hadoop目录为:/home/hadoop/hadoop-2.7.7注意配置HADOOP_HOME环境变量exportHADOOP_HOME=/home/hadoop/hadoop-2.7.7exportPATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin三、配置服务器免密登录$ssh-keygen-trsa-P''-f~/.ssh/id_rsa$cat~/.ssh/id_rsa.pub>>~/.ssh/authorized_keys$chmod0600~/.ssh/authorized_keys执行完成后:sshmaster命令则能够跳过输入密码阶段直接连接四、修改配置==配置文件所在位置:$HADOOP_HOME/etc/hadoop==core-size.xml<configuration><property><name>fs.defaultFS</name><value>hdfs://master:9000</value></property></configuration>hdfs-size.xml<configuration><property><name>dfs.replication</name><value>1</value></property></configuration>mapred-site.xml<configuration><property><name>mapreduce.framework.name</name><value>yarn</value></property><property><name>mapreduce.application.classpath</name><value>$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/*:$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/lib/*</value></property></configuration>yarn-site.xml<configuration><property><name>yarn.nodemanager.aux-services</name><value>mapreduce_shuffle</value></property><property><name>yarn.nodemanager.env-whitelist</name><value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value></property></configuration>五、启动初始化HDFShdfsnamenode-format启动HDFSstart-dfs.sh启动YARNstart-yarn.sh启动成功后访问http://master:50070查看HDFS状态六、相关命令start-dfs.sh启动HDFS(namenode/datanode/SecondaryNamenode)stop-dfs.sh停止HDFSstart-yarn.sh启动Yarnstop-yarn.sh停止Yarnstart-all.sh启动HDFS和Yarnstop-all.sh停止HDFS和Yarn
一、安装Redis1.下载Rediswgethttp://download.redis.io/releases/redis-4.0.6.tar.gz2.解压tar-zxvfredis-4.0.6.tar.gz3.yum安装gccyuminstall-ygcc4.编译安装rediscdredis-4.0.6makeMALLOC=libccdsrc&&makeinstall二、启动Redis1.在/etc目录下新建redis目录mkdir-p/etc/redis2.将/usr/local/redis-4.0.6/redis.conf文件复制一份到/etc/redis目录下,并命名为6379.confcp/usr/local/redis-4.0.6/redis.conf/etc/redis/6379.conf3.将redis的启动脚本复制一份放到/etc/init.d目录下cp/usr/local/redis-4.0.6/utils/redis_init_script/etc/init.d/redisd4.设置redis开机自启动cd/etc/init.dchkconfigredisdonserviceredisddoesnotsupportchkconfig看结果是redisd不支持chkconfig,编辑redisd文件,加入如下注释:#chkconfig:23459010#description:Redisisapersistentkey-valuedatabasechkconfigredisdon启动redis:serviceredisdstart停止redis:serviceredisdstop
1.验证码工具类1.新建包utils2.新建VerifyCodeUtil类packagecn.coralcloud.ims.utils;importjavax.imageio.ImageIO;importjava.awt.*;importjava.awt.geom.AffineTransform;importjava.awt.image.BufferedImage;importjava.io.File;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.OutputStream;importjava.util.Arrays;importjava.util.Random;/***@authorc-geff*/publicclassVerifyCodeUtil{/***使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符*/privatestaticfinalStringVERIFY_CODES="23456789ABCDEFGHJKLMNPQRSTUVWXYZ";privatestaticRandomrandom=newRandom();/***使用系统默认字符源生成验证码*@paramverifySize验证码长度*@return*/publicstaticStringgenerateVerifyCode(intverifySize){returngenerateVerifyCode(verifySize,VERIFY_CODES);}/***使用指定源生成验证码*@paramverifySize验证码长度*@paramsources验证码字符源*@return*/publicstaticStringgenerateVerifyCode(intverifySize,Stringsources){if(sources==null||sources.length()==0){sources=VERIFY_CODES;}intcodesLen=sources.length();Randomrand=newRandom(System.currentTimeMillis());StringBuilderverifyCode=newStringBuilder(verifySize);for(inti=0;i<verifySize;i++){verifyCode.append(sources.charAt(rand.nextInt(codesLen-1)));}returnverifyCode.toString();}/***生成随机验证码文件,并返回验证码值*@paramw*@paramh*@paramoutputFile*@paramverifySize*@return*@throwsIOException*/publicstaticStringoutputVerifyImage(intw,inth,FileoutputFile,intverifySize)throwsIOException{StringverifyCode=generateVerifyCode(verifySize);outputImage(w,h,outputFile,verifyCode);returnverifyCode;}/***输出随机验证码图片流,并返回验证码值*@paramw*@paramh*@paramos*@paramverifySize*@return*@throwsIOException*/publicstaticStringoutputVerifyImage(intw,inth,OutputStreamos,intverifySize)throwsIOException{StringverifyCode=generateVerifyCode(verifySize);outputImage(w,h,os,verifyCode);returnverifyCode;}/***生成指定验证码图像文件*@paramw*@paramh*@paramoutputFile*@paramcode*@throwsIOException*/publicstaticvoidoutputImage(intw,inth,FileoutputFile,Stringcode)throwsIOException{if(outputFile==null){return;}Filedir=outputFile.getParentFile();if(!dir.exists()){dir.mkdirs();}try{outputFile.createNewFile();FileOutputStreamfos=newFileOutputStream(outputFile);outputImage(w,h,fos,code);fos.close();}catch(IOExceptione){throwe;}}/***输出指定验证码图片流*@paramw*@paramh*@paramos*@paramcode*@throwsIOException*/publicstaticvoidoutputImage(intw,inth,OutputStreamos,Stringcode)throwsIOException{intverifySize=code.length();BufferedImageimage=newBufferedImage(w,h,BufferedImage.TYPE_INT_RGB);Randomrand=newRandom();Graphics2Dg2=image.createGraphics();g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);Color[]colors=newColor[5];Color[]colorSpaces=newColor[]{Color.WHITE,Color.CYAN,Color.GRAY,Color.LIGHT_GRAY,Color.MAGENTA,Color.ORANGE,Color.PINK,Color.YELLOW};float[]fractions=newfloat[colors.length];for(inti=0;i<colors.length;i++){colors[i]=colorSpaces[rand.nextInt(colorSpaces.length)];fractions[i]=rand.nextFloat();}Arrays.sort(fractions);//设置边框色g2.setColor(Color.GRAY);g2.fillRect(0,0,w,h);Colorc=getRandColor(200,250);//设置背景色g2.setColor(c);g2.fillRect(0,2,w,h-4);//绘制干扰线Randomrandom=newRandom();//设置线条的颜色g2.setColor(getRandColor(160,200));intloop=20;for(inti=0;i<loop;i++){intx=random.nextInt(w-1);inty=random.nextInt(h-1);intxl=random.nextInt(6)+1;intyl=random.nextInt(12)+1;g2.drawLine(x,y,x+xl+40,y+yl+20);}//添加噪点//噪声率floatyawpRate=0.05f;intarea=(int)(yawpRate*w*h);for(inti=0;i<area;i++){intx=random.nextInt(w);inty=random.nextInt(h);intrgb=getRandomIntColor();image.setRGB(x,y,rgb);}//使图片扭曲shear(g2,w,h,c);g2.setColor(getRandColor(100,160));intfontSize=h-4;Fontfont=newFont("Algerian",Font.ITALIC,fontSize);g2.setFont(font);char[]chars=code.toCharArray();for(inti=0;i<verifySize;i++){AffineTransformaffine=newAffineTransform();affine.setToRotation(Math.PI/4*rand.nextDouble()*(rand.nextBoolean()?1:-1),(w/verifySize)*i+fontSize/2,h/2);g2.setTransform(affine);g2.drawChars(chars,i,1,((w-10)/verifySize)*i+5,h/2+fontSize/2-10);}g2.dispose();ImageIO.write(image,"jpg",os);}privatestaticfinalIntegerCOLOR_MAX_INT=255;privatestaticColorgetRandColor(intfc,intbc){if(fc>COLOR_MAX_INT){fc=COLOR_MAX_INT;}if(bc>COLOR_MAX_INT){bc=COLOR_MAX_INT;}intr=fc+random.nextInt(bc-fc);intg=fc+random.nextInt(bc-fc);intb=fc+random.nextInt(bc-fc);returnnewColor(r,g,b);}privatestaticintgetRandomIntColor(){int[]rgb=getRandomRgb();intcolor=0;for(intc:rgb){color=color<<8;color=color|c;}returncolor;}privatestaticint[]getRandomRgb(){int[]rgb=newint[3];intloop=3;for(inti=0;i<loop;i++){rgb[i]=random.nextInt(255);}returnrgb;}privatestaticvoidshear(Graphicsg,intw1,inth1,Colorcolor){shearx(g,w1,h1,color);sheary(g,w1,h1,color);}privatestaticvoidshearx(Graphicsg,intw1,inth1,Colorcolor){intperiod=random.nextInt(2);booleanborderGap=true;intframes=1;intphase=random.nextInt(2);for(inti=0;i<h1;i++){doubled=(double)(period>>1)*Math.sin((double)i/(double)period+(6.2831853071795862D*(double)phase)/(double)frames);g.copyArea(0,i,w1,1,(int)d,0);if(borderGap){g.setColor(color);g.drawLine((int)d,i,0,i);g.drawLine((int)d+w1,i,w1,i);}}}privatestaticvoidsheary(Graphicsg,intw1,inth1,Colorcolor){intperiod=random.nextInt(40)+10;booleanborderGap=true;intframes=20;intphase=7;for(inti=0;i<w1;i++){doubled=(double)(period>>1)*Math.sin((double)i/(double)period+(6.2831853071795862D*(double)phase)/(double)frames);g.copyArea(i,0,1,h1,0,(int)d);if(borderGap){g.setColor(color);g.drawLine(i,(int)d,i,0);g.drawLine(i,(int)d+h1,i,h1);}}}}2.UserController新增验证码接口2.1新增captcha方法@GetMapping("/captcha")publicvoidcaptcha(HttpServletResponseresponse,HttpSessionsession){Stringcode=VerifyCodeUtil.generateVerifyCode(4);session.setAttribute(SessionKey.ADMIN_CAPTCHA_KEY,code);try{VerifyCodeUtil.outputImage(150,50,response.getOutputStream(),code);}catch(IOExceptione){e.printStackTrace();}}2.2修改login方法,增加验证下方为最终的登录验证方法:@PostMapping("/login")publicModelAndViewlogin(Stringemail,Stringpassword,Stringcaptcha,HttpSessionsession){StringsessionCaptcha=(String)session.getAttribute(SessionKey.ADMIN_CAPTCHA_KEY);ModelAndViewview=newModelAndView();view.setViewName("user/login");//将email和password写回到页面,使得登录失败时输入的账号密码不会丢失view.addObject("email",email);view.addObject("password",password);if(StringUtils.isEmpty(captcha)||!Objects.equals(captcha,sessionCaptcha)){view.addObject("errmsg","验证码错误!");returnview;}Useruser=userService.login(email,password);if(user!=null){session.setAttribute(SessionKey.ADMIN_USER_KEY,user);view.setViewName("redirect:/index");returnview;}view.addObject("errmsg","用户名或密码错误!");returnview;}注:此处将Session的Key值通过一个常量类SessionKey保存2.3SessionKey类在utils包下新建SessionKey类packagecn.coralcloud.ims.utils;/***@authorc-geff*@nameSessionKey*@description*@date2020-11-0410:12*/publicclassSessionKey{publicstaticfinalStringADMIN_USER_KEY="AdminUserKey";publicstaticfinalStringADMIN_CAPTCHA_KEY="AdminLoginCaptchaCode";}3.修改login.ftl3.1引入jquery下载jqeury文件jquery.min.js在/static/js文件夹下新建jquery文件夹,将jquery.min.js复制到文件夹下修改login.ftl文件,最终login.ftl内容为下:<!doctypehtml><htmllang="en"xmlns:th="http://www.thymeleaf.org"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0"><metahttp-equiv="X-UA-Compatible"content="ie=edge"><linktype="text/css"rel="stylesheet"href="/static/css/main.css"><linktype="text/css"rel="stylesheet"href="/static/css/login.css"><scriptsrc="/static/js/jquery/jquery.min.js"type="application/javascript"></script><title>用户登录</title></head><body><divclass="login-container"><formaction="/user/login"method="post"><div><h3>用户登录</h3></div><divclass="ims-form-item"><labelclass="ims-form-label"for="email">登录邮箱</label><inputclass="ims-form-input"id="email"autocomplete="off"th:value="${email}"placeholder="请输入邮箱"type="text"name="email"></div><divclass="ims-form-item"><labelclass="ims-form-label"for="password">登录密码</label><inputclass="ims-form-input"id="password"autocomplete="new-password"th:value="${password}"placeholder="请输入密码"type="password"name="password"></div><divclass="ims-form-item"><labelclass="ims-form-label"for="captcha">图片验证</label><inputclass="ims-form-input"id="captcha"type="text"placeholder="请输入图片验证码"name="captcha"><imgsrc="/user/captcha"class="captcha"alt="图片验证码"></div><pclass="errormsg"th:if="${errmsg}!=null"th:text="${errmsg}"></p><div><buttontype="submit"class="ims-button">登录</button></div></form></div></body><scripttype="application/javascript">$(document).ready(function(){$('img.captcha').click(function(){$(this).attr("src","/user/captcha?_="+newDate().getTime())})})</script></html>注,login.ftl变更如下:1.head新增引入jquery.min.js2.input新增读取前面保存的email和password3.新增图片验证码输入框及图片4.新建图片点击监听事件,更换图片验证码4.修改样式login.css#captcha{width:100px;border-top-right-radius:0;border-bottom-right-radius:0;}.captcha{width:1px;flex:1;height:42px;cursor:pointer;border-top-right-radius:4px;border-bottom-right-radius:4px;}5.最终效果
1.新建CSS和JS文件2.新建静态资源配置类:ImsConfig.javapackagecn.coralcloud.ims.config;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;/***@authorc-geff*@nameImsConfig*@description*@date2020-11-0315:28*/@ConfigurationpublicclassImsConfigextendsWebMvcConfigurerAdapter{@OverridepublicvoidaddResourceHandlers(ResourceHandlerRegistryregistry){registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");super.addResourceHandlers(registry);}}注:新建config包,然后新建ImsConfig类,继承自WebMvcConfigurerAdapter,实现了addResourceHandlers方法,该方法设置了访问/static/路径的文件时会映射到项目static文件夹下3.login.ftl修改,head添加CSS引入:4.login.ftl修改,页面布局修改:5.编写对应的main.css文件,该文件为通用样式html,body{padding:0;margin:0;}.ims-form-label{font-size:15px;color:rgba(0,0,0,.7);width:100px;height:40px;line-height:40px;letter-spacing:3px;}.ims-form-input{height:40px;line-height:40px;flex:1;outline:0;padding:015px;border:1pxsolid#DCDFE6;border-radius:4px;}.ims-form-input:focus{border-color:#409EFF;}.ims-form-item{margin:15px0;width:100%;display:flex;}.ims-button{height:40px;line-height:40px;border-radius:4px;padding:030px;border:none;color:#FFFFFF;font-size:14px;background-color:#409EFF;cursor:pointer;margin:15px0;outline:0;}.ims-button:hover{background-color:#3888e0;}.ims-button:focus{background-color:rgba(64,158,255,0.81);}6.编写对应的login.css文件,该文件为登录页专用样式.login-container{display:flex;align-content:center;justify-content:center;text-align:center;-webkit-box-pack:center;-webkit-box-align:center;align-items:center;width:100vw;height:100vh;background-image:url("/static/images/login_bg.jpg");background-repeat:no-repeat;background-size:100%100%;}.login-containerform{width:350px;height:300px;background-color:rgba(255,255,255,.7);border-radius:5px;padding:10px20px;}.login-container.ims-button{width:100%}.errormsg{color:#ed2322;font-size:13px;margin-bottom:0;}7.static目录下新建文件夹images保存背景图片login_bg.jpglogin_bg.jpg
1.@Component,@Service,@Controller,@Repository是spring注解,注解后可以被spring框架所扫描并注入到spring容器来进行管理2.@Component是通用注解,其他三个注解是这个注解的拓展,并且具有了特定的功能3.如果想使用自定义的组件注解,那么只要在你定义的新注解中加上@Component即可:4.@Repository注解在持久层中,具有将数据库操作抛出的原生异常翻译转化为spring的持久层异常的功能。5.@Controller层是spring-mvc的注解,具有将请求进行转发,重定向的功能。6.@Service层是业务逻辑层注解,这个注解只是标注该类处于业务逻辑层。7.用这些注解对应用进行分层之后,就能将请求处理,义务逻辑处理,数据库操作处理分离出来,为代码解耦,也方便了以后项目的维护和开发。
1.在使用mybatis的动态sql时,有时候遇到根据条件判断添加where后面的筛选条件的情况,会出现多余的AND或者OR:2.使用where关键字:2.1当第一个参数为空时,拼接后的sql为:select*fromtdwhereandphone=.......;2.2当所有的参数都为空时,拼接后的sql为:select*fromtdwhere.....,显然这样的sql不是完整的sql,执行时会报错.3.使用where标签时:3.1当第一个参数为空时,拼接后的sql为:select*fromtdwherephone=......(若语句的开头为AND或者OR时,where元素会将他们去除).3.2当所有的参数都为空时,拼接后的sql为:select*fromtd.(where元素只会在至少有一个子元素的条件返回SQL子句的情况下才去插入“WHERE”子句)。
1.项目介绍本项目基础架构为:SpringBoot+Thymleaf+Mybatis整合SpringBoot版本:2.3.52.创建项目(打开IDEA,选择File->New->Project,在弹出的对话框中选择SpringInitializr)3.设置项目基础信息4.选择项目基础依赖5.设置项目保存路径6.创建完成等待项目依赖下载完成,则项目框架到此全部搭建完成7.pom.xml最终项目的pom.xml:<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="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.0https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.5.RELEASE</version><relativePath/><!--lookupparentfromrepository--></parent><groupId>cn.coralcloud</groupId><artifactId>ims</artifactId><version>0.0.1-SNAPSHOT</version><name>ims</name><description>DemoprojectforSpringBoot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.3</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
- SpringBoot+Thymleaf项目初入(五) - 图片验证码
- SpringBoot+Thymleaf项目初入(四) - 用户登录页面优化
- SpringBoot+Thymleaf项目初入(三) - 用户登录
- SpringBoot+Thymleaf项目初入(二) - 配置基础页面访问
- SpringBoot+Thymleaf项目初入(一) - 基础项目搭建
- MyBatis之where关键字与<where>标签的区别
- 文件上传之@RequestParam与@RequestPart
- Spring注解之@Component
- SpringBoot框架之@Controller和@RestController的区别?
- Centos安装ApacheHadoop2.7.7