字符編碼的處理和BeanUtils組件使用詳解
1、字符編碼問題解決方案
原理:過濾器技術(shù)攔截所有的controll的請求、在controll請求中使用了動態(tài)代理的設(shè)計(jì)模式監(jiān)聽了HttpServletRequest這個(gè)接口中g(shù)etParameter方法的執(zhí)行、在getParameter執(zhí)行的時(shí)候、我們首先去獲取這個(gè)數(shù)據(jù)、再通過判斷當(dāng)前的請求是GET還是POST、如果是GET那么先使用IOS-8859-1進(jìn)行轉(zhuǎn)碼 然后使用UTF-8從新進(jìn)行編碼、如果是POST那么直接使用request.setCharacterEncoding(“UTF-8”)來進(jìn)行處理
1.1、字符編碼處理的實(shí)現(xiàn)
public class CharacterFilter implements Filter{ @Override public void init(FilterConfig arg0) throws ServletException { } /** * 攔截的這個(gè)方法 */ @Override public void doFilter(ServletRequest request, ServletResponse response, final FilterChain chain) throws IOException, ServletException { final HttpServletRequest req=(HttpServletRequest) request; final HttpServletResponse resp=(HttpServletResponse) response; //第一步:將返回?cái)?shù)據(jù)的編碼問題給處理了 resp.setContentType("text/html;charset=utf-8"); //POST的解決方案 req.setCharacterEncoding("UTF-8"); //第二步:監(jiān)聽httpServletRequest中 getParameter方法的執(zhí)行 HttpServletRequest req1= (HttpServletRequest) Proxy.newProxyInstance(HttpServletRequest.class.getClassLoader(), new Class[]{HttpServletRequest.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //監(jiān)聽當(dāng)前執(zhí)行的方法是不是 getParameter String methodName=method.getName(); if("getParameter".equals(methodName)){ //說明執(zhí)行的是getParameter //判斷當(dāng)前執(zhí)行的是POST呢?還是GET呢? String reqName=req.getMethod(); //通過key獲取這個(gè)值 String val= (String) method.invoke(req, args); if("GET".equalsIgnoreCase(reqName)){ //說明是GET方法 //執(zhí)行這個(gè)方法獲取這個(gè)值 val=new String(val.getBytes("ISO-8859-1"),"UTF-8"); }else if("POST".equalsIgnoreCase(reqName)){ //說明是POST方法 } //返回這個(gè)方法執(zhí)行的結(jié)果 return val; }else{ return method.invoke(req, args); } } }); //最終要進(jìn)行放行 chain.doFilter(req1, resp); } @Override public void destroy() { } }
2、字符和諧的問題
明白一個(gè)問題:什么是字符和諧:類似于博客網(wǎng)站上行 比如你罵人了一句話這句話并不會直接顯示出來、而是顯示成****等這種現(xiàn)象就稱為字符的和諧
要實(shí)現(xiàn)字符和諧首先要解決編碼問題(上面已經(jīng)解決了)
在過濾器中設(shè)置臟數(shù)據(jù)
//需要和諧的臟數(shù)據(jù) private String[] dirtyData={"MMD","NND","殺人","CTM"};
在處理完字符編碼問題的時(shí)候進(jìn)行和諧(在處理完編碼之后進(jìn)行調(diào)用)
protected String handleDirtyData(String val) { for (int i = 0; i < dirtyData.length; i++) { if(val.contains(dirtyData[i])){ val=val.replaceAll(dirtyData[i],"***"); } } return val; }
3、BeanUtils組件的使用
Beanutils組件是啥?
Beanutils不是一個(gè)框架、就相當(dāng)于是一個(gè)幫助類、這個(gè)幫助類的作用就是專門用來操作我們java Bean
BeanUtils組件能干啥?
能夠?qū)⒁粋€(gè)實(shí)體的值賦值給另外一個(gè)實(shí)體、也可以將map類型的值賦值給實(shí)體、也可以將實(shí)體進(jìn)行拷貝
BeanUtils組件的使用?
導(dǎo)入beanUtils的包
使用BeanUtils組件的API
public void testbeanUtils() throws Exception { User user=new User(1,"小波波","123"); //使用BeanUtils來操作這個(gè)是實(shí)體 //API:表示的是給那個(gè)對象的那個(gè)屬性設(shè)置什么值 //BeanUtils.setProperty(user,"uName","小波波"); //BeanUtils.copyProperty(user,"uPwd","123"); //API:拷貝一個(gè)實(shí)體 返回值就是copy生成的新的實(shí)體 //User user2=(User) BeanUtils.cloneBean(user); User user2=new User(); //把一個(gè)實(shí)體里面的屬性copy給另外一個(gè)實(shí)體的屬性 //BeanUtils.copyProperties(user2, user); //將實(shí)體轉(zhuǎn)換成map //Map<Object,Object> maps=BeanUtils.describe(user); //獲取實(shí)體的屬性值 并轉(zhuǎn)換成String類型的數(shù)組 //String[] strVal=BeanUtils.getArrayProperty(user,"uName"); //將Map中的數(shù)據(jù)直接賦值給JAVA的對象 Map<String,Object> maps=new HashMap<String, Object>(); maps.put("uId",123); maps.put("uName","小波波"); maps.put("uPwd","110"); //將map中的數(shù)據(jù)直接賦值給JAVA對象 BeanUtils.populate(user2, maps); System.out.println(user2); }
4、Servlet請求參數(shù)的自動封裝
public static<T> T getObject(HttpServletRequest request,Class clazz) throws Exception{ //反射得到這個(gè)數(shù)據(jù)類型 T t=(T) clazz.newInstance(); //使用beanUtils組件來設(shè)置這個(gè)值 BeanUtils.populate(t,request.getParameterMap()); return t; }
5、源數(shù)據(jù)使用
源數(shù)據(jù)分類:數(shù)據(jù)庫的源數(shù)據(jù) 、請求參數(shù)的元數(shù)據(jù)、結(jié)果集的元數(shù)據(jù)
數(shù)據(jù)庫的元數(shù)據(jù):能夠獲取當(dāng)前訪問數(shù)據(jù)庫的一些信息(數(shù)據(jù)庫的名字、連接的URL、連接的用戶名、數(shù)據(jù)庫的版本信息)
請求參數(shù)的元數(shù)據(jù):能夠精確的知道當(dāng)前的SQL語句中有多少個(gè)占位符
結(jié)果集元數(shù)據(jù):就能清楚的知道當(dāng)前訪問的這個(gè)數(shù)據(jù)庫的列名是什么
5.1、數(shù)據(jù)庫的元數(shù)據(jù)的使用
public void testDatabaseMetaData() throws Exception { //第一步:加載驅(qū)動 Class.forName("com.mysql.jdbc.Driver"); //第二步:創(chuàng)建連接 Connection conn= DriverManager.getConnection(URL, USER, PASSWORD); //獲取數(shù)據(jù)庫的元數(shù)據(jù) DatabaseMetaData data=conn.getMetaData(); //獲取數(shù)據(jù)庫的相關(guān)信息 System.out.println("數(shù)據(jù)庫的名字:"+data.getDatabaseProductName()); System.out.println("數(shù)據(jù)庫的版本:"+data.getDatabaseProductVersion()); System.out.println("數(shù)據(jù)庫的URL:"+data.getURL()); System.out.println("訪問的用戶名:"+data.getUserName()); System.out.println("---------------------------------------"); //第三步:創(chuàng)建操作數(shù)據(jù)庫的對象 PreparedStatement state=conn.prepareStatement("select * from msgstateinfo"); //第四步:操作 ResultSet set=state.executeQuery(); //遍歷.... while (set.next()) { String str=set.getString("msgstate"); System.out.println("獲取到的數(shù)據(jù)是:"+str); } conn.close(); }
5.2、請求參數(shù)的元數(shù)據(jù)
public void testRequestParameMetaData() throws Exception { //第一步:加載驅(qū)動 Class.forName("com.mysql.jdbc.Driver"); //第二步:創(chuàng)建連接 Connection conn= DriverManager.getConnection(URL, USER, PASSWORD); System.out.println("---------------------------------------"); //第三步:創(chuàng)建操作數(shù)據(jù)庫的對象 PreparedStatement state=conn.prepareStatement("select * from msgstateinfo where id < ? and msgobj = ? and aa=?"); //第四步:玩下請求參數(shù)的元數(shù)據(jù) ParameterMetaData data=state.getParameterMetaData(); //現(xiàn)在你就可以知道當(dāng)前的SQL語句中有多少個(gè)占位符了 System.out.println("占位符的個(gè)數(shù):"+data.getParameterCount()); conn.close(); }
5.3、結(jié)果集元數(shù)據(jù)
public void testResultSetMetaData() throws Exception { //第一步:加載驅(qū)動 Class.forName("com.mysql.jdbc.Driver"); //第二步:創(chuàng)建連接 Connection conn= DriverManager.getConnection(URL, USER, PASSWORD); System.out.println("---------------------------------------"); //第三步:創(chuàng)建操作數(shù)據(jù)庫的對象 PreparedStatement state=conn.prepareStatement("select * from t_user"); ResultSet set=state.executeQuery(); //下面就可以獲取結(jié)果集的元數(shù)據(jù)了 ResultSetMetaData resultSetMetaData=set.getMetaData(); while (set.next()) { //相當(dāng)于是遍歷的是行 //我們還可以遍歷列 int columnNum=resultSetMetaData.getColumnCount(); //通過列的下標(biāo)來知道列的名字 for (int i = 0; i < columnNum; i++) { //通過列的下標(biāo)來找到列的名字 String columnName=resultSetMetaData.getColumnName(i+1); //知道了列的名字也就能找到這個(gè)列的值了 Object val=set.getObject(columnName); System.out.println(val); } } conn.close(); }
5.4、封裝一個(gè)通用的JDBC的增刪改的方法
public void update(String sql, Object... parames) throws Exception { // 獲取連接 Connection conn = getConnection(); // 第二步:獲取操作數(shù)據(jù)庫的對象 PreparedStatement state = conn.prepareStatement(sql); // 第三步:將傳遞過來的參數(shù)直接賦值給占位符 // 獲取占位符的個(gè)數(shù) ParameterMetaData parameterMetaData = state.getParameterMetaData(); // 獲取占位符的個(gè)數(shù) int num = parameterMetaData.getParameterCount(); if (parames.length < num) { throw new RuntimeException("參數(shù)不對應(yīng)沒法玩...."); } // 說明參數(shù)是對的 for (int i = 0; i < num; i++) { // 設(shè)置參數(shù)了 state.setObject(i + 1, parames[i]); } // 執(zhí)行這個(gè)SQL語句 state.executeUpdate(); close(); }
5.5、封裝一個(gè)根據(jù)條件查詢返回集合的方法
public <T> List<T> findAll(String sql, Class<T> clazz,Object...parames) throws Exception { //確定返回的這個(gè)容器 List<T> lists=new ArrayList<T>(); // 獲取連接 Connection conn = getConnection(); // 第二步:獲取操作數(shù)據(jù)庫的對象 PreparedStatement state = conn.prepareStatement(sql); // 第三步:將傳遞過來的參數(shù)直接賦值給占位符 // 獲取占位符的個(gè)數(shù) ParameterMetaData parameterMetaData = state.getParameterMetaData(); // 獲取占位符的個(gè)數(shù) int num = parameterMetaData.getParameterCount(); if (parames.length < num) { throw new RuntimeException("參數(shù)不對應(yīng)沒法玩...."); } //判斷:假設(shè)這個(gè)SQL語句根本就沒有占位符呢? if(num!=0){ //說明有占位符 // 說明參數(shù)是對的 for (int i = 0; i < num; i++) { // 設(shè)置參數(shù)了 state.setObject(i + 1, parames[i]); } } // 執(zhí)行這個(gè)SQL語句 ResultSet set=state.executeQuery(); //下面移動游標(biāo)遍歷這個(gè)行 //獲取這個(gè)列的數(shù)量 ResultSetMetaData metadata=set.getMetaData(); //可以獲取這個(gè)列的數(shù)量 int columnCount=metadata.getColumnCount(); while (set.next()) { T t=clazz.newInstance(); //遍歷每一個(gè)列 for (int i = 0; i <columnCount; i++) { //獲取每一個(gè)列的列名 String columnName=metadata.getColumnName(i+1); //獲取這個(gè)列的值 Object columnVal= set.getObject(columnName); //把上面的屬性和值 放到這個(gè)JAVA對象中去 BeanUtils.copyProperty(t, columnName, columnVal); } //將t放到List集合中去 lists.add(t); } close(); return lists; } ```
以上就是字符編碼的處理和BeanUtils組件的使用的詳細(xì)內(nèi)容,更多關(guān)于字符編碼處理BeanUtils組件的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于SpringMVC接受JSON參數(shù)詳解及常見錯(cuò)誤總結(jié)
下面小編就為大家分享一篇基于SpringMVC接受JSON參數(shù)詳解及常見錯(cuò)誤總結(jié),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03解決mybatis-plus自動配置的mapper.xml與java接口映射問題
這篇文章主要介紹了解決mybatis-plus自動配置的mapper.xml與java接口映射問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08Java中Final關(guān)鍵字的使用技巧及其性能優(yōu)勢詳解
這篇文章主要介紹了Java中Final關(guān)鍵字的使用技巧及其性能優(yōu)勢詳解,Java中的final關(guān)鍵字用于修飾變量、方法和類,可以讓它們在定義后不可更改,從而提高程序的穩(wěn)定性和可靠性,此外,final關(guān)鍵字還有一些使用技巧和性能優(yōu)勢,需要的朋友可以參考下2023-10-10java策略枚舉:消除在項(xiàng)目里大批量使用if-else的優(yōu)雅姿勢
這篇文章主要給大家介紹了關(guān)于Java徹底消滅if-else的8種方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2021-06-06詳解SpringBoot開發(fā)使用@ImportResource注解影響攔截器
這篇文章主要介紹了詳解SpringBoot開發(fā)使用@ImportResource注解影響攔截器,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-11-11Java簡單數(shù)據(jù)加密方法DES實(shí)現(xiàn)過程解析
這篇文章主要介紹了Java簡單數(shù)據(jù)加密方法DES實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12Java Kafka 消費(fèi)積壓監(jiān)控的示例代碼
這篇文章主要介紹了Java Kafka 消費(fèi)積壓監(jiān)控,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-07-07