首页 文章 精选 留言 我的

精选列表

搜索[整理],共10001篇文章
优秀的个人博客,低调大师

整理收集的一些常用java工具类

1.json转换工具 [java] view plain copy packagecom.taotao.utils; importjava.util.List; importcom.fasterxml.jackson.core.JsonProcessingException; importcom.fasterxml.jackson.databind.JavaType; importcom.fasterxml.jackson.databind.JsonNode; importcom.fasterxml.jackson.databind.ObjectMapper; /** *json转换工具类 */ publicclassJsonUtils{ //定义jackson对象 privatestaticfinalObjectMapperMAPPER=newObjectMapper(); /** *将对象转换成json字符串。 *<p>Title:pojoToJson</p> *<p>Description:</p> *@paramdata *@return */ publicstaticStringobjectToJson(Objectdata){ try{ Stringstring=MAPPER.writeValueAsString(data); returnstring; }catch(JsonProcessingExceptione){ e.printStackTrace(); } returnnull; } /** *将json结果集转化为对象 * *@paramjsonDatajson数据 *@paramclazz对象中的object类型 *@return */ publicstatic<T>TjsonToPojo(StringjsonData,Class<T>beanType){ try{ Tt=MAPPER.readValue(jsonData,beanType); returnt; }catch(Exceptione){ e.printStackTrace(); } returnnull; } /** *将json数据转换成pojo对象list *<p>Title:jsonToList</p> *<p>Description:</p> *@paramjsonData *@parambeanType *@return */ publicstatic<T>List<T>jsonToList(StringjsonData,Class<T>beanType){ JavaTypejavaType=MAPPER.getTypeFactory().constructParametricType(List.class,beanType); try{ List<T>list=MAPPER.readValue(jsonData,javaType); returnlist; }catch(Exceptione){ e.printStackTrace(); } returnnull; } } 2.cookie的读写 [java] view plain copy packagecom.taotao.common.utils; importjava.io.UnsupportedEncodingException; importjava.net.URLDecoder; importjava.net.URLEncoder; importjavax.servlet.http.Cookie; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; /** * *Cookie工具类 * */ publicfinalclassCookieUtils{ /** *得到Cookie的值,不编码 * *@paramrequest *@paramcookieName *@return */ publicstaticStringgetCookieValue(HttpServletRequestrequest,StringcookieName){ returngetCookieValue(request,cookieName,false); } /** *得到Cookie的值, * *@paramrequest *@paramcookieName *@return */ publicstaticStringgetCookieValue(HttpServletRequestrequest,StringcookieName,booleanisDecoder){ Cookie[]cookieList=request.getCookies(); if(cookieList==null||cookieName==null){ returnnull; } StringretValue=null; try{ for(inti=0;i<cookieList.length;i++){ if(cookieList[i].getName().equals(cookieName)){ if(isDecoder){ retValue=URLDecoder.decode(cookieList[i].getValue(),"UTF-8"); }else{ retValue=cookieList[i].getValue(); } break; } } }catch(UnsupportedEncodingExceptione){ e.printStackTrace(); } returnretValue; } /** *得到Cookie的值, * *@paramrequest *@paramcookieName *@return */ publicstaticStringgetCookieValue(HttpServletRequestrequest,StringcookieName,StringencodeString){ Cookie[]cookieList=request.getCookies(); if(cookieList==null||cookieName==null){ returnnull; } StringretValue=null; try{ for(inti=0;i<cookieList.length;i++){ if(cookieList[i].getName().equals(cookieName)){ retValue=URLDecoder.decode(cookieList[i].getValue(),encodeString); break; } } }catch(UnsupportedEncodingExceptione){ e.printStackTrace(); } returnretValue; } /** *设置Cookie的值不设置生效时间默认浏览器关闭即失效,也不编码 */ publicstaticvoidsetCookie(HttpServletRequestrequest,HttpServletResponseresponse,StringcookieName, StringcookieValue){ setCookie(request,response,cookieName,cookieValue,-1); } /** *设置Cookie的值在指定时间内生效,但不编码 */ publicstaticvoidsetCookie(HttpServletRequestrequest,HttpServletResponseresponse,StringcookieName, StringcookieValue,intcookieMaxage){ setCookie(request,response,cookieName,cookieValue,cookieMaxage,false); } /** *设置Cookie的值不设置生效时间,但编码 */ publicstaticvoidsetCookie(HttpServletRequestrequest,HttpServletResponseresponse,StringcookieName, StringcookieValue,booleanisEncode){ setCookie(request,response,cookieName,cookieValue,-1,isEncode); } /** *设置Cookie的值在指定时间内生效,编码参数 */ publicstaticvoidsetCookie(HttpServletRequestrequest,HttpServletResponseresponse,StringcookieName, StringcookieValue,intcookieMaxage,booleanisEncode){ doSetCookie(request,response,cookieName,cookieValue,cookieMaxage,isEncode); } /** *设置Cookie的值在指定时间内生效,编码参数(指定编码) */ publicstaticvoidsetCookie(HttpServletRequestrequest,HttpServletResponseresponse,StringcookieName, StringcookieValue,intcookieMaxage,StringencodeString){ doSetCookie(request,response,cookieName,cookieValue,cookieMaxage,encodeString); } /** *删除Cookie带cookie域名 */ publicstaticvoiddeleteCookie(HttpServletRequestrequest,HttpServletResponseresponse, StringcookieName){ doSetCookie(request,response,cookieName,"",-1,false); } /** *设置Cookie的值,并使其在指定时间内生效 * *@paramcookieMaxagecookie生效的最大秒数 */ privatestaticfinalvoiddoSetCookie(HttpServletRequestrequest,HttpServletResponseresponse, StringcookieName,StringcookieValue,intcookieMaxage,booleanisEncode){ try{ if(cookieValue==null){ cookieValue=""; }elseif(isEncode){ cookieValue=URLEncoder.encode(cookieValue,"utf-8"); } Cookiecookie=newCookie(cookieName,cookieValue); if(cookieMaxage>0) cookie.setMaxAge(cookieMaxage); if(null!=request){//设置域名的cookie StringdomainName=getDomainName(request); System.out.println(domainName); if(!"localhost".equals(domainName)){ cookie.setDomain(domainName); } } cookie.setPath("/"); response.addCookie(cookie); }catch(Exceptione){ e.printStackTrace(); } } /** *设置Cookie的值,并使其在指定时间内生效 * *@paramcookieMaxagecookie生效的最大秒数 */ privatestaticfinalvoiddoSetCookie(HttpServletRequestrequest,HttpServletResponseresponse, StringcookieName,StringcookieValue,intcookieMaxage,StringencodeString){ try{ if(cookieValue==null){ cookieValue=""; }else{ cookieValue=URLEncoder.encode(cookieValue,encodeString); } Cookiecookie=newCookie(cookieName,cookieValue); if(cookieMaxage>0) cookie.setMaxAge(cookieMaxage); if(null!=request){//设置域名的cookie StringdomainName=getDomainName(request); System.out.println(domainName); if(!"localhost".equals(domainName)){ cookie.setDomain(domainName); } } cookie.setPath("/"); response.addCookie(cookie); }catch(Exceptione){ e.printStackTrace(); } } /** *得到cookie的域名 */ privatestaticfinalStringgetDomainName(HttpServletRequestrequest){ StringdomainName=null; StringserverName=request.getRequestURL().toString(); if(serverName==null||serverName.equals("")){ domainName=""; }else{ serverName=serverName.toLowerCase(); serverName=serverName.substring(7); finalintend=serverName.indexOf("/"); serverName=serverName.substring(0,end); finalString[]domains=serverName.split("\\."); intlen=domains.length; if(len>3){ //www.xxx.com.cn domainName="."+domains[len-3]+"."+domains[len-2]+"."+domains[len-1]; }elseif(len<=3&&len>1){ //xxx.comorxxx.cn domainName="."+domains[len-2]+"."+domains[len-1]; }else{ domainName=serverName; } } if(domainName!=null&&domainName.indexOf(":")>0){ String[]ary=domainName.split("\\:"); domainName=ary[0]; } returndomainName; } } 3.HttpClientUtil 相关包及文档下载 [java] view plain copy packagecom.taotao.utils; importjava.io.IOException; importjava.net.URI; importjava.util.ArrayList; importjava.util.List; importjava.util.Map; importorg.apache.http.NameValuePair; importorg.apache.http.client.entity.UrlEncodedFormEntity; importorg.apache.http.client.methods.CloseableHttpResponse; importorg.apache.http.client.methods.HttpGet; importorg.apache.http.client.methods.HttpPost; importorg.apache.http.client.utils.URIBuilder; importorg.apache.http.entity.ContentType; importorg.apache.http.entity.StringEntity; importorg.apache.http.impl.client.CloseableHttpClient; importorg.apache.http.impl.client.HttpClients; importorg.apache.http.message.BasicNameValuePair; importorg.apache.http.util.EntityUtils; publicclassHttpClientUtil{ publicstaticStringdoGet(Stringurl,Map<String,String>param){ //创建Httpclient对象 CloseableHttpClienthttpclient=HttpClients.createDefault(); StringresultString=""; CloseableHttpResponseresponse=null; try{ //创建uri URIBuilderbuilder=newURIBuilder(url); if(param!=null){ for(Stringkey:param.keySet()){ builder.addParameter(key,param.get(key)); } } URIuri=builder.build(); //创建httpGET请求 HttpGethttpGet=newHttpGet(uri); //执行请求 response=httpclient.execute(httpGet); //判断返回状态是否为200 if(response.getStatusLine().getStatusCode()==200){ resultString=EntityUtils.toString(response.getEntity(),"UTF-8"); } }catch(Exceptione){ e.printStackTrace(); }finally{ try{ if(response!=null){ response.close(); } httpclient.close(); }catch(IOExceptione){ e.printStackTrace(); } } returnresultString; } publicstaticStringdoGet(Stringurl){ returndoGet(url,null); } publicstaticStringdoPost(Stringurl,Map<String,String>param){ //创建Httpclient对象 CloseableHttpClienthttpClient=HttpClients.createDefault(); CloseableHttpResponseresponse=null; StringresultString=""; try{ //创建HttpPost请求 HttpPosthttpPost=newHttpPost(url); //创建参数列表 if(param!=null){ List<NameValuePair>paramList=newArrayList<>(); for(Stringkey:param.keySet()){ paramList.add(newBasicNameValuePair(key,param.get(key))); } //模拟表单 UrlEncodedFormEntityentity=newUrlEncodedFormEntity(paramList); httpPost.setEntity(entity); } //执行http请求 response=httpClient.execute(httpPost); resultString=EntityUtils.toString(response.getEntity(),"utf-8"); }catch(Exceptione){ e.printStackTrace(); }finally{ try{ response.close(); }catch(IOExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } } returnresultString; } publicstaticStringdoPost(Stringurl){ returndoPost(url,null); } publicstaticStringdoPostJson(Stringurl,Stringjson){ //创建Httpclient对象 CloseableHttpClienthttpClient=HttpClients.createDefault(); CloseableHttpResponseresponse=null; StringresultString=""; try{ //创建HttpPost请求 HttpPosthttpPost=newHttpPost(url); //创建请求内容 StringEntityentity=newStringEntity(json,ContentType.APPLICATION_JSON); httpPost.setEntity(entity); //执行http请求 response=httpClient.execute(httpPost); resultString=EntityUtils.toString(response.getEntity(),"utf-8"); }catch(Exceptione){ e.printStackTrace(); }finally{ try{ response.close(); }catch(IOExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } } returnresultString; } } 4.FastDFSClient工具类 相关包以及文档下载 [java] view plain copy packagecn.itcast.fastdfs.cliennt; importorg.csource.common.NameValuePair; importorg.csource.fastdfs.ClientGlobal; importorg.csource.fastdfs.StorageClient1; importorg.csource.fastdfs.StorageServer; importorg.csource.fastdfs.TrackerClient; importorg.csource.fastdfs.TrackerServer; publicclassFastDFSClient{ privateTrackerClienttrackerClient=null; privateTrackerServertrackerServer=null; privateStorageServerstorageServer=null; privateStorageClient1storageClient=null; publicFastDFSClient(Stringconf)throwsException{ if(conf.contains("classpath:")){ conf=conf.replace("classpath:",this.getClass().getResource("/").getPath()); } ClientGlobal.init(conf); trackerClient=newTrackerClient(); trackerServer=trackerClient.getConnection(); storageServer=null; storageClient=newStorageClient1(trackerServer,storageServer); } /** *上传文件方法 *<p>Title:uploadFile</p> *<p>Description:</p> *@paramfileName文件全路径 *@paramextName文件扩展名,不包含(.) *@parammetas文件扩展信息 *@return *@throwsException */ publicStringuploadFile(StringfileName,StringextName,NameValuePair[]metas)throwsException{ Stringresult=storageClient.upload_file1(fileName,extName,metas); returnresult; } publicStringuploadFile(StringfileName)throwsException{ returnuploadFile(fileName,null,null); } publicStringuploadFile(StringfileName,StringextName)throwsException{ returnuploadFile(fileName,extName,null); } /** *上传文件方法 *<p>Title:uploadFile</p> *<p>Description:</p> *@paramfileContent文件的内容,字节数组 *@paramextName文件扩展名 *@parammetas文件扩展信息 *@return *@throwsException */ publicStringuploadFile(byte[]fileContent,StringextName,NameValuePair[]metas)throwsException{ Stringresult=storageClient.upload_file1(fileContent,extName,metas); returnresult; } publicStringuploadFile(byte[]fileContent)throwsException{ returnuploadFile(fileContent,null,null); } publicStringuploadFile(byte[]fileContent,StringextName)throwsException{ returnuploadFile(fileContent,extName,null); } } [java] view plain copy <spanstyle="font-size:14px;font-weight:normal;">publicclassFastDFSTest{ @Test publicvoidtestFileUpload()throwsException{ //1、加载配置文件,配置文件中的内容就是tracker服务的地址。 ClientGlobal.init("D:/workspaces-itcast/term197/taotao-manager-web/src/main/resources/resource/client.conf"); //2、创建一个TrackerClient对象。直接new一个。 TrackerClienttrackerClient=newTrackerClient(); //3、使用TrackerClient对象创建连接,获得一个TrackerServer对象。 TrackerServertrackerServer=trackerClient.getConnection(); //4、创建一个StorageServer的引用,值为null StorageServerstorageServer=null; //5、创建一个StorageClient对象,需要两个参数TrackerServer对象、StorageServer的引用 StorageClientstorageClient=newStorageClient(trackerServer,storageServer); //6、使用StorageClient对象上传图片。 //扩展名不带“.” String[]strings=storageClient.upload_file("D:/Documents/Pictures/images/200811281555127886.jpg","jpg",null); //7、返回数组。包含组名和图片的路径。 for(Stringstring:strings){ System.out.println(string); } } }</span> 5.获取异常的堆栈信息 [java] view plain copy packagecom.taotao.utils; importjava.io.PrintWriter; importjava.io.StringWriter; publicclassExceptionUtil{ /** *获取异常的堆栈信息 * *@paramt *@return */ publicstaticStringgetStackTrace(Throwablet){ StringWritersw=newStringWriter(); PrintWriterpw=newPrintWriter(sw); try{ t.printStackTrace(pw); returnsw.toString(); }finally{ pw.close(); } } } 6.easyUIDataGrid对象返回值 [java] view plain copy packagecom.taotao.result; importjava.util.List; /** *easyUIDataGrid对象返回值 *<p>Title:EasyUIResult</p> *<p>Description:</p> *<p>Company:www.itcast.com</p> *@author入云龙 *@date2015年7月21日下午4:12:52 *@version1.0 */ publicclassEasyUIResult{ privateIntegertotal; privateList<?>rows; publicEasyUIResult(Integertotal,List<?>rows){ this.total=total; this.rows=rows; } publicEasyUIResult(longtotal,List<?>rows){ this.total=(int)total; this.rows=rows; } publicIntegergetTotal(){ returntotal; } publicvoidsetTotal(Integertotal){ this.total=total; } publicList<?>getRows(){ returnrows; } publicvoidsetRows(List<?>rows){ this.rows=rows; } } 7.ftp上传下载工具类 [java] view plain copy packagecom.taotao.utils; importjava.io.File; importjava.io.FileInputStream; importjava.io.FileNotFoundException; importjava.io.FileOutputStream; importjava.io.IOException; importjava.io.InputStream; importjava.io.OutputStream; importorg.apache.commons.net.ftp.FTP; importorg.apache.commons.net.ftp.FTPClient; importorg.apache.commons.net.ftp.FTPFile; importorg.apache.commons.net.ftp.FTPReply; /** *ftp上传下载工具类 *<p>Title:FtpUtil</p> *<p>Description:</p> *<p>Company:www.itcast.com</p> *@author入云龙 *@date2015年7月29日下午8:11:51 *@version1.0 */ publicclassFtpUtil{ /** *Description:向FTP服务器上传文件 *@paramhostFTP服务器hostname *@paramportFTP服务器端口 *@paramusernameFTP登录账号 *@parampasswordFTP登录密码 *@parambasePathFTP服务器基础目录 *@paramfilePathFTP服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath *@paramfilename上传到FTP服务器上的文件名 *@paraminput输入流 *@return成功返回true,否则返回false */ publicstaticbooleanuploadFile(Stringhost,intport,Stringusername,Stringpassword,StringbasePath, StringfilePath,Stringfilename,InputStreaminput){ booleanresult=false; FTPClientftp=newFTPClient(); try{ intreply; ftp.connect(host,port);//连接FTP服务器 //如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器 ftp.login(username,password);//登录 reply=ftp.getReplyCode(); if(!FTPReply.isPositiveCompletion(reply)){ ftp.disconnect(); returnresult; } //切换到上传目录 if(!ftp.changeWorkingDirectory(basePath+filePath)){ //如果目录不存在创建目录 String[]dirs=filePath.split("/"); StringtempPath=basePath; for(Stringdir:dirs){ if(null==dir||"".equals(dir))continue; tempPath+="/"+dir; if(!ftp.changeWorkingDirectory(tempPath)){ if(!ftp.makeDirectory(tempPath)){ returnresult; }else{ ftp.changeWorkingDirectory(tempPath); } } } } //设置上传文件的类型为二进制类型 ftp.setFileType(FTP.BINARY_FILE_TYPE); //上传文件 if(!ftp.storeFile(filename,input)){ returnresult; } input.close(); ftp.logout(); result=true; }catch(IOExceptione){ e.printStackTrace(); }finally{ if(ftp.isConnected()){ try{ ftp.disconnect(); }catch(IOExceptionioe){ } } } returnresult; } /** *Description:从FTP服务器下载文件 *@paramhostFTP服务器hostname *@paramportFTP服务器端口 *@paramusernameFTP登录账号 *@parampasswordFTP登录密码 *@paramremotePathFTP服务器上的相对路径 *@paramfileName要下载的文件名 *@paramlocalPath下载后保存到本地的路径 *@return */ publicstaticbooleandownloadFile(Stringhost,intport,Stringusername,Stringpassword,StringremotePath, StringfileName,StringlocalPath){ booleanresult=false; FTPClientftp=newFTPClient(); try{ intreply; ftp.connect(host,port); //如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器 ftp.login(username,password);//登录 reply=ftp.getReplyCode(); if(!FTPReply.isPositiveCompletion(reply)){ ftp.disconnect(); returnresult; } ftp.changeWorkingDirectory(remotePath);//转移到FTP服务器目录 FTPFile[]fs=ftp.listFiles(); for(FTPFileff:fs){ if(ff.getName().equals(fileName)){ FilelocalFile=newFile(localPath+"/"+ff.getName()); OutputStreamis=newFileOutputStream(localFile); ftp.retrieveFile(ff.getName(),is); is.close(); } } ftp.logout(); result=true; }catch(IOExceptione){ e.printStackTrace(); }finally{ if(ftp.isConnected()){ try{ ftp.disconnect(); }catch(IOExceptionioe){ } } } returnresult; } publicstaticvoidmain(String[]args){ try{ FileInputStreamin=newFileInputStream(newFile("D:\\temp\\image\\gaigeming.jpg")); booleanflag=uploadFile("192.168.25.133",21,"ftpuser","ftpuser","/home/ftpuser/www/images","/2015/01/21","gaigeming.jpg",in); System.out.println(flag); }catch(FileNotFoundExceptione){ e.printStackTrace(); } } } 8.各种id生成策略 [java] view plain copy packagecom.taotao.utils; importjava.util.Random; /** *各种id生成策略 *<p>Title:IDUtils</p> *<p>Description:</p> *@date2015年7月22日下午2:32:10 *@version1.0 */ publicclassIDUtils{ /** *图片名生成 */ publicstaticStringgenImageName(){ //取当前时间的长整形值包含毫秒 longmillis=System.currentTimeMillis(); //longmillis=System.nanoTime(); //加上三位随机数 Randomrandom=newRandom(); intend3=random.nextInt(999); //如果不足三位前面补0 Stringstr=millis+String.format("%03d",end3); returnstr; } /** *商品id生成 */ publicstaticlonggenItemId(){ //取当前时间的长整形值包含毫秒 longmillis=System.currentTimeMillis(); //longmillis=System.nanoTime(); //加上两位随机数 Randomrandom=newRandom(); intend2=random.nextInt(99); //如果不足两位前面补0 Stringstr=millis+String.format("%02d",end2); longid=newLong(str); returnid; } publicstaticvoidmain(String[]args){ for(inti=0;i<100;i++) System.out.println(genItemId()); } } 9.上传图片返回值 [java] view plain copy packagecom.result; /** *上传图片返回值 *<p>Title:PictureResult</p> *<p>Description:</p> *<p>Company:www.itcast.com</p> *@author入云龙 *@date2015年7月22日下午2:09:02 *@version1.0 */ publicclassPictureResult{ /** *上传图片返回值,成功:0失败:1 */ privateIntegererror; /** *回显图片使用的url */ privateStringurl; /** *错误时的错误消息 */ privateStringmessage; publicPictureResult(Integerstate,Stringurl){ this.url=url; this.error=state; } publicPictureResult(Integerstate,Stringurl,StringerrorMessage){ this.url=url; this.error=state; this.message=errorMessage; } publicIntegergetError(){ returnerror; } publicvoidsetError(Integererror){ this.error=error; } publicStringgetUrl(){ returnurl; } publicvoidsetUrl(Stringurl){ this.url=url; } publicStringgetMessage(){ returnmessage; } publicvoidsetMessage(Stringmessage){ this.message=message; } } 10.自定义响应结构 [java] view plain copy packagecom.result; importjava.util.List; importcom.fasterxml.jackson.databind.JsonNode; importcom.fasterxml.jackson.databind.ObjectMapper; /** *自定义响应结构 */ publicclassTaotaoResult{ //定义jackson对象 privatestaticfinalObjectMapperMAPPER=newObjectMapper(); //响应业务状态 privateIntegerstatus; //响应消息 privateStringmsg; //响应中的数据 privateObjectdata; publicstaticTaotaoResultbuild(Integerstatus,Stringmsg,Objectdata){ returnnewTaotaoResult(status,msg,data); } publicstaticTaotaoResultok(Objectdata){ returnnewTaotaoResult(data); } publicstaticTaotaoResultok(){ returnnewTaotaoResult(null); } publicTaotaoResult(){ } publicstaticTaotaoResultbuild(Integerstatus,Stringmsg){ returnnewTaotaoResult(status,msg,null); } publicTaotaoResult(Integerstatus,Stringmsg,Objectdata){ this.status=status; this.msg=msg; this.data=data; } publicTaotaoResult(Objectdata){ this.status=200; this.msg="OK"; this.data=data; } //publicBooleanisOK(){ //returnthis.status==200; //} publicIntegergetStatus(){ returnstatus; } publicvoidsetStatus(Integerstatus){ this.status=status; } publicStringgetMsg(){ returnmsg; } publicvoidsetMsg(Stringmsg){ this.msg=msg; } publicObjectgetData(){ returndata; } publicvoidsetData(Objectdata){ this.data=data; } /** *将json结果集转化为TaotaoResult对象 * *@paramjsonDatajson数据 *@paramclazzTaotaoResult中的object类型 *@return */ publicstaticTaotaoResultformatToPojo(StringjsonData,Class<?>clazz){ try{ if(clazz==null){ returnMAPPER.readValue(jsonData,TaotaoResult.class); } JsonNodejsonNode=MAPPER.readTree(jsonData); JsonNodedata=jsonNode.get("data"); Objectobj=null; if(clazz!=null){ if(data.isObject()){ obj=MAPPER.readValue(data.traverse(),clazz); }elseif(data.isTextual()){ obj=MAPPER.readValue(data.asText(),clazz); } } returnbuild(jsonNode.get("status").intValue(),jsonNode.get("msg").asText(),obj); }catch(Exceptione){ returnnull; } } /** *没有object对象的转化 * *@paramjson *@return */ publicstaticTaotaoResultformat(Stringjson){ try{ returnMAPPER.readValue(json,TaotaoResult.class); }catch(Exceptione){ e.printStackTrace(); } returnnull; } /** *Object是集合转化 * *@paramjsonDatajson数据 *@paramclazz集合中的类型 *@return */ publicstaticTaotaoResultformatToList(StringjsonData,Class<?>clazz){ try{ JsonNodejsonNode=MAPPER.readTree(jsonData); JsonNodedata=jsonNode.get("data"); Objectobj=null; if(data.isArray()&&data.size()>0){ obj=MAPPER.readValue(data.traverse(), MAPPER.getTypeFactory().constructCollectionType(List.class,clazz)); } returnbuild(jsonNode.get("status").intValue(),jsonNode.get("msg").asText(),obj); }catch(Exceptione){ returnnull; } } } 11.jedis操作 [java] view plain copy packagecom.taotao.jedis; publicinterfaceJedisClient{ Stringset(Stringkey,Stringvalue); Stringget(Stringkey); Booleanexists(Stringkey); Longexpire(Stringkey,intseconds); Longttl(Stringkey); Longincr(Stringkey); Longhset(Stringkey,Stringfield,Stringvalue); Stringhget(Stringkey,Stringfield); Longhdel(Stringkey,String...field); } [java] view plain copy packagecom.taotao.jedis; importorg.springframework.beans.factory.annotation.Autowired; importredis.clients.jedis.JedisCluster; publicclassJedisClientClusterimplementsJedisClient{ @Autowired privateJedisClusterjedisCluster; @Override publicStringset(Stringkey,Stringvalue){ returnjedisCluster.set(key,value); } @Override publicStringget(Stringkey){ returnjedisCluster.get(key); } @Override publicBooleanexists(Stringkey){ returnjedisCluster.exists(key); } @Override publicLongexpire(Stringkey,intseconds){ returnjedisCluster.expire(key,seconds); } @Override publicLongttl(Stringkey){ returnjedisCluster.ttl(key); } @Override publicLongincr(Stringkey){ returnjedisCluster.incr(key); } @Override publicLonghset(Stringkey,Stringfield,Stringvalue){ returnjedisCluster.hset(key,field,value); } @Override publicStringhget(Stringkey,Stringfield){ returnjedisCluster.hget(key,field); } @Override publicLonghdel(Stringkey,String...field){ returnjedisCluster.hdel(key,field); } } [java] view plain copy packagecom.taotao.jedis; importorg.springframework.beans.factory.annotation.Autowired; importredis.clients.jedis.Jedis; importredis.clients.jedis.JedisPool; publicclassJedisClientPoolimplementsJedisClient{ @Autowired privateJedisPooljedisPool; @Override publicStringset(Stringkey,Stringvalue){ Jedisjedis=jedisPool.getResource(); Stringresult=jedis.set(key,value); jedis.close(); returnresult; } @Override publicStringget(Stringkey){ Jedisjedis=jedisPool.getResource(); Stringresult=jedis.get(key); jedis.close(); returnresult; } @Override publicBooleanexists(Stringkey){ Jedisjedis=jedisPool.getResource(); Booleanresult=jedis.exists(key); jedis.close(); returnresult; } @Override publicLongexpire(Stringkey,intseconds){ Jedisjedis=jedisPool.getResource(); Longresult=jedis.expire(key,seconds); jedis.close(); returnresult; } @Override publicLongttl(Stringkey){ Jedisjedis=jedisPool.getResource(); Longresult=jedis.ttl(key); jedis.close(); returnresult; } @Override publicLongincr(Stringkey){ Jedisjedis=jedisPool.getResource(); Longresult=jedis.incr(key); jedis.close(); returnresult; } @Override publicLonghset(Stringkey,Stringfield,Stringvalue){ Jedisjedis=jedisPool.getResource(); Longresult=jedis.hset(key,field,value); jedis.close(); returnresult; } @Override publicStringhget(Stringkey,Stringfield){ Jedisjedis=jedisPool.getResource(); Stringresult=jedis.hget(key,field); jedis.close(); returnresult; } @Override publicLonghdel(Stringkey,String...field){ Jedisjedis=jedisPool.getResource(); Longresult=jedis.hdel(key,field); jedis.close(); returnresult; } } 相关话题:JAVA初级、中级、高级,你是什么级别,你觉得不同级别应该要对哪些技能呢? 与阿里巴巴JAVA大神一起进行JAVA互动交流吧!

优秀的个人博客,低调大师

Linux探索之路1---CentOS入坑笔记整理

前言 上次跟运维去行方安装行内环境,发现linux命令还是不是很熟练。特别是用户权限分配以及vi下的快捷操作。于是决定在本地安装一个CentOS虚拟机,后面有时间就每天学习一点Linux常用命令。 作为一个小白正式入坑CentOS了,于是就有了CentOS摸索系列。后续我会根据自己的摸索情况不间断更新。 安装 安装VMWare WorkStation:直接百度搜索下载安装即可,我这里安装的版本是VMware® Workstation 14 Pro。正版需要序列号,否则只能试用30天。这里我给出一些该版本的序列号: CG54H-D8D0H-H8DHY-C6X7X-N2KG6 ZC3WK-AFXEK-488JP-A7MQX-XL8YF AC5XK-0ZD4H-088HP-9NQZV-ZG2R4 ZC5XK-A6E0M-080XQ-04ZZG-YF08D ZY5H0-D3Y8K-M89EZ-AYPEG-MYUA8 安装CentOS: 直接进入CentOS官网https://www.centos.org/, 点击上方的Get CentOS.并且选择DVD版,我这里下载的版本是: CentOS-7-x86_64-DVD-1708.iso 创建新的虚拟机: 打开VMWare WorkStation, 点击“创建新的虚拟机”---》典型---》选择"安装程序光盘映像文件",选择刚刚下载的iso镜像文件,后续安装过程这里直接跳过 修改root密码 ​ 前面迷迷糊糊的安装完成之后,我需要下载一个东西,于是我使用yum install命令,发现需要root权限,于是我使用su root命令进行用户切换,需要输入root密码,我输入我创建的用户密码一致显示认证失败,完了。看来必须要改一次密码了...... ​ 好在修改密码并不复杂,这里给出一个正确可行的链接:https://linux.cn/article-3962-1.html。 总结了下,基本步骤也就包含以下几个: 启动的时候按e进入grab模式 找到fi后面那一行,将ro替换为rw init=/sysroot/bin/sh 按下Control + X 键,使用单用户模式启动 执行chroot命令,然后执行passwd开始进行密码修改 执行touch /.autorelabel更新系统信息,并执行exit退出chroot模式 执行reboot重启即可 网络连接不上 ​ 修改了root密码之后,切换到root模式下,我想使用yum install 命令下载,发现报了个网络连接不上的错误。于是我试了下: ping www.baidu.com, 竟然报了个name or service not know。无赖继续搜索解决方案,最终发现https://www.cnblogs.com/Lin-Yi/p/7787392.html所说的方案能够正常解决我的问题,这里将关键点列举一下: 添加DNS服务器: root用户执行vi /ect/resolv.conf, 在文件中添加如下两行: nameserver 8.8.8.8 nameserver 8.8.4.4 保存退出后重启虚拟机 修改网络配置: 执行命令vi /etc/sysconfig/network-scprits/ifcfg-ens33(文件名称ifcfg-ens33后面的数字可能不同,最好先进到对应目录ls看下),将文件中的onboot=no替换成onboot=yes .保存并退出 重启网络: root下执行service network restart 重启网络 注意网络配置: 一般情况下执行完前面步骤之后应该可以正常ping通,如果还不行的话,需确认虚拟机的网络适配器配置的是NAT模式 无法鼠标选中复制 ​ 这些基本的问题解决之后,发现鼠标在centOS中无法选中复制文字,于是继续搜索解决。最终解决方案如下: 安装gpm: 执行yum install gpm* 启动gpm服务: 执行service gpm start 将gpm服务添加为后台服务: 执行systemctl enable gpm.service 这里给出CentOS服务启用停用的相关方法: systemctl start [服务文件名] systemctl restart [服务文件名] systemctl stop [服务文件名] systemctl status [服务文件名] 设置开机启动 systemctl enable [服务文件名] systemctl disable [服务文件名] 安装VMTools ​ 安装了gpm之后文字可以在CentOS内部复制粘贴了,但是无法在虚拟机和主机之间进行复制。网上搜索说要安装VMTools,好吧开始安装。 主要参考下面两个链接: https://blog.csdn.net/warnerwu/article/details/73718901 https://www.cnblogs.com/mylinux/p/5612168.html ​ 本地XShell连接虚拟机 ​ 开始准备在CentOS中安装各种软件以方便虚拟机操作,后续一搜才发现,可以直接通过XShell连接CentOS。那直接通过XShell连接CentOS操作比打开丑陋的CentOS操作不是要爽的多。于是开始摸索XShell连接CentOS。 ​ 本来想通过固定虚拟机的IP,这样每次连接CentOS就不用修改IP。但是参照了网上的固定IP教程之后,蛋疼的事情发生了: 虚拟机连接不到网络......而且本机telnet虚拟机的22端口一直不通!! ​ 只有最后还原网络设置,折腾了几个小时终于又能ping通百度了。。 ​ 这里总结下XShell连接CentOS的相关设置: 开启CentOS的SSH服务: 默认情况下CentOS是默认自带SSH的,使用命令rpm -qa|grep ssh查看 是否安装了SSH,如果安装了话输出会大致如下: openssh-7.4p1-11.el7.x86_64 openssh-server-7.4p1-11.el7.x86_64 openssh-clients-7.4p1-11.el7.x86_64 libssh2-1.4.3-10.el7_2.1.x86_64 如果未安装则执行yum install openssh*安装对应的ssh服务。安装完成后通过命令systemctl status sshd查看该服务是否开启。如果未开启,则执行命令service sshd restart . 启动之后通过命令netstat -ant | grep 22进一步确认是否开启ssh的22号端口是否开启 关闭防火墙: systemctl stop firewalld.service #停止firewall systemctl disable firewalld.service #禁止firewall开机启动 firewall-cmd --state #查看默认防火墙状态(关闭后显示notrunning,开启后显示running) 关闭iptables: 如果未安装iptables这里直接跳过,如果安装了iptables这使用下面命令来关闭iptables: systemctl stop iptables.service #重启防火墙使配置生效 systemctl disable iptables.service #设置防火墙开机启动 ​ 之后就可以愉快地使用XShell来连接CentOS了 安装rzsz软件 ​ 刚安装的CentOS是不支持rz/sz命令的,这里直接使用yum install lrzsz进行安装 安装JDK ​ 网上一般给的安装步骤如下: 查找有哪些可安装的JDK: 执行命令 yum search jdk|grep java 安装JDK: 找到想要装的JDK版本,用对应的yum命令进行安装,我这里执行的是yum install java-1.8.0-openjdk.x86_64 ​ 需要注意的是这种情况下,只是安装了JRE。此时不管怎样都是无法启用javac命令的。这里还需要正确安装jdk: 使用rpm -qa | grep jdk查找刚刚安装的jdk,我这里查询的结果如下 java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64 java-1.8.0-openjdk-headless-1.8.0.161-0.b14.el7_4.x86_64 针对刚刚查询出来的jdk依次删除: yum -y remove java java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64 yum -y remove java java-1.8.0-openjdk-headless-1.8.0.161-0.b14.el7_4.x86_64 使用yum install java-devel直接安装原生的jdk即可 配置环境变量: sudo vi /ect/profile, 在文件最后两行之前加入如下配置: export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64 export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar export PATH=$JAVA_HOME/bin:$PATH 重新启用配置文件: 执行命令 source /etc/profile 安装tomcat 安装wget支持: 执行yum install wget 下载tomcat安装包: 直接去tomcat官网找到tomcat的下载链接,然后通过wget命令去获取,我这里执行的命令如下:wget http://mirrors.shu.edu.cn/apache/tomcat/tomcat-9/v9.0.11/bin/apache-tomcat-9.0.11.tar.gz 解压刚下载的tomcat: 执行命令tar -zxvf apache-tomcat-9.0.7.tar.gz 验证: 进入tomcat的bin目录执行:sh startup.sh, 本机通过虚拟机IP:端口访问看是否成功 修改目录的所有者 ​ 在开始安装tomcat的过程中,我开始在创建tomcat目录是在root用户下操作的。后续我切换到tomcat用户发现wget没有权限写这个tomcat目录。于是通过以下命令将该目录以及其下的子目录权限全部改为tomcat用户: chown -R tomcat:tomcat tomcat 其中-R表示递归旗下的所有子目录 如何返回上一次输入的目录 ​ 直接执行cd - 即可返回上一次操作的目录。输入cd或者cd ~ 即可进入当前用户的根目录 黎明前最黑暗,成功前最绝望!

优秀的个人博客,低调大师

android例子程序(ApiDemo)的简单分类整理

总览: -App(应用) -Content(字体样式) -Graphics(图像) -Media(媒体) -OS(操作系统) -Text(文本显示样式) -Views(视图) -App(应用) --Activity ---Animation(教你以怎样的动态效果显示一个新ACTIVITY) ---Custom Dialog(教你如何定制对话框DIALOG) ---Custom Title(教你如何改变程序的标题栏信息) ---Dialog(教你如何打开一个标准的对话框DIALOG) ---Forwarding(直接跳转,并不保存当前ACTIVITY,所以当你跳转后点返回的时候不会回到当前ACTIVITY) ---Hello World(这个地球人都知道) ---Persistent State(教你如何使保存在某个ACTIVITY中的信息不因ACTIVITY的切换而消失。)(所谓的有状态和无状态?) ---QuickContactsDemo(教你如何对联系人进行快速操作) ---Receive Result(从另一个ACTIVITY中得到数据返回给当前ACTIVITY) ---Redirection(从一个ACTIVITY获得用户数据传给下一个ACTIVITY,注意和前一个的区别) ---Reorder Activities(在四个ACTIVITY间进行切换,这个不知道用来干嘛的?) ---Save & Restore State(在onSaveInstanceState()方法中保存状态信息,在onCreate()中恢复状态信息。不太明白这个) ---SetWallpaper(教你如何修改和设置墙纸) ---Translucent(教你如何设置半透明背景,此处背景为前一个ACTIVITY) ---Translucent Blur(同上,只是增加了背景模糊处理) ---Wallpaper(同Translucent,只是此处背景为墙纸) --Alarm(任务安排,闹钟的处理) --Dialog(对话框) ---确定、取消对话框 ---确定、取消、外加一段描述信息的对话框 ---下拉选择框 ---进度条对话框 ---单选下拉列表框 ---多选下拉列表框 ---带文本输入的对话框 --Intents(加载数据?不是很明白) --Laucher Shortcuts(加载快捷键,具体使用有待跟进) --Menu(教你如何给自己的程序添加菜单) --Notification(通知) ---IncomingMessage(来电信息通知) ---Notifying Service Controller(通知服务控制器设置) ---NotifyWithText(文本形式的通知) ---Status Bar(通过修改状态栏来实现通知) 本文转自java豆子博客园博客,原文链接:http://www.cnblogs.com/error404/archive/2011/10/10/2205173.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

iOS ReactiveCocoa 最全常用API整理(可做为手册查询)

本文适合有一定RAC基础的童鞋做不时的查询,所以本文不做详细解释。 一、常见类 1、RACSiganl 信号类。 RACEmptySignal :空信号,用来实现 RACSignal 的 +empty 方法; RACReturnSignal :一元信号,用来实现 RACSignal 的 +return: 方法; RACDynamicSignal :动态信号,使用一个 block - 来实现订阅行为,我们在使用 RACSignal 的 +createSignal: 方法时创建的就是该类的实例; RACErrorSignal :错误信号,用来实现 RACSignal 的 +error: 方法; RACChannelTerminal :通道终端,代表 RACChannel 的一个终端,用来实现双向绑定。 2、RACSubscriber 订阅者 3、RACDisposable 用于取消订阅或者清理资源,当信号发送完成或者发送错误的时候,就会自动触发它。 RACSerialDisposable :作为 disposable 的容器使用,可以包含一个 disposable 对象,并且允许将这个 disposable 对象通过原子操作交换出来; RACKVOTrampoline :代表一次 KVO 观察,并且可以用来停止观察; RACCompoundDisposable :它可以包含多个 disposable 对象,并且支持手动添加和移除 disposable 对象 RACScopedDisposable :当它被 dealloc 的时候调用本身的 -dispose 方法。 4、RACSubject 信号提供者,自己可以充当信号,又能发送信号。 RACGroupedSignal :分组信号,用来实现 RACSignal 的分组功能; RACBehaviorSubject :重演最后值的信号,当被订阅时,会向订阅者发送它最后接收到的值; RACReplaySubject :重演信号,保存发送过的值,当被订阅时,会向订阅者重新发送这些值。 5、RACTuple 元组类,类似NSArray,用来包装值. 6、RACSequence RAC中的集合类 7、RACCommand RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,他可以很方便的监控事件的执行过程。 8、RACMulticastConnection 用于当一个信号,被多次订阅时,为了保证创建信号时,避免多次调用创建信号中的block,造成副作用,可以使用这个类处理。 9、RACScheduler RAC中的队列,用GCD封装的。 RACImmediateScheduler :立即执行调度的任务,这是唯一一个支持同步执行的调度器; RACQueueScheduler :一个抽象的队列调度器,在一个 GCD 串行列队中异步调度所有任务; RACTargetQueueScheduler :继承自 RACQueueScheduler ,在一个以一个任意的 GCD 队列为 target 的串行队列中异步调度所有任务; RACSubscriptionScheduler :一个只用来调度订阅的调度器。 二、常见用法 rac_signalForSelector : 代替代理 rac_valuesAndChangesForKeyPath: KVO rac_signalForControlEvents:监听事件 rac_addObserverForName 代替通知 rac_textSignal:监听文本框文字改变 rac_liftSelector:withSignalsFromArray:Signals:当传入的Signals(信号数组),每一个signal都至少sendNext过一次,就会去触发第一个selector参数的方法。 三、常见宏 RAC(TARGET, [KEYPATH, [NIL_VALUE]]):用于给某个对象的某个属性绑定 RACObserve(self, name) :监听某个对象的某个属性,返回的是信号。 @weakify(Obj)和@strongify(Obj) RACTuplePack :把数据包装成RACTuple(元组类) RACTupleUnpack:把RACTuple(元组类)解包成对应的数据 RACChannelTo 用于双向绑定的一个终端 四、常用操作方法 flattenMap map 用于把源信号内容映射成新的内容。 concat 组合 按一定顺序拼接信号,当多个信号发出的时候,有顺序的接收信号 then 用于连接两个信号,当第一个信号完成,才会连接then返回的信号。 merge 把多个信号合并为一个信号,任何一个信号有新值的时候就会调用 zipWith 把两个信号压缩成一个信号,只有当两个信号同时发出信号内容时,并且把两个信号的内容合并成一个元组,才会触发压缩流的next事件。 combineLatest:将多个信号合并起来,并且拿到各个信号的最新的值,必须每个合并的signal至少都有过一次sendNext,才会触发合并的信号。 reduce聚合:用于信号发出的内容是元组,把信号发出元组的值聚合成一个值 filter:过滤信号,使用它可以获取满足条件的信号. ignore:忽略完某些值的信号. distinctUntilChanged:当上一次的值和当前的值有明显的变化就会发出信号,否则会被忽略掉。 take:从开始一共取N次的信号 takeLast:取最后N次的信号,前提条件,订阅者必须调用完成,因为只有完成,就知道总共有多少信号. takeUntil:(RACSignal *):获取信号直到某个信号执行完成 skip:(NSUInteger):跳过几个信号,不接受。 switchToLatest:用于signalOfSignals(信号的信号),有时候信号也会发出信号,会在signalOfSignals中,获取signalOfSignals发送的最新信号。 doNext: 执行Next之前,会先执行这个Block doCompleted: 执行sendCompleted之前,会先执行这个Block timeout:超时,可以让一个信号在一定的时间后,自动报错。 interval 定时:每隔一段时间发出信号 delay 延迟发送next。 retry重试 :只要失败,就会重新执行创建信号中的block,直到成功. replay重放:当一个信号被多次订阅,反复播放内容 throttle节流:当某个信号发送比较频繁时,可以使用节流,在某一段时间不发送信号内容,过了一段时间获取信号的最新内容发出。 五、UI - Category(常用汇总) 1、rac_prepareForReuseSignal: 需要复用时用 相关UI: MKAnnotationView、UICollectionReusableView、UITableViewCell、UITableViewHeaderFooterView 2、rac_buttonClickedSignal:点击事件触发信号 相关UI:UIActionSheet、UIAlertView 3 、rac_command:button类、刷新类相关命令替换 相关UI:UIBarButtonItem、UIButton、UIRefreshControl 4、rac_signalForControlEvents: control event 触发 相关UI:UIControl 5、rac_gestureSignal UIGestureRecognizer 事件处理信号 相关UI:UIGestureRecognizer 6、rac_imageSelectedSignal 选择图片的信号 相关UI:UIImagePickerController 7、rac_textSignal 相关UI:UITextField、UITextView 8、可实现双向绑定的相关API rac_channelForControlEvents: key: nilValue: 相关UI:UIControl类 rac_newDateChannelWithNilValue: 相关UI:UIDatePicker rac_newSelectedSegmentIndexChannelWithNilValue: 相关UI:UISegmentedControl rac_newValueChannelWithNilValue: 相关UI:UISlider、UIStepper rac_newOnChannel 相关UI:UISwitch rac_newTextChannel 相关UI:UITextField 六、Foundation - Category (常用汇总) 1、NSArray rac_sequence 信号集合 2、NSData rac_readContentsOfURL: options: scheduler: 比oc多出线程设置 3、NSDictionary rac_sequence 不解释 rac_keySequence key 集合 rac_valueSequence value 集合 4、NSEnumerator rac_sequence 不解释 5、NSFileHandle rac_readInBackground 见名知意 6、NSIndexSet rac_sequence 不解释 7、NSInvocation rac_setArgument: atIndex: 设置参数 rac_argumentAtIndex 取某个参数 rac_returnValue 所关联方法的返回值 8、NSNotificationCenter rac_addObserverForName: object:注册通知 9、NSObject rac_willDeallocSignal 对象销毁时发动的信号 rac_description debug用 rac_observeKeyPath: options: observer: block:监听某个事件 rac_liftSelector: withSignals: 全部信号都next在执行 rac_signalForSelector: 代替某个方法 rac_signalForSelector:(SEL)selector fromProtocol:代替代理 10、NSOrderedSet rac_sequence 不解释 11、NSSet rac_sequence 不解释 12、NSString rac_keyPathComponents 获取一个路径所有的部分 rac_keyPathByDeletingLastKeyPathComponent 删除路径最后一部分 rac_keyPathByDeletingFirstKeyPathComponent 删除路径第一部分 rac_sequence 不解释 (character) rac_readContentsOfURL: usedEncoding: scheduler: 比之OC多线程调用 13、NSURLConnection rac_sendAsynchronousRequest 发起异步请求 14、NSUserDefaults rac_channelTerminalForKey 用于双向绑定,此乃一 作者:王隆帅 来源:51CTO

优秀的个人博客,低调大师

给 Java 学习者的超全教程整理

Java 在编程语言排行榜中一直位列前排,可知 Java 语言的受欢迎程度了。 网上有很多 Java 教程,无论是基础入门还是开发小项目的教程都比比皆是,可是系统的很少,对于Java 学习者来说找到系统、完整、可学性较强的教程其实并不是那么容易。实验楼上有很多 Java 教程,从基础入门、J2SE 开发、SSH 框架到实战项目都有,因此,这里就把这些课程总结一下,希望对 Java 学习者有所帮助~ 一、Java基础 Java 基础不必多说了,下面的5门课程就可以带你动手学习,入门Java。 Java编程语言 这个课程介绍了 Java 基本语法、Java 平台应用、 Java 的核心概念:JVM、JDK、JRE以及 java 面向对象思想。非常适合 Java 入门学习。 Java 8 新特性指南 Java 8是近年来一个Java编程语言发行版本,由Oracle 2014年3月发布。该版本为Java带来许多新特性,是一个具有重大改变的版本。 这个课程适用于Java初学者或者是具有一定编程经验的开发者,主要是学习 Java 8 的一些新特性,为自己的技能升级打补丁。如果你想学习java可以来这个群,首先是二二零,中间是一四二,最后是九零六,里面有大量的学习资料可以下载。 JDBC 入门教程 这个教程学习 JDBC 定义和架构,回顾 SQL 语法,搭建 JDBC 的环境,通过实例来深入学习 JDBC。 JDK 核心 API 这个课程学习包括 java.lang 包,java.util 包,java.io 包以及泛型的相关知识。 Java进阶之设计模式 这个课程介绍常用的设计模式以及 Java 语言的实现实例来学习 java 设计模式。通过这个课程可以学习到很多类型的设计模式,其中包括工厂模式、抽象工厂模式、单例模式、适配器模式、观察者模式、装饰者模式等等。 二、J2SE 开发 J2SE,全称为Java 2 Standard Edition。Java 2平台包括:标准版(J2SE)、企业版(J2EE)和微缩版(J2ME)三个版本。J2SE即Java 2的标准版,主要用于桌面应用软件的开发。 下面这段话是ORACLE对于Java SE的官方描述: Java Platform, Standard Edition (Java SE) 可以让您在桌面和服务器以及目前要求较高的嵌入式环境中开发和部署 Java 应用程序。 Java 提供了当今应用程序所需要的丰富的用户界面、良好的性能、多功能性、可移植性和安全性。 J2SE与J2EE、J2ME之间的关系可以通过下图来表示: J2SE的架构 J2SE的架构如下图所示,它主要包含了UI、集成库、语言和工具基础库、其他基础库、Java虚拟机等组件。 综上所述,将J2SE压缩一点再加上一些CLDC等方面的特性就是J2ME;将其扩充一点再增加一些EJB等企业应用方面的特性就是J2EE。因此J2SE是J2EE的基础,建议从事Java的开发人员从J2SE开始学习。 以下是学习J2SE的教程: J2SE核心开发实战 这个课程主要讲解IO、Util等常用类库的使用、Swing图形化编程、多线程编程等知识点。 J2SE网络通信实践 这个课程介绍怎么使用 J2SE 常用网络通信 API 以及 Socket 编程。可以学习到网络基础知识、获取URL资源的大小、Swing图形界面编程、套接字编程。 三、Java SSH框架 SSH(Spring + Struts + Hibernate)集成框架,是应用十分广泛的一种 Java Web 应用程序开发框架。SSH 框架也体现了典型的分层结构,分层有很多好处,例如项目整体的构架更加清晰,代码也更易维护和扩展。 通常来说,SSH 整体上大致可以用下图描述: 以下是教程: Spring框架入门教程 这个课程主要是介绍 Spring 框架。 Struts框架教程 这个课程主要是介绍 Struts 框架。 Hibernate框架教程 这个课程主要是介绍 Hibernate 框架。 SSH 框架应用实例 这个课程学习 SSH(Spring + Struts + Hibernate)集成框架的应用,并用 SSH 框架开发一个简单的用户管理网站。 四、Java 实战项目 当然,我们在学习了Java各种基础知识之后,最需要做的就是学会应用,开发一些项目把所学的知识应用起来,下面的8个实战项目就是比较好的练手教程。 1、Java开发简单的计算器 这个项目一看名字就知道,开发一个常见的计算器。 2、Java实现记事本 这也是一个常见的Java项目,开发记事本。 3、Java实现电子通讯录 用Java实现电子通讯录功能。 4、Java实现简单的支付平台业务流程 这个项目编写简单的 PayPlatform 程序模拟支付平台流程,主要涉及到 Java 线程与同步。 5、自己的Java编辑器 项目使用 Eclipse 开发,配合 Java 语言完成一个 Java 编辑器。它的主要功能:1、Java代码的编辑 2、编译及运行Java程序。 6、Java实现MD5文件校验 项目使用 Java 语言编写对文件进行MD5值的校验程序。可以学习到MD5的加密逻辑以及Swing插件的安装方法和Java界面编程等知识。 7、Java和WebSocket开发网页聊天室 8、结合七牛搭建个人相册 项目基于七牛云存储的 SDK 实现个人相册服务,学习并实践 Java Web 开发基本方法及七牛云存储 Java API 接口。 最后 ,以上,就是总结的Java学习教程,无论是Java初学者,还是想找项目练手的,都可以找到合适的教程。 当然,教程是有了,剩下的就是自己多动手学习啦!

优秀的个人博客,低调大师

关于MySQL常见的所有锁,已汇总整理完毕

我,小Y。 又来面试了,还是之前那家公司,即将和之前那个老面试官进行第二次 battle,心情还是xue微有点忐忑。 没看过第一次 battle 的同学可以看这里,一个MVCC和面试官大战三十回合 又一抹光亮闪过,面试官推门而入,我抬头望去,没错,还是那味儿。 看到面试官头上那“傲然矗立”的头发,差点又想站起来给他敬了个礼,算了先稳住,低调一点。 面试官瞥了我一眼:来吧,咱们继续面试,上次没办法,女朋友就是粘人,这次问 MySQL InnoDB 的锁喔。 我:.....(行,我知道你有女朋友了),好的面试官,您请。 面试官:MySQL InnoDB 的锁 和 MyISAM 的锁有什么区别? 我:MyISAM 只支持表锁,一锁就锁整张表,而 InnoDB 不仅支持表锁,还支持粒度更低的行锁,仅对相关的记录上锁即可,所以对于写入操作来说 InnoDB 的性能更高。 面试官:那不论表锁还是行锁,其实有分为两类的,你知道是哪两类吗? 我:你指的是 shared (S) locks 和 exclusive (X) locks 吗? S锁,称为共享锁,事务在读取记录的时候获取 S 锁,它允许多个事务同时获取 S 锁,互相之间不会冲突。 X锁,称为独占锁,事务在修改记录的时候获取 X 锁,且只允许一个事务获取 X 锁,其它事务需要阻塞等待。 所以 S 锁之间不冲突,X 锁则为独占锁,所以 X 之间会冲突, X 和 S 也会冲突。 冲突 S X S 不冲突 冲突 X 冲突 冲突 不论是表级别锁还是行级别锁,S 和 X 的特性都是一样的。 面试官:你说事务在读取记录的时候需要获取 S 锁?这不对吧? 我:确实不准确。益与 MVCC 的功劳,普通的 select 是不需要加锁的。 而 SELECT ... LOCK IN SHARE MODE; 这种读取需要对记录上 S 锁。 SELECT ... FOR UPDATE; 这种需要对记录上 X 锁。 面试官:对了,你刚提到表级锁,那你平时用过 InnoDB 的表锁吗? 我:没用过,InnoDB 的表锁很鸡肋,我知道: LOCK TABLES yes READ 是对 yes 这个表上 S 锁。 LOCK TABLES yes WRITE 是对 yes 这个表上 X 锁。 但是基本上没用。 面试官:噢?怎么个鸡肋了? 我:平日的 update 、select 要用也是用行锁了,不可能用粒度粗的表锁。唯一能想到用上表锁的就是 DDL 语句了,比如 ALTER TABLE 的时候,应该锁定整个表,防止查询和修改。 但是这个 server 已经提供了一个叫 MDL 的东西,即 Metadata Locks,所以已经用 MDL 来阻塞了,表锁也就排不上用场了。 真要用表锁,估计也就是数据恢复的时候,手动锁表还原数据了。 面试官摸了摸头上的反光处:可以,但是如果真要到用表锁的时候,那表锁和行锁之间不是会冲突的吗?如果表里面已经加了行锁怎么办?得一条记录一条记录遍历过去找行锁吗? 我:这确实是一种实现方式,但是性能太差了,假设数据库里有上千万的数据,这加个表锁得找死。 所以有了个叫意向锁(Intention Locks)的东西。 IS(Intention Shared Lock),共享意向锁 IX(Intention Exclusive Lock),独占意向锁。 这两个锁是表级别的锁,当需要对表中的某条记录上 S 锁的时候,先在表上加个 IS 锁,表明此时表内有 S 锁。当需要对表中的某条记录上 X 锁的时候,先在表上加个 IX 锁,表明此时表内有 X 锁。 这样操作之后,如果要加表锁,就不需要遍历所有记录去找了,直接看看表上面有没有 IS 和 IX 锁。 比如,此时要上表级别的 S 锁,如果表上没有 IX ,说明表中没有记录有独占锁,其实就可以直接上表级 S 锁。 如果此时要上表级别的 X 锁,如果表上没有 IX 和 IS ,说明表中的所有记录都没加锁,其实就可以直接上表级 X 锁。 因此 IS 和 IX 的作用就是在上表级锁的时候,可以快速判断是否可以上锁,而不需要遍历表中的所有记录。 所以 IS 和 IX 互相之间是不会冲突的,因为它们的作用只是打个标记,来丰富一下上面的表格: 冲突 S X IS IX S 不冲突 冲突 不冲突 冲突 X 冲突 冲突 冲突 冲突 IS 不冲突 冲突 不冲突 不冲突 IX 冲突 冲突 不冲突 不冲突 面试官:行,那再来说说行锁吧,InnoDB 有几类行锁? 我:有记录锁(Record Locks)、间隙锁(Gap Locks)、Next-Key Locks。 面试官:详细说说看? 我:记录锁顾名思义就是锁住当前的记录,它是作用到索引上的。我们都知道 innodb 是肯定有索引的,即使没有主键也会创建隐藏的聚簇索引,所以记录锁总是锁定索引记录。 比如,此时一个事务 A 执行 SELECT * FROM yes WHERE name = 'xx' FOR UPDATE; 那么 name = xx 这条记录就被锁定了,其他事务无法插入、删除、修改 name = xx 的记录。 此时事务 A 还未提交,另一个事务 B 要执行 insert into yes (name) values ('xx'),此时会被阻塞,这个很好理解。 但是,如果另一个事务 C 执行了 insert into yes (name) values ('aa'),这个语句会被阻塞吗? 看情况。 如果 name 没有索引。前面提到记录锁是加到索引上的,但是 name 没索引啊,那只能去找聚簇索引,但聚簇索引上面只有主键啊,它哪知道各自的 name 是什么,所以咋办?都锁了呗! 因此,如果 name 没有索引,那么事务 C 会被阻塞,如果有索引,则不会被阻塞! 所以这里要注意,没索引的列不要轻易的锁,不要以为有行锁就可以为所欲为,并不是这样滴。 面试官:哟,有点东西,继续继续。 我:然后是间隙锁,这个东西它有点东西。 前面说了,记录锁需要加到记录上,但是如果要给此时还未存在的记录加锁怎么办?也就是要预防幻读的出现! 这时候间隙锁就派上用场了,它是给间隙加上锁。 比如此时有 1、3、5、10 这四条记录,之前的文章分析过,数据页中还有两条虚拟的记录,分别是 Infimum 和 Supremum。 可以看到,记录之前都有间隙,那间隙锁呢,锁的就是这个间隙! 比如我把 3 和 5 之间的间隙锁了,此时要插入 id = 4 的记录,就会被这个间隙锁给阻塞了,这样就避免了幻读的产生!也就实现了锁定未插入的记录的需求! 还有个 Next-Key Locks 就是记录锁+间隙锁,像上面间隙锁的举例,只能锁定(3,5) 这个区间,而 Next-Key Locks 是一个前开后闭的区间(3,5],这样能防止查询 id=5 的这个幻读。 面试官:那间隙锁之间会不会冲突? 我 :不会,间隙锁的唯一目的就是防止其他事务插入数据到间隙中 ,所以即使两个间隙锁要锁住相同的间隙也没有关系,因为它们的目的是一致的,所以不冲突。 面试官:那间隙锁可以显式禁用吗? 我 :可以的。间隙锁是在事务隔离级别为可重复读的时候生效的,如果将事务隔离级别更改为 READ COMMITTED,就会禁用了,此时,间隙锁对于搜索和索引扫描是禁用的,仅用于外键约束检查和重复键检查。 面试官:说到间隙锁,那你知道什么是插入意向锁吗? 我:插入意向锁,即 Insert Intention Locks,它也是一类间隙锁,但是它不是锁定间隙,而是等待某个间隙。比如上面举例的 id = 4 的那个事务 C ,由于被间隙锁给阻塞了,所以事务 C 会生成一个插入意向锁,表明等待这个间隙锁的释放。 并且插入意向锁之间不会阻塞,因为它们的目的也是只等待这个间隙被释放,所以插入意向锁之间没有冲突。 面试官:所以这个插入意向锁其实没什么用的? 我:确实,它的目的不在于锁定资源防止别人访问,我个人觉得更像是为了遵循 MySQL 的锁代码实现而为之。 锁其实就是内存里面的一个结构,每个事务为某个记录或者间隙上锁就是创建一个锁对象来争抢资源。 如果某个事务没有抢到资源,那也会生成一个锁对象,只是状态是等待的,而当拥有资源的事务释放锁之后,就会寻找正在等待当前资源的锁结构,然后选一个让它获得资源并唤醒对应的事务使之得以执行。 所以按照这么个逻辑,那些在等待间隙锁的插入事务,也需要对应的建立一个锁结构,然后锁类型是插入意向锁。 这样一来,间隙锁的事务在释放间隙锁的时候,才能得以找到那些等待插入的事务,然后进行唤醒,而由锁的类型也可以得知是插入意向锁,之间不需要阻塞,所以可以一起执行插入。 面试官:说到插入新记录我问你个问题,如果插入的事务还未提交,现在有另一个事务通过SELECT ... LOCK IN SHARE MODE 或者SELECT ... FOR UPDATE 打算读取这条记录怎么办?此时生效的是什么锁? 我:(我丢,面试官想给我挖坑?哼,但是这难不倒我霸中霸!) 插入的事务还未提交,此时普通 select 没问题,有 MVCC 在,所以读的是老版本。而 SELECT ... LOCK IN SHARE MODE或者SELECT ... FOR UPDATE` 是要获取记录 S 锁和 X 锁的,但是此时事务还未提交,因此这两类 select 会阻塞。 具体是怎么阻塞的呢?因为有事务ID!通过 MVCC 可以利用事务ID 来进行判断当前记录是否可见,这其实相当于一把隐式锁!知道当前记录不可见,于是这个查询事务会为之前未提交的插入的事务生成一个锁结构,然后查询事务自己也生成锁结构,接着等待插入事务的释放,这样就完成了阻塞! 面试官:(这小子,我要压不住他了!)行,那你知道什么是 AUTO-INC Locks 锁吗? 我:知道,Auto-Inc Lock 是一个特殊的表级锁,用于自增列插入数据时使用。在插入一条数据的时候,需要在表上加个 Auto-Inc Lock,然后为自增列分配递增的值,在语句插入结束之后,再释放 Auto-Inc Lock。 在 MySQL 5.1.22 版本之后,又弄了个互斥量来进行自增减的累加。互斥量的性能高于 Auto-Inc Lock,因为 Auto-Inc Lock是语句插入完毕之后才释放锁,而互斥量是在语句插入的时候,获得递增值之后,就可以释放锁,所以性能更好。 但是我们还需要考虑主从的情况,由于并发插入的情况,基于 statement -based binlog 复制时,自增的值顺序无法把控,可能会导致主从数据不一致。 所以 MySQL 有个 innodb_autoinc_lock_mode 配置,一共有三个值: 0,只用 Auto-Inc Lock。 1, 默认值,对于插入前已知插入行数的插入,用互斥量,对于插入前不知道具体插入数的插入,用 Auto-Inc Lock,这样即使基于 statement -based binlog 复制也是安全的。 2,只用互斥量。 面试官:那 MyISAM 有 AUTO-INC Locks 锁吗? 我:没啊,MyISAM 插入本来就用了表锁。 面试官:(这小子行啊,我得找回行子)那你还知道 MySQL 有什么锁吗? 我:(这还没问够??)表锁、IS、IX、MDL、记录锁、间隙锁、Next-key locks、插入意向锁、Auto-Inc Locks,还有啥? 面试官瞥了我一眼:(好小子,总算治了你了)不知道了? 我:(该怂的时候,还是得怂)知识盲区了,请面试官教教我。 面试官:还有个 Predicate Locks,谓词锁。 我:什么玩意? 面试官:InnoDB 是支持空间数据的,所以有空间索引,为了处理涉及空间索引的操作的锁定,next-key locking 不好使,因为多维数据中没有绝对排序的概念,因此不清楚“下一个” key 在哪。 所以为了支持具有空间索引的表的隔离级别,InnoDB使用谓词锁。 空间索引包含最小边界矩形(MBR)值,因此 InnodB 通过在用于查询的 MBR 值上设置谓词锁定,使得 InnoDB 在索引上执行一致性读, 其他事务无法插入或修改与查询条件匹配的行。 我:(.....果然超出了我的知识范围,这个B被他装到了)老面试官您真的是66666。 面试官:行吧,你今天答的马马虎虎还可以,下次再问问你啥 buffer pool、change buffer、doublewrite buffer 啥的。 我:(????还问呢),这是还继续面吗?这算三面吗? 面试官:你管我,我就想多面面你,充分了解一下,我们公司很严格的,人不是随便招的!赶紧回去等通知! 我:行行行,您老等着,就一堆 buffer 是吧,我回去好好准备准备哈~ 今天就到这儿,下篇我再画个图总结汇总一波今天的锁~ 欢迎关注我的公众号【yes的练级攻略】,更多硬核文章等你来读。 我是 yes,从一点点到亿点点,我们下篇见。 本文分享自微信公众号 - yes的练级攻略(yes_java)。 如有侵权,请联系 support@oschina.cn 删除。 本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册