<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java通過注解或攔截器實現(xiàn)出入?yún)Ⅰ劮迮c蛇式互轉(zhuǎn)

          共 18416字,需瀏覽 37分鐘

           ·

          2023-08-01 09:35



          一個努力中的公眾號

          長的好看的人都關(guān)注了


              Java語言遵循的開發(fā)規(guī)范為使用駝峰式命名,如columnA,然而數(shù)據(jù)庫表字段一般使用蛇式命名,如column_a,且前端一般也是使用數(shù)據(jù)庫的字段格式進行交互。因此參數(shù)傳遞和返回就需要對駝峰和蛇式的參數(shù)進行轉(zhuǎn)化。

          一:注解式

          最簡單的一種方式就是采用注解直接進行駝峰轉(zhuǎn)蛇形轉(zhuǎn)換????
          引入Maven依賴com.fasterxml.jackson.core??
          <dependency>    <groupId>com.fasterxml.jackson.core</groupId>    <artifactId>jackson-core</artifactId>    <version>2.11.2</version></dependency>
          在配置文件中聲明
          # application.propertiesspring.jackson.property-naming-strategy=SNAKE_CASE
          在實體類添加注解
          JsonInclude注解可以過濾為null的數(shù)據(jù)
          @Data@JsonInclude(JsonInclude.Include.NON_NULL)public class TestDTO implements Serializable {    private static final long serialVersionUID = 1L;
          private Integer id;
          private String userName;
          private Integer createTime;}

          上面注解就可以實現(xiàn)輸入與輸出都為蛇式,但是這種情況不能滿足自定義開關(guān),以及同時兼容駝峰與蛇式(因為第三方接口交互時有些要求采用駝峰,有的又要求蛇式)

          所以還有另外一種方式

          二:自定義攔截器統(tǒng)一處理??????????

          2.1 新建過濾器 
             
          替換過濾器內(nèi)request,防止參數(shù)丟失
          SpringBoot也是通過獲取request的輸入流來獲取參數(shù),如果不替換過濾
          器來到Controller請求參數(shù)就沒了,這是因為 InputStream read方法
          內(nèi)部有一個,postion,標志當前流讀取到的位置,每讀取一次,位置就
          會移動一次,如果讀到最后,InputStream.read方法會返回-1,標志已
          經(jīng)讀取完了,如果想再次讀取,可以調(diào)用inputstream.reset方法,
          position就會移動到上次調(diào)用mark的位置,mark默認是0,所以就能從頭
          再讀了。但是呢是否能reset又是由markSupported決定的,為true
          reset,為false就不能reset,從源碼可以看到,markSupported是為
          false的,而且一調(diào)用reset就是直接異常所以這也就代表,InpuStream
          只能被讀取一次,后面就讀取不到了。因此我們在過濾器的時候,已經(jīng)將
          InputStream讀取過了一次,當來到ControllerSpringBoot讀取
          InputStream的時候自然是什么都讀取不到了
          import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import java.io.IOException;
          /** * @Description: 重寫過濾器Filter * @Author: bigearchart * @CreateTime: 2023-02-22 * @Version: 1.0 */public class HttpServletRequestReplacedFilter implements Filter{
          @Override public void destroy() {
          }
          /** * @description: 替換過濾器內(nèi)request,防止參數(shù)丟失 * @author: bigearchart * @date: 2023/2/22 14:50 * @param: [request, response, chain] * @return: void **/ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { ServletRequest requestWrapper = null; if (request instanceof HttpServletRequest) { requestWrapper = new RequestReaderHttpServletRequestWrapper((HttpServletRequest) request); } //獲取請求中的流如何,將取出來的字符串,再次轉(zhuǎn)換成流,然后把它放入到新request對象中。 // 在chain.doFiler方法中傳遞新的request對象 if (requestWrapper == null) { chain.doFilter(request, response); } else { chain.doFilter(requestWrapper, response); } }
          @Override public void init(FilterConfig arg0) throws ServletException {
          }
          }


          2.2 新建請求攔截器
          request中獲取所有請求參數(shù)、根據(jù)需求將特定請求中參數(shù)進行將蛇形
          命名轉(zhuǎn)為駝峰
          import com.alibaba.fastjson.JSONArray;import com.alibaba.fastjson.JSONObject;import com.fz.common.util.JudgeUtils;import com.fz.common.util.sys.JsonObjectUtil;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Value;import javax.servlet.ReadListener;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import java.io.*;import java.nio.charset.Charset;
          /** * @Description: 獲取所有請求參數(shù)執(zhí)行蛇形轉(zhuǎn)駝峰 * @Author: bigearchart * @CreateTime: 2023-02-22 * @Version: 1.0 */@Slf4jpublic class RequestReaderHttpServletRequestWrapper extends HttpServletRequestWrapper { private String body = null;  @Value ("${open_camel}") private boolean openCamel;
          /** * @description: 從request中獲取所有請求參數(shù)將蛇形命名轉(zhuǎn)為駝峰 * @author: bigearchart * @date: 2023/2/22 14:47 * @param: [request] * @return: **/ public RequestReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException { super(request); JSONObject js = new JSONObject (); //獲取請求路徑 String url = request.getRequestURI(); //獲取請求ip String ip = JudgeUtils.getIpAddrByRequest (request); //獲取請求內(nèi)容 String bodyOld = getBodyStr(request); //如果開啟 蛇形命名轉(zhuǎn)駝峰-將請求內(nèi)容按要求轉(zhuǎn)換    if(openCamel && (url.contains ("third/") || url.contains ("api/third")|| url.contains ("web/api"))){ //如果請求是jsonObj try { JSONObject jsonObject = JSONObject.parseObject (bodyOld); //如果開啟 蛇形命名轉(zhuǎn)駝峰-將請求內(nèi)容按要求轉(zhuǎn)換 if(openCamel){ log.info ("================開啟蛇形命名轉(zhuǎn)駝峰"); jsonObject = JsonObjectUtil.humpConvertJSONObject (JSONObject.parseObject (bodyOld)); } if (jsonObject != null) { js = jsonObject; } //重構(gòu)入?yún)?/span> body = js.toJSONString(); //將ip塞入請求參數(shù)內(nèi) js.put("ip", ip); } catch (Exception e) { //否則為array log.info ("=======array=========開啟蛇形命名轉(zhuǎn)駝峰"); JSONArray jsonArray = JSONObject.parseArray (bodyOld); JSONArray valArray = new JSONArray (); JSONObject jsonObject ; //數(shù)組長度大于1才執(zhí)行轉(zhuǎn)換 if (jsonArray != null && jsonArray.size () > 0) { for(int i = 0;i < jsonArray.size(); i++){ valArray.set (i, JsonObjectUtil.humpConvertJSONObject (jsonArray.getJSONObject (i))); } //重構(gòu)入?yún)?/span> body = valArray.toJSONString(); }else{ body = bodyOld; } //將ip塞入請求參數(shù)內(nèi) js.put("ip", ip); } }else { body = bodyOld; } } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream bais = new ByteArrayInputStream(body.getBytes(Charset.forName("UTF-8"))); return new ServletInputStream() { @Override public int read() throws IOException { return bais.read(); } @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener readListener) { } }; } /** * 獲取post請求body參數(shù) * @param request HttpServletRequest * @return String */ public static String getBodyStr(HttpServletRequest request) { StringBuilder sb = new StringBuilder(); InputStream inputStream = null; BufferedReader reader = null; try { inputStream = request.getInputStream(); reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8"))); String line = ""; while ((line = reader.readLine()) != null) { sb.append(line); } } catch (IOException e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return sb.toString();  } }

          2.3 新建駝峰蛇式互轉(zhuǎn)工具類

          下劃線轉(zhuǎn)駝峰或者駝峰轉(zhuǎn)下劃線

          import com.alibaba.fastjson.JSONArray;import com.alibaba.fastjson.JSONObject;import java.util.*;import java.util.regex.Matcher;import java.util.regex.Pattern;
          /** * @Description: 駝峰轉(zhuǎn)換Util類 * @Author: bigearchart * @CreateTime: 2023-02-22 * @Version: 1.0 */public class JsonObjectUtil { private static Pattern humpPattern = Pattern.compile("[A-Z]"); /** * @param json 下劃線轉(zhuǎn)駝峰 * @Description 駝峰命名轉(zhuǎn)換 * @Throws * @Return com.alibaba.fastjson.JSONObject * @Date 2021-09-17 17:04:31 * @Author bigearchart **/ public static JSONObject humpConvertJSONObject (JSONObject json) { if (null == json) { return null; } //得到所有待處理的key Set<String> keys = json.keySet (); //key轉(zhuǎn)數(shù)組 String[] array = keys.toArray (new String[ 0 ]); //循環(huán)遍歷處理所有key for (String key : array) { //得到key Object value = json.get (key); //根據(jù)_分割為數(shù)組 String[] keyArray = key.toLowerCase ().split ("_"); //定義接收處理好格式的Obj HashMap<String, Object> objMap; //如果是數(shù)組 進行數(shù)組轉(zhuǎn)換 if(json.get (key) instanceof JSONArray){ JSONArray vArray = (JSONArray) json.get (key); //數(shù)組長度大于1才執(zhí)行轉(zhuǎn)換 if (keyArray.length > 0) { JSONArray newArray = new JSONArray(); for(int i = 0;i < vArray.size(); i++){ objMap = objToCamel(vArray.getJSONObject (i));// vArray.remove (i); newArray.set (i, objMap); value = newArray; } } }else if(json.get (key) instanceof JSONObject){ //否則執(zhí)行obj轉(zhuǎn)換 objMap = objToCamel(json.getJSONObject (key)); json.put (key, objMap); value = objMap; } //如果含有蛇形命名執(zhí)行轉(zhuǎn)換 if (isUpperCase (key) && ! key.contains ("_")) { json.remove (key); json.put (key.toLowerCase (), value); continue; } //如果含有多個蛇形命名執(zhí)行轉(zhuǎn)換 if (keyArray.length > 1) { StringBuilder sb = new StringBuilder (); for (int i = 0; i < keyArray.length; i++) { String ks = keyArray[ i ]; if (! "".equals (ks)){ if (i == 0) { sb.append (ks); } else { int c = ks.charAt (0); if (c >= 97 && c <= 122) { int v = c - 32; sb.append ((char) v); if (ks.length () > 1) { sb.append (ks.substring (1)); } } else { sb.append (ks); } } } } json.remove (key); json.put (sb.toString (), value); } } return json; } /** * @param objectList obj駝峰轉(zhuǎn)下劃線 * @Description 駝峰轉(zhuǎn)換 * @Throws * @Return java.util.List<com.alibaba.fastjson.JSONObject> * @Date 2021-09-17 17:09:15 * @Author bigearchart **/ public static List<JSONObject> humpConvertListObject (List<JSONObject> objectList) { if (null == objectList || objectList.size () <= 0) { return null; } List<JSONObject> data = new ArrayList<> (); for (JSONObject object : objectList) { data.add (humpConvertJSONObject (object)); } return data; } /** * @param array * @Description array駝峰轉(zhuǎn)下劃線 * @Throws * @Return java.util.List<com.alibaba.fastjson.JSONObject> * @Date 2021-09-17 17:13:22 * @Author bigearchart **/ public static List<JSONObject> humpConvertJSONArray (JSONArray array) { if (null == array || array.size () <= 0) { return null; } List<JSONObject> data = new ArrayList<> (); for (int i = 0; i < array.size (); i++) { data.add (humpConvertJSONObject (array.getJSONObject (i))); } return data; } /** * @param str * @Description 判斷字符串字母是否為大寫 * @Throws * @Return boolean * @Date 2021-09-17 17:03:50 * @Author bigearchart **/ public static boolean isUpperCase (String str) { for (int i = 0; i < str.length (); i++) { char c = str.charAt (i); if (c >= 97 && c <= 122) { return false; } } return true; } /** * @param json obj駝峰轉(zhuǎn)下劃線 * @Description 駝峰轉(zhuǎn)換 * @Throws * @Return java.util.List<com.alibaba.fastjson.JSONObject> * @Date 2021-09-17 17:09:15 * @Author bigearchart **/ public static JSONObject humpConvertJson (JSONObject json) { if (null == json || json.size () <= 0) { return null; } //得到所有待處理的key Set<String> keys = json.keySet (); //key轉(zhuǎn)數(shù)組 String[] array = keys.toArray (new String[ 0 ]); //循環(huán)遍歷處理所有key for (String key : array) {
          //根據(jù)_分割為數(shù)組 String[] keyArray = key.toLowerCase ().split ("_"); //定義接收處理好格式的Obj HashMap<String, Object> objMap; //如果是數(shù)組 進行數(shù)組轉(zhuǎn)換 if(json.get (key) instanceof JSONArray){ JSONArray vArray = (JSONArray) json.get (key); //數(shù)組長度大于1才執(zhí)行轉(zhuǎn)換 if (keyArray.length > 0) { for(int i = 0;i < vArray.size(); i++){ Set<Map.Entry<String, Object>> objEntry = vArray.getJSONObject (i).entrySet (); objMap = new HashMap<> (); for (Map.Entry<String, Object> entry : objEntry) { String oKey = entry.getKey (); Object oVal = entry.getValue (); objMap.put (humpToLine2 (oKey), oVal); } vArray.remove (i); vArray.set (i, objMap); } } }else{ //否則執(zhí)行obj轉(zhuǎn)換 Set<Map.Entry<String, Object>> objEntry = json.getJSONObject (key).entrySet (); objMap = new HashMap<> (); for (Map.Entry<String, Object> entry : objEntry) { String oKey = entry.getKey (); Object oVal = entry.getValue (); objMap.put (humpToLine2 (oKey), oVal); } json.put (key, objMap);
          } } return json; } /** * @description: 駝峰轉(zhuǎn)下劃線, * @author: bigearchart * @date: 2023/2/22 16:41 * @param: [str] * @return: java.lang.String **/ public static String humpToLine2(String str){ Matcher matcher = humpPattern.matcher (str); StringBuffer sb = new StringBuffer (); while (matcher.find ()) { matcher.appendReplacement (sb, "_" + matcher.group (0).toLowerCase ()); } matcher.appendTail (sb);      return sb.toString ();   } /** * 功能:下劃線命名轉(zhuǎn)駝峰命名 * 將下劃線替換為空格,將字符串根據(jù)空格分割成數(shù)組,再將每個單詞首字母大寫 * @param s * @return */ private static String under2camel(String s){ String separator = "_"; String under = ""; //判斷如果有蛇形命名才執(zhí)行 if (s.contains (separator)) { s = s.toLowerCase ().replace (separator, " "); String sarr[] = s.split (" "); for (int i = 0; i < sarr.length; i++) { if (i > 0) { String w = sarr[ i ].substring (0, 1).toUpperCase () + sarr[ i ].substring (1); under += w; } else { under = sarr[ i ]; } } } else { under = s; } return under; } /** * @description: obj蛇形轉(zhuǎn)駝峰 * @author: bigearchart * @date: 2023/2/22 14:23 * @param: [] * @return: java.util.HashMap<java.lang.String,java.lang.Object> **/ private static HashMap<String, Object> objToCamel(JSONObject obj) { Set<Map.Entry<String, Object>> objEntry = obj.entrySet(); HashMap<String, Object> objMap = new HashMap<> (); for (Map.Entry<String, Object> entry : objEntry) { String oKey = entry.getKey (); Object oVal = entry.getValue (); objMap.put (under2camel (oKey), oVal); } return objMap;  } }

          2.2 攔截器注入啟動類
          /**     * @description: 注冊過濾器到啟動類     * @author: bigearchart     * @date: 2023/2/22 14:54     * @param: []     * @return: org.springframework.boot.web.servlet.FilterRegistrationBean     **/    @Bean    public FilterRegistrationBean httpServletRequestReplacedRegistration() {        FilterRegistrationBean registration = new FilterRegistrationBean();        registration.setFilter(new HttpServletRequestReplacedFilter ());        registration.addUrlPatterns("/*");        registration.addInitParameter("paramName", "paramValue");        registration.setName("httpServletRequestReplacedFilter");        registration.setOrder(1);        return registration;    }


          至此實現(xiàn)參數(shù)駝峰與蛇式的兩種方式到此結(jié)束,通過接口測試工具調(diào)用即可驗證。????

          如果對您有幫助 請點個關(guān)注,萬分感謝

                                          (微信技術(shù)交流群 請加圖圖微信)


          瀏覽 131
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一级片在线| 国产成人HD | 欧美三级网站在线 | 色婷亚洲| 囯产精品久久久久久久久久久 |