常用代碼、特定函數、復雜概念、特定功能……在學習編程的過程中你會記錄下哪些內容?快來分享你的筆記,一起切磋進步吧!
一、常用代碼
在java編程中常用需要儲備的就是工具類。包括封裝的時間工具類。http工具類,加解密工具類,JSON工具類,翻頁工具類,字符串處理工具類等等。
1、時間工具類
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;public class DateTimeUtils {/*** 獲取當前時間,格式為:yyyy-MM-dd HH:mm:ss* @return*/public static String getDateStr() {SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");return df.format(new Date());}/*** 獲取當前時間,格式為:yyyy-MM-dd* @return*/public static String getDayStr() {SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");return df.format(new Date());}/*** 獲取到月份,格式為:yyyyMM* @return*/public static String getThisMonth() {SimpleDateFormat df = new SimpleDateFormat("yyyyMM");return df.format(new Date());}/*** 獲取到月份,格式為:yyyyMMdd* @return*/public static String getYyyyMMdd() {SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");return df.format(new Date());}/** * @description: 兩個String類型,按照日期格式對比 * eg: * dateOne:2015-12-26 * dateTwo:2015-12-26 * dateFormatType: yyyy-MM-dd * 返回類型:-1:dateOne小于dateTwo, 0:dateOne=dateTwo ,1:dateOne大于dateTwo * @param dateOne * @param dateTwo * @param dateFormatType:yyyy-MM-dd / yyyy-MM-dd HH:mm:ss /等 * @return -1,0,1,100 * @throws */ public static int compareTime(String dateOne, String dateTwo , String dateFormatType){ DateFormat df = new SimpleDateFormat(dateFormatType); Calendar calendarStart = Calendar.getInstance(); Calendar calendarEnd = Calendar.getInstance(); try { calendarStart.setTime(df.parse(dateOne)); calendarEnd.setTime(df.parse(dateTwo)); } catch (ParseException e) { e.printStackTrace(); return 100; } int result = calendarStart.compareTo(calendarEnd); if(result > 0){ result = 1; }else if(result < 0){ result = -1; }else{ result = 0 ; } return result ; } /*** 獲取當前時間,格式為: HH:mm:ss* @return*/public static String getHHmmSS() {SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");return df.format(new Date());}public static void main(String[] args) throws ParseException {System.out.println(DateTimeUtils.getHHmmSS());}//將時間轉換為時間戳public static String dateToStamp(String s) throws ParseException {String res;SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date date = simpleDateFormat.parse(s);long ts = date.getTime();res = String.valueOf(ts);return res;}/*** 獲取昨天日期"yyyy-MM-dd"* @return*/public static String getYesterday() {DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");Calendar calendar=Calendar.getInstance();calendar.set(Calendar.HOUR_OF_DAY,-24);return dateFormat.format(calendar.getTime());}}
2、http工具類
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.util.Map;import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;import cn.hutool.core.collection.CollectionUtil;
import lombok.extern.slf4j.Slf4j;/*** http請求*/
@Slf4j
public class HttpUtils {public static String doGet(String url) {return doGet(url, null);}public static String doGet(String url, Map<String, String> map) {String resultString = "";RestTemplate client = new RestTemplate();HttpHeaders headers = new HttpHeaders();// 參數設置MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();if (CollectionUtil.isNotEmpty(map)) {for (String key : map.keySet()) {params.add(key, map.get(key));}}try {// 設置表單提交headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(params, headers);// 執行HTTP請求ResponseEntity<String> response = client.exchange(url, HttpMethod.GET, requestEntity, String.class);resultString = response.getBody();} catch (Exception e) {log.error(e.getMessage(), e);}return resultString;}public static String doPost(String url) {return doPost(url, null);}public static String doPost(String url, Map<String, String> map) {String resultString = "";ResponseEntity<String> response = null;RestTemplate client = new RestTemplate();HttpHeaders headers = new HttpHeaders();// 參數設置MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();if (CollectionUtil.isNotEmpty(map)) {for (String key : map.keySet()) {params.add(key, map.get(key));}}try {// 請勿輕易改變此提交方式,大部分的情況下,提交方式都是表單提交headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(params, headers);// 執行HTTP請求response = client.exchange(url, HttpMethod.POST, requestEntity, String.class);resultString = response.getBody();} catch (Exception e) {log.error(e.getMessage(), e);}return resultString;}public static String doPostJson(String url, String json) {String resultString = "";RestTemplate client = new RestTemplate();ResponseEntity<String> response = null;// 提交方式設置HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);HttpEntity<String> requestEntity = new HttpEntity<String>(json, headers);try {// 執行HTTP請求response = client.exchange(url, HttpMethod.POST, requestEntity, String.class);resultString = response.getBody();} catch (Exception e) {log.error(e.getMessage(), e);} finally {try {} catch (Exception e) {// TODO Auto-generated catch blocklog.error(e.getMessage(), e);}}return resultString;}/*** 創建http請求頭* @param url* @return* @throws Exception*/public static URLConnection FactoryCreatURLConnection(String url) throws Exception {URL realUrl;URLConnection conn = null;try {// 打開和URL之間的連接realUrl = new URL(url);conn = realUrl.openConnection();conn.setRequestProperty("accept", "text/plain;charset=utf-8");conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");conn.setRequestProperty("connection", "Keep-Alive");conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");} catch (MalformedURLException e1) {e1.printStackTrace();} catch (IOException e) {e.printStackTrace();}return conn;}/*** 判斷連接是否可用* * @param url http請求地址* @return*/public static boolean isRearchUrl(String url) {return isRearchUrl(url, 3000);}/*** 判斷連接是否可用* * @param url http請求地址* @return*/public static boolean isRearchUrl(String url, int timeout) {if (StringUtils.isEmpty(url)) {return false;}HttpURLConnection connection = null;try {connection = (HttpURLConnection) new URL(url).openConnection();// 設置超時時間connection.setConnectTimeout(timeout);connection.setReadTimeout(timeout);if (connection.getResponseCode() >= HttpURLConnection.HTTP_OK&& connection.getResponseCode() <= HttpURLConnection.HTTP_VERSION) {return true;}} catch (Exception e) {log.error(" HttpURLConnection exception happend!");return false;} finally {if (connection != null) {connection.disconnect();}}return false;}/*** 判斷ip是否能ping通*/public static boolean checkIp(String ipAddr) {try {boolean status = false;if (!StringUtils.isEmpty(ipAddr)) {int timeOut = 3000; // 超時 3秒status = InetAddress.getByName(ipAddr).isReachable(timeOut);return status;}return status;} catch (UnknownHostException e) {e.printStackTrace();return false;} catch (IOException e) {e.printStackTrace();return false;}}}
3、加解密工具類
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.AES;/*** Aes加解密* @date 2022-4-07*/
public class AesUtil {private static final Logger logger = LogManager.getLogger("AESUtil");private static final String CHARSET = "UTF-8";public static String base64Encode(byte[] bytes) {return Base64.encodeBase64String(bytes);}public static byte[] base64Decode(String base64Code) throws Exception {return Base64.decodeBase64(base64Code.getBytes(CHARSET));}/*** 加密** @param content* @param encryptKey* @return* @throws Exception*/public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {initEncryptCipher(encryptKey);return encryptCipher.doFinal(content.getBytes(CHARSET));}/*** 加密** @param content* @param encryptKey* @return* @throws Exception*/public static byte[] aesEncryptToBytes(byte[] content, String encryptKey) throws Exception {initEncryptCipher(encryptKey);return encryptCipher.doFinal(content);}/*** 加密轉字符** @param content* @param encryptKey* @return* @throws Exception*/public static String aesEncrypt(String content, String encryptKey) throws Exception {return base64Encode(aesEncryptToBytes(content, encryptKey));}/*** 解密** @param content* @param decryptKey* @return* @throws Exception*/public static byte[] aesDecryptByBytes(String content, String decryptKey) throws Exception {initDecryptCipher(decryptKey);return decryptCipher.doFinal(content.getBytes(CHARSET));}/*** 解密** @param content* @param decryptKey* @return* @throws Exception*/public static byte[] aesDecryptByBytes(byte[] content, String decryptKey) throws Exception {initDecryptCipher(decryptKey);return decryptCipher.doFinal(content);}public static String aesDecrypt(String content, String decryptKey) throws Exception {return new String(aesDecryptByBytes(base64Decode(content), decryptKey));}private static Cipher encryptCipher = null;private static Cipher decryptCipher = null;public static void initEncryptCipher(String aesKey) throws Exception {if (encryptCipher == null) {//5.根據字節數組生成AES密鑰SecretKeySpec skeySpec = new SecretKeySpec(Hex.decodeHex(aesKey.toCharArray()), "AES");//6.根據指定算法AES自成密碼器encryptCipher = Cipher.getInstance("AES");//7.初始化密碼器encryptCipher.init(Cipher.ENCRYPT_MODE, skeySpec);}}public static void initDecryptCipher(String aesKey) throws Exception {if (decryptCipher == null) {//5.根據字節數組生成AES密鑰SecretKeySpec skeySpec = new SecretKeySpec(Hex.decodeHex(aesKey.toCharArray()), "AES");//6.根據指定算法AES自成密碼器decryptCipher = Cipher.getInstance("AES");//7.初始化密碼器decryptCipher.init(Cipher.DECRYPT_MODE, skeySpec);}}public static String hutoolEncrpt(String content,String key){AES aes=new AES(Mode.ECB, Padding.ISO10126Padding, key.getBytes());return aes.encryptBase64(content);}public static String hutoolDecrpt(String content,String key){AES aes=new AES(Mode.ECB, Padding.ISO10126Padding, key.getBytes());return aes.decryptStr(content);}public static void main(String[] args) throws Exception {}}
4、JSON工具類
import java.lang.reflect.Type;import cn.hutool.json.JSONUtil;public class JsonUtil {/*** JSON串轉成對象* * @param jsonStr* @param cls* @return*/public static <T> T fromJson(String jsonStr, Class<T> cls) {try {if (null == jsonStr || jsonStr.trim().length() == 0) {return null;}return JSONUtil.toBean(jsonStr, cls);} catch (Exception e) {return null;}}/*** JSON串轉成對象* * @param jsonStr* @param typeOfT* @return*/public static Object fromJson(String jsonStr, Type typeOfT) {if (null == jsonStr || jsonStr.trim().length() == 0) {return null;}return JSONUtil.toBean(jsonStr, typeOfT, true);}/*** 對象轉JSON串* * @param t* @return*/public static <T> String toJson(T obj) {if (obj == null) {return null;}return JSONUtil.toJsonStr(obj);}
}
5、翻頁工具類
import com.baomidou.mybatisplus.core.metadata.IPage;import java.io.Serializable;
import java.util.List;/*** 分頁工具類*/
public class PageUtils implements Serializable {private static final long serialVersionUID = 1L;/*** 總記錄數*/private int totalCount;/*** 每頁記錄數*/private int pageSize;/*** 總頁數*/private int totalPage;/*** 當前頁數*/private int currPage;/*** 列表數據*/private List<?> list;/*** 分頁* @param list 列表數據* @param totalCount 總記錄數* @param pageSize 每頁記錄數* @param currPage 當前頁數*/public PageUtils(List<?> list, int totalCount, int pageSize, int currPage) {this.list = list;this.totalCount = totalCount;this.pageSize = pageSize;this.currPage = currPage;this.totalPage = (int)Math.ceil((double)totalCount/pageSize);}/*** 分頁*/public PageUtils(IPage<?> page) {this.list = page.getRecords();this.totalCount = (int)page.getTotal();this.pageSize = (int)page.getSize();this.currPage = (int)page.getCurrent();this.totalPage = (int)page.getPages();}public int getTotalCount() {return totalCount;}public void setTotalCount(int totalCount) {this.totalCount = totalCount;}public int getPageSize() {return pageSize;}public void setPageSize(int pageSize) {this.pageSize = pageSize;}public int getTotalPage() {return totalPage;}public void setTotalPage(int totalPage) {this.totalPage = totalPage;}public int getCurrPage() {return currPage;}public void setCurrPage(int currPage) {this.currPage = currPage;}public List<?> getList() {return list;}public void setList(List<?> list) {this.list = list;}}
?二、特定函數
在java開發中使用最多的就是增刪查改翻頁查詢。所以這幾個是比不可少的特定函數。特別是在springboot框架的開發中。像這種具有共性的代碼模塊,我們可以使用逆向工程生成。
import java.util.List;
import java.util.Map;
import cn.hutool.core.util.ObjectUtil;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.ctg.common.util.PageUtils;
import cn.ctg.common.response.ResponseData;
import cn.ctg.common.util.CtgUtils;
import lombok.extern.slf4j.Slf4j;
import cn.ctg.video.entity.MUser;
import cn.ctg.video.service.MUserService;
import cn.ctg.video.constant.MUserConstant;/*** * @Description: 用戶Controller*/
@RestController
@RequestMapping("mUser")
@Slf4j
public class MUserController {@Autowiredprivate MUserService mUserService;@ApiOperation(value = "分頁查詢用戶列表", notes = "分頁查詢用戶列表")@PostMapping("pageList")public ResponseData<PageUtils> queryPage(@RequestBody Map<String, Object> param) {PageUtils pageUtils = mUserService.queryPage(param);return ResponseData.success(pageUtils);}/*** 查詢所有用戶列表* @param * @return*/@ApiOperation(value = "查詢所有用戶列表", notes = "查詢所有用戶列表")@PostMapping("searchAll")public ResponseData<List<MUser>> searchAll() {List<MUser> mUserList = mUserService.list();if(!CtgUtils.isCollectionNull(mUserList)) {return ResponseData.success(mUserList);}else {log.info(MUserConstant.NOT_EXIST);return ResponseData.success(mUserList);}}/*** 保存用戶* @param mUser* @return*/@ApiOperation(value = "保存用戶", notes = "保存用戶")@PostMapping("save")public ResponseData<String> save(@RequestBody MUser mUser) {boolean res = mUserService.save(mUser);if(res) {return ResponseData.success(MUserConstant.SAVE_SUCCESS);}else {log.error(MUserConstant.SAVE_FAILED);return ResponseData.error(MUserConstant.SAVE_FAILED);}}/*** 刪除用戶* @param mUser* @return*/@ApiOperation(value = "刪除用戶", notes = "刪除用戶")@PostMapping("delete")public ResponseData<String> delete(@RequestBody MUser mUser) {boolean res = mUserService.removeById(mUser);if(res) {return ResponseData.success(MUserConstant.DELETE_SUCCESS);}else {log.error(MUserConstant.DELETE_FAILED);return ResponseData.error(MUserConstant.DELETE_FAILED);}}/*** 根據主鍵ID更新用戶* @param mUser* @return*/@ApiOperation(value = "根據主鍵ID更新用戶", notes = "根據主鍵ID更新用戶")@PostMapping("update")public ResponseData<Boolean> update(@RequestBody MUser mUser) {boolean res = mUserService.updateById(mUser);if(res) {return ResponseData.success(true);}else {log.error(MUserConstant.UPDATE_FAILED);return ResponseData.error(MUserConstant.UPDATE_FAILED);}}/*** 批量刪除用戶* @param mUserList* @return*/@ApiOperation(value = "批量刪除用戶", notes = "批量刪除用戶")@PostMapping("deleteList")public ResponseData<String> deleteList(@RequestBody List<MUser> mUserList) {boolean res = mUserService.removeByIds(mUserList);if(res) {return ResponseData.success(MUserConstant.DELETE_SUCCESS);}else {log.error(MUserConstant.DELETE_FAILED);return ResponseData.error(MUserConstant.DELETE_FAILED);}}/*** 根據主鍵ID查找用戶*/@ApiOperation(value = "根據主鍵ID查找用戶", notes = "根據主鍵ID查找用戶")@PostMapping("searchById")public ResponseData<MUser> searchById (@RequestBody MUser mUser) {MUser mUserRes = mUserService.getById(mUser.getId());if (ObjectUtil.isNotEmpty(mUserRes)) {return ResponseData.success(mUserRes);}else {log.error(MUserConstant.QUERY_FAILED);return ResponseData.error(MUserConstant.QUERY_FAILED);}}}
三、復雜概念
一些復雜概念主要涉及
1、IOC和AOP
?什么是 IoCIoC (Inversion of control )控制反轉/反轉控制。
它是一種思想不是一個技術實現。描述的是:Java 開發領域對象的創建以及管理的問題。例如:現有類 A 依賴于類 B傳統的開發方式 :往往是在類 A 中手動通過 new 關鍵字來 new 一個 B 的對象出來使用 IoC 思想的開發方式 :不通過 new 關鍵字來創建對象,而是通過 IoC 容器(Spring 框架) 來幫助我們實例化對象。我們需要哪個對象,直接從 IoC 容器里面過去即可。從以上兩種開發方式的對比來看:我們 “喪失了一個權力” (創建、管理對象的權力),從而也得到了一個好處(不用再考慮對象的創建、管理等一系列的事情)
什么是 AOP
AOP:Aspect oriented programming 面向切面編程,AOP 是 OOP(面向對象編程)的一種延續。
2、過濾器,攔截器,事務,日志服務,定時器,任務調度等等
什么是過濾器與攔截器?
1.1過濾器(Filter)
java過濾器指的是在java中起到過濾的作用的一個方法。可以在一個請求到達servlet之前,將其截取進行邏輯判斷,然后決定是否放行到請求的servlet;也可以在一個response到達客戶端之前,截取結果進行邏輯判斷,然后決定是否允許返回給客戶端。
filter(過濾器)?有如下幾個種類(功能):
- 用戶授權的filter:filter負責判斷用戶是否有權限請求該頁面。
- 給予過濾判斷日志的filter:截取某個用戶在本網站上的所有請求。
- 記錄軌跡負責解碼的filter:規定處理本次請求的解碼方式。
需要注意的是,一個filter過濾器可以加在多個servlet控制器上,當然多個filter過濾器也是可以加在一個servlet控制器上的。
由此也是可以看出來,我們使用filter往往是對一些公共的操作進行處理。例如:判斷用戶權限,解碼本次請求等。還比如,我們的web應用中某些頁面是需要用戶登錄后才能訪問的,以往我們都是在每個servlet頁面加上判斷控制,導致代碼冗余。有了filter,我們可以定義一個實現了filter的過濾器,讓需要判斷是否登錄的頁面都加上這么一個過濾器,可以大大降低代碼的冗余程度
1.2攔截器(Interceptor)
java里的攔截器是動態攔截Action調用的對象,它提供了一種機制可以使開發者在一個Action執行的前后執行一段代碼,也可以在一個Action執行前阻止其執行,同時也提供了一種可以提取Action中可重用部分代碼的方式。
作用域:動態攔截Action調用的對象(也就是我們的controller層)
在實現上基于Java的反射機制,屬于面向切面編程(AOP)的一種運用,AOP可參考 Spring AOP速查筆記。 由于攔截器是基于web框架的調用,因此可以使用Spring的依賴注入(DI)進行一些業務操作,同時一個攔截器實例在一個controller生命周期之內可以多次調用。但是缺點是只能對controller請求進行攔截,對其他的一些比如直接訪問靜態資源的請求則沒辦法進行攔截處理。
過濾器與攔截器的區別
1.1 實現原理不同
- 過濾器的實現基于回調函數
- 攔截器基于Java的反射機制【動態代理】實現。
1.2 使用范圍不同
- 過濾器是Servlet的規范,需要實現javax.servlet.Filter接口,Filter使用需要依賴于Tomcat等容器。
- 攔截器是Spring組件,定義在org.springframework.web.servlet包下,由Spring容器管理【又有更加豐富的生繆那個周期處理方法,細粒度,且能夠使用Spring中的資源】,不依賴Tomcat等容器。
1.3 觸發時機不同
- 過濾器:對請求在進入后Servlet之前或之后進行處理。
- 攔截器:對請求在handler【Controller】前后進行處理。
1.4 執行順序不同
執行順序 :Filter 處理中 -> Interceptor 前置 -> 我是controller -> Interceptor 處理中 -> Interceptor 處理后
當有兩個過濾器或攔截器時:
過濾器:
每一次都將chain對象傳入,達到最后接口回調的效果,類似函數的堆棧調用。
攔截器:
preHandle1 -> preHande2 -> 【Controller】 -> postHandle2 -> postHandle1 -> afterCompletion2 -> afterComplention1
preHandle按照注冊順序,后兩個與注冊順序相反。
- 一個攔截器的preHandle為false,則之后的所有攔截器都不會執行。
- 一個攔截器的preHandle為true,則這個攔截器的triggerAfterCompletion一定會執行。
- 只有所有的攔截器preHandler都為true,也就是正常執行,postHandle才會執行。
1.5 控制執行順序方式不同
實際開發過程中,會出現多個過濾器或攔截器同時存在的情況,不過,有時我們希望某個過濾器或攔截器能優先執行,就涉及到它們的執行順序。
過濾器用@Order注解控制執行順序,通過@Order控制過濾器的級別,值越小級別越高越先執行。
3、與第三方的一些接口調用,比如支付,郵件,短信,驗證碼,加解密等等是必須掌握的功能。
四、特定功能
java開發系統中用戶的登錄注冊是最基本的特定功能。
登錄用戶表的設計
-- Drop table-- DROP TABLE public.t_user;CREATE TABLE public.t_user (id varchar(32) NOT NULL,user_name varchar(255) NOT NULL,login_name varchar(255) NOT NULL,password varchar(255) NOT NULL,create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,last_login_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,deleted int4 NOT NULL DEFAULT 0,pwd_val_time timestamp NOT NULL,belong_code varchar(8) NULL,belong_name varchar(255) NULL,data_type varchar(255) NULL,phone varchar(255) NULL,CONSTRAINT t_user_pkey PRIMARY KEY (id)
);