最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用springmvc的controller層獲取到請求的數(shù)據(jù)方式

 更新時間:2021年08月26日 10:50:08   作者:萬米高空  
這篇文章主要介紹了使用springmvc的controller層獲取到請求的數(shù)據(jù)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

javaweb應(yīng)用開發(fā),最常用到的就是應(yīng)用之間的信息交互,調(diào)用別的應(yīng)用模塊得到自己想獲取的數(shù)據(jù)信息,然后解析數(shù)據(jù)并進(jìn)行處理返回到上一層。那controller層的方法如何獲取http請求/webservice請求中的參數(shù),或者說請求數(shù)據(jù)呢?

按照我個人的接觸和理解,把請求可以分為兩大類:

1.頁面請求到后臺controller層的請求。

2.別的應(yīng)用http/webservice調(diào)用本應(yīng)用中封裝接口的請求。

無論哪種方式的請求,都是http請求(webservice底層也是http請求,待考證),controller層對請求數(shù)據(jù)的解析是按照json還是xml的依據(jù)就是請求頭content-type,接下來我們就先來詳細(xì)介紹一下。

content-type

content-type請求頭是干嗎的呢,http請求頭有四種類型,分別是通用頭部,請求頭部,響應(yīng)頭部以及內(nèi)容頭部. 首先,我們要弄清楚,content-type是屬于內(nèi)容頭部,既然是內(nèi)容頭部,那這個請求頭是用來向接收端解釋傳遞的該內(nèi)容主體的,content-type的取值是告訴服務(wù)端,你傳遞過去的內(nèi)容是啥,你應(yīng)該準(zhǔn)備好如何接收和解析。常用的content-type可以分為application/x-www-form-urlencoded , multipart/form-data ,application/json , text/xml四種。

下面一一介紹

1.application/x-www-form-urlencoded

application/x-www-form-urlencoded是常用的表單發(fā)包方式,普通的表單提交(即不帶文件上傳的提交),或者js (例如:post方式)發(fā)包,默認(rèn)都是通過這種方式,提交代碼demo如下:

function searchInfo() {
    $("#cxjg").datagrid({
        url : basepath + 'jijin/getList',
        queryParams : getParam($("#query").serializeArray()),
        method : "post"
    });
function searchInfo(){
    $("#cxjg").datagrid({
        url:basepath+'jijin/getList',
        queryParams : {'age':23,'name':'zhangsan'},
        method:"post"
});

請求頭信息如下所示,可以看到content-type和FormData(表單的數(shù)據(jù)格式)

這里寫圖片描述

如何獲取這種數(shù)據(jù)結(jié)構(gòu)的請求?有兩種方式來解決

1.1 String 參數(shù)值=reqeust.getParameter(“參數(shù)名”);

(以springmvc 的controller層的方法為例)

@RequestMapping("/getParam")
public String getParamFromRequest(HttpServletRequest request){
    String jiJinCode=(String)request.getParameter("jinJinCode");
    ...
}

1.2 Map<String,String[]> paramMap=request.getParameterMap();

@RequestMapping("/getParam")
public String getParamFromRequest(HttpServletRequest request){
    Map<String,String[]> paramMap=request.getParameterMap();
    StringBuffer inputDate=new StringBuffer();
    inputDate.append("<jiJinBean>");
    for(Map.Entry<String,String[]> entry :paramMap.entrySet()){
        String key=entry.getKey();
        String[] values=entry.getValue();
        String value=null;
        if(values.length>0){
            value=values[0];
        }
        inputDate.append("<"+key+">"+value+"</"+key+">");
    }
    return inputDate.toString();
}

兩種方法比較來說,第一種適合當(dāng)參數(shù)不多時,可以一個一個取。但第二種則是遍歷出所有的請求參數(shù),并生成標(biāo)簽格式,利于自動生成報文格式。

2.multipart/form-data

multipart/form-data用在頁面(提交)發(fā)送文件的POST請求。之所以會和第一種content-type同是post提交,為啥在這里就變成multipart/form-data了呢?

當(dāng)然程序不會自動識別是不是文件,而是我們在<form>這個標(biāo)簽里加上了這句話:

enctype="multipart/form-data",這才是讓請求頭發(fā)生變化的原因!具體代碼demo如下

$("#batchAddInfo").form('submit',{
                url:basepath+"jijin/fileUpload",
                onSubmit:function(){},
                success:function(data){
                    data=eval('('+data+')');
                    var flag=data.flag;
                    if(flag){
                        $("#batchDivDialog").window("close");
                        $.messager.alert('提示',"批量新增成功!");
                        searchInfo();
                    }else{
                        $("#batchDivDialog").window("close");
                        $.messager.alert('提示',"批量新增失敗!");
                        searchInfo();
                    }
                }
            });

對應(yīng)的谷歌頁面request調(diào)試信息如下:

這里寫圖片描述

這里Content-Type告訴我們,發(fā)包是以multipart/form-data格式來傳輸,另外,還有boundary用于分割數(shù)據(jù)。

這種方式的請求數(shù)據(jù)如何獲取?出文件外的表單參數(shù)值當(dāng)然還是和上面一樣——request.getParameter(“parameterName”)來獲取,不一樣的是文件怎么來獲?。恳玫組ultipartHttpServletRequest,這個MultipartHttpServletRequest 繼承于HttpServletRequest,MultipartRequest。

我們要從這個子類里面來獲取,具體代碼如下:

@RequestMapping("/fileUpload")
public  void fileUpload(HttpServletRequest request,HttpServletResponse response){
    InputStream is=null;
    //創(chuàng)建解析器
    CommonsMultipartResolver resolver=new CommonsMultipartResolver(request.getSession().getServletContext());
    //判斷request是否有文件上傳,即多部請求
    if(resolver.isMultipart(request)){
        MultipartHttpServletRequest multiRequest=(MultipartHttpServletRequest)request;
        //獲取多部request中的文件名
        Iterator<String> iter=multiRequest.getFileNames();
        while(iter.hasNext()){
            //取得上傳的文件
            MultipartFile file=multiRequest.getFile(iter.next());
            if(file!=null){
                is=new ByteArrayInputStream(file.getBytes());
            }
        }
    }
Workbook wb=new XSSFWorkbook(is);
...
}

3.text/xml

這種請求頭一般出現(xiàn)實在webservice請求時才會有。由于別的應(yīng)用請求我們,所以我們這邊就是服務(wù)端,他們是客戶端。這里無法用瀏覽器模擬,只能給出客戶端和服務(wù)端代碼,然后看如何解析客戶端的請求數(shù)據(jù)。

客戶端代碼

public class AxisClientTest {
    public static void main(String[] args) throws Exception {
  String nameSpaceURI = "com.serviceTargetName";
  String publishUrl = "http://localhost:8080/springCXFWebserviceDemo01/service/HelloWorldService?wsdl";
 Service service = new Service();
// 通過service創(chuàng)建call對象
 Call call = (Call) service.createCall();
 // 設(shè)置webservice接口地址
 call.setTargetEndpointAddress(new URL(publishUrl));
 call.setOperationName(new QName(nameSpaceURI, "sayHello"));
 call.addParameter("parameterName", XMLType.XSD_STRING, ParameterMode.IN);
call.setReturnType(XMLType.XSD_STRING);
  // 給方法傳遞參數(shù),并且調(diào)用方法
  String name = "zhanglifeng";
  String temp = getXml(name);
  // 這里的obj{}是放入幾個入?yún)ⅲ耆蓅ervice提供的接口方法的入?yún)Q定,且順序和你存放的順序一致!一般入?yún)镾tring類型的xml報文,回參也是xml報文。
  Object[] obj = new Object[] { temp };
  String result = (String) call.invoke(obj);
}
    private static String getXml(String name) {
        StringBuffer sb = new StringBuffer(
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        sb.append("<userBean>");
        sb.append("<userName>" + name + "</userName>");
        sb.append("</userBean>");
        return sb.toString();
    }
}

上面的方法getXml(String name)就是客戶端發(fā)給服務(wù)端的請求:

<?xml version="1.0" encoding="UTF-8"?>
    <userBean>
        <userName>" + 入?yún)ⅲ喝嗣?+ </userName>
    </userBean>

下面我們再看服務(wù)端,也就是我們這邊接受請求的代碼是啥樣的:

/**
 * 由于實現(xiàn)類和接口不在同一個包中。所以要加上targetNamespace屬性。
 * 另外,這里的endpointInterface是實現(xiàn)類對應(yīng)接口的全路徑
 * @author Administrator
 */
@WebService(targetNamespace="com.serviceTargetName",endpointInterface="com.zlf.HelloWorld")
@Component("HelloWord")//spring注入用
public class HelloWorldImpl implements HelloWorld {
    @Override
     public String sayHello(String str) {
        String username="aaa";
        Document document = XMLUtils.parse(str);
        //首先接口開發(fā)肯定是雙發(fā)都知道此方法要接受的報文格式的。我們獲取報文中人名對應(yīng)的節(jié)點即可。
          Node node = document.getElementsByTagName("userName").item(0);
          if(node !=null){
              username=node.getTextContent();
          }
        return "你好,"+username+"  你已成功訪問了webservice服務(wù)端!" ;
    }
}

這里我們是直接拿著入?yún)tr進(jìn)行Documen解析,因為客戶端的請求數(shù)據(jù)已經(jīng)綁定到這個入?yún)⑸狭恕S捎谖覀冎浪恼埱髨笪母袷绞莤ml的,所以可以進(jìn)行Document轉(zhuǎn)換,然后我們從節(jié)點中取值既可以實現(xiàn)請求數(shù)據(jù)的解析了。

解析的代碼請查看我以前的文章: 基于cxf和axis兩種框架下的webservice客戶端開發(fā)文的最后就是這個解析的工具類。

4.application/json

application/json 這個 Content-Type 作為響應(yīng)頭大家肯定不陌生。實際上,現(xiàn)在越來越多的人把它作為請求頭,用來告訴服務(wù)端消息主體是序列化后的 JSON 字符串。由于 JSON 規(guī)范的流行,除了低版本 IE 之外的各大瀏覽器都原生支持 JSON.stringify,服務(wù)端語言也都有處理 JSON 的函數(shù),使用 JSON 不會遇上什么麻煩。

JSON 格式支持比鍵值對復(fù)雜得多的結(jié)構(gòu)化數(shù)據(jù),這一點也很有用。

這個請求頭還有一個特殊點就是頁面通過jquery過來的數(shù)據(jù)結(jié)構(gòu)和其他應(yīng)用請求的數(shù)據(jù)結(jié)構(gòu)不一樣,因為jquery對json的數(shù)據(jù)做了轉(zhuǎn)換:

 "data":{
                "mobilenum":"15867426421",'age':23,'name':'zhangsan'
              }
         ——>mobilenum=15867426421&age=23&name=zhangsan

然而應(yīng)用沒有發(fā)生轉(zhuǎn)化,還是json結(jié)構(gòu)的數(shù)據(jù)。所以獲取上會有所不同。這里我們分成頁面和應(yīng)用兩種請求來分別說

4.1 頁面請求的數(shù)據(jù)獲取

4.1.1 頁面js請求如下

數(shù)據(jù)結(jié)構(gòu)為json,且data為var data={}的json類型時

$.ajax({
type: "post", 
data:{'mobilenum':'15867426421','age':'23','name':'zhangsan'},
contentType: "application/json; charset=utf-8",
url :basepath+'jijin/getList',
success: function(data){    
                   ... }
});

但是當(dāng)用瀏覽器來看是這樣的:

這里寫圖片描述

我們的數(shù)據(jù)結(jié)構(gòu)明顯發(fā)生了變化,由json變成了用&符號連接的普通傳值方式。所以這時候獲取參數(shù)值通過:String name=request.getParameter(“name”)這種來獲取。

4.1.2 如果頁面js請求如下

數(shù)據(jù)結(jié)構(gòu)為json,且data為var data=”“的String類型時,controller獲取數(shù)據(jù)則可以和下面的4.2一樣通過注解@RequestBody來綁定到入?yún)⑸稀?/p>

  $.ajax(
          {
              dataType: "json",
              type: "POST",
              data:"{'mobilenum':'15867426421','age':'23','name':'zhangsan'}",
              contentType: "application/json; charset=utf-8",
              url :basepath+'jijin/getList',
              success: function(data){    
              }
           });
    }

這時對應(yīng)的瀏覽器的請求頭信息如下:

這里寫圖片描述

可以看到串到后臺的數(shù)據(jù)結(jié)構(gòu)為json格式的數(shù)據(jù)結(jié)構(gòu),和4.1.1完全不同了。就是因為data的數(shù)據(jù)類型不同導(dǎo)致的,4.1.1的data是json類型,結(jié)果轉(zhuǎn)成普通的get方式拼接的參數(shù)結(jié)構(gòu),4.1.2的data是String類型,反而保持住了json類型的數(shù)據(jù)結(jié)構(gòu)。從而可以實現(xiàn)在controller層通過參數(shù)綁定來獲取請求參數(shù)。

4.1總結(jié)

通過上面兩個比較可以知道,頁面的jquery還是能夠識別json數(shù)據(jù)的,真是由于識別才導(dǎo)致數(shù)據(jù)轉(zhuǎn)換而。String類型的字符串沒有轉(zhuǎn)換的意義,而是直接傳給后臺,從而保證了數(shù)據(jù)結(jié)構(gòu)的不變。故:我們真想讓后臺接受json數(shù)據(jù)結(jié)構(gòu)的參數(shù)話,還是傳String類型的吧!

4.2 當(dāng)別的應(yīng)用調(diào)用我們的服務(wù)

發(fā)送json數(shù)據(jù)的請求時如何解析(springmvc controller層)?總的來說通過@RequestBody 注解方法的入?yún)ⅲ梢宰屨埱蟮膮?shù)綁定到該參數(shù)上,然后用Gson轉(zhuǎn)換成json即可獲得jsonObject/實體類(這里的UserBo),具體代碼如下

@RequestMapping("/url")
public void getUrlByPhone(@RequestBody String json,HttpServletRequest request){
    Gson gson=new Gson();
    UserBo ub=gson.fromJson(json,UserBo.class);
    //這里還可以通過jackson的ObjectMapper()把String json轉(zhuǎn)成JsonNode,然后用jsonNode.get(fieldName)來獲取各個json字段。例如:
    JsonNode node=new ObjectMapper().readTree(json);
    String name=node.get("name");
    ......
}

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringCloud使用Feign實現(xiàn)遠(yuǎn)程調(diào)用流程詳細(xì)介紹

    SpringCloud使用Feign實現(xiàn)遠(yuǎn)程調(diào)用流程詳細(xì)介紹

    OpenFeign源于Netflix的Feign,是http通信的客戶端。屏蔽了網(wǎng)絡(luò)通信的細(xì)節(jié),直接面向接口的方式開發(fā),讓開發(fā)者感知不到網(wǎng)絡(luò)通信細(xì)節(jié)。所有遠(yuǎn)程調(diào)用,都像調(diào)用本地方法一樣完成
    2023-02-02
  • 詳解Java多線程與并發(fā)

    詳解Java多線程與并發(fā)

    多線程是一個進(jìn)程在執(zhí)行過程中產(chǎn)生多個更小的程序單元,這些更小的單元稱為線程,這些線程可以同時存在,同時運(yùn)行,一個進(jìn)程可能包含多個同時執(zhí)行的線程。多線程是實現(xiàn)并發(fā)機(jī)制的一種有效手段。進(jìn)程和線程一樣,都是實現(xiàn)并發(fā)的一個基本單位。
    2021-06-06
  • SpringCloud?分布式微服務(wù)架構(gòu)操作步驟

    SpringCloud?分布式微服務(wù)架構(gòu)操作步驟

    SpringCloud是一種微服務(wù)的框架,利用它我們可以去做分布式服務(wù)開發(fā),這篇文章主要介紹了SpringCloud?分布式微服務(wù)架構(gòu),需要的朋友可以參考下
    2022-07-07
  • java實現(xiàn)圖片用Excel畫出來

    java實現(xiàn)圖片用Excel畫出來

    這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)圖片用Excel畫出來,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • SpringMVC 重定向參數(shù)RedirectAttributes實例

    SpringMVC 重定向參數(shù)RedirectAttributes實例

    這篇文章主要介紹了SpringMVC 重定向參數(shù)RedirectAttributes實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java數(shù)據(jù)結(jié)構(gòu)與算法之二分查找詳解

    Java數(shù)據(jù)結(jié)構(gòu)與算法之二分查找詳解

    這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)與算法之二分查找詳解,二分查找算法是一種在有序數(shù)組中查找某一特定元素的搜索算法,其思想就是不斷地將有序查找表“一分為二”,逐漸縮小搜索區(qū)域,進(jìn)而找到目標(biāo)元素,需要的朋友可以參考下
    2023-12-12
  • java數(shù)據(jù)庫連接池的特點及步驟

    java數(shù)據(jù)庫連接池的特點及步驟

    大家好,本篇文章主要講的是數(shù)據(jù)庫連接池的特點及步驟,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • spring學(xué)習(xí)教程之@ModelAttribute注解運(yùn)用詳解

    spring學(xué)習(xí)教程之@ModelAttribute注解運(yùn)用詳解

    這篇文章主要給大家介紹了關(guān)于spring學(xué)習(xí)教程之@ModelAttribute注釋運(yùn)用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-06-06
  • springboot將mybatis升級為mybatis-plus的實現(xiàn)

    springboot將mybatis升級為mybatis-plus的實現(xiàn)

    之前項目工程用的是mybatis,現(xiàn)在需要將其替換為mybatis-plus,本文主要介紹了springboot將mybatis升級為mybatis-plus的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2023-09-09
  • springboot打jar包之后下載文件的路徑問題

    springboot打jar包之后下載文件的路徑問題

    這篇文章主要介紹了springboot打jar包之后下載文件的路徑問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評論

新竹市| 玉田县| 淅川县| 遵义市| 拉萨市| 谷城县| 西宁市| 梅河口市| 炉霍县| 富阳市| 晴隆县| 诸城市| 徐水县| 古丈县| 广东省| 道孚县| 临泽县| 布尔津县| 阜新市| 专栏| 伊金霍洛旗| 苏州市| 丹棱县| 井研县| 新密市| 重庆市| 万盛区| 颍上县| 阿巴嘎旗| 吴江市| 万源市| 米泉市| 永仁县| 万宁市| 綦江县| 郑州市| 五家渠市| 丰台区| 云浮市| 克拉玛依市| 五指山市|