SpringMVC—對Ajax的處理(含 JSON 類型)(1)

來源:互聯網
上載者:User

標籤:分享   cep   foo   工具類   訊息   etag   低版本   tar   ati   

一、首先要搞明白的一些事情。1.從用戶端來看,需要搞明白:(1)要發送什麼樣格式的 JSON 資料才能被伺服器端的 SpringMVC 很便捷的處理,怎麼才能讓我們寫更少的代碼,如何做好 JSON 資料和實體之間的對應。(2)如何組織這些發送的資料。2.從伺服器端來看,需要搞明白:(1)SpringMVC 如何返回 JSON 資料。(2)SpringMVC 如何處理請求的複雜資料。3.$.ajax 的幾個參數:(1)contentType:contentType: ‘application/json;charset=utf-8‘,作為要求標頭,用來告訴伺服器訊息的主體是序列化後的 JSON 字串。除了低版本的 ie 瀏覽器外,各大瀏覽器都原生支援 JSON.stringify() 對對象進行序列化。(2)dataType:預期伺服器返回的資料類型。4.SpringMVC 是如何處理 JSON 資料的5.總體的思想:(1)SpringMVC 能完成的,盡量藉助於 SpringMVC,而不是我們手動的去解析。(2)SpringMVC 解析不了的,盡量藉助於第三方的 Jar 包來解析。(3)SpringMVC 和 第三方 Jar 包解決不了的時候,我們再自己去解析。 二、想要搞明白第一個問題,前提是先要搞明白第一個問題:SpringMVC 是如何處理 JSON 資料的。1.使用 HttpMessageConverter<T> 來處理  JSON 資料的。Spring 的 HttpMessageConverter<T> 負責將請求資訊轉換為一個對象,將對象輸出為響應資訊。2.API(1)boolean canRead(Class<?> clazz, MediaType mediaType);轉換器是否可將請求資訊轉換為 clazz 類型的對象,同時支援指定的 MIME 類型,如: text/html,application/json 等。(2)boolean canWrite(Class<?> clazz, MediaType mediaType);轉換器是否可以將 clazz 類型的對象寫到響應中,響應支援的類型在 mediaType 中定義。(3)List<MediaType> getSupportedMediaTypes();改轉換器支援的 MediaType 類型。(4)T read(Class<? extends T> clazz, HttpInputMessage inputMessage);將請求資訊流轉換為 clazz 類型的對象。(5)void write(T t, MediaType contentType, HttpOutputMessage outputMessage)。將 T 類型的對象寫到響應輸出資料流中,同時指定 MediaType。

  3.實作類別

Spring 預設支援使用 Jackson來處理 JSON 問題。

匯入的 Jackson Jar 包:

 

 

4.具體的處理方法:(1)使用 @RequestBody 和 HttpEntity<T> 對請求進行處理。(2)使用 @ResponseBody 和 ResponseEntity<T> 對響應進行處理。(3)@RequestBody 對處理方法的入參進行標註。(4)@ResponseBody 對處理方法的簽名進行標註。(5)HttpEntity<T> 和 ResponseEntity<T> 作為處理方法的入參使用。具體的使用方法會在下面例子中進行說明。[email protected] 和 @ResponseBody 是可以同時使用的。 三、上面簡單介紹了 SpringMVC 是怎麼處理 JSON 資料的,現在來看第二個問題:發送什麼樣格式的 JSON 資料才能被伺服器端的 SpringMVC 很便捷的處理,這裡主要指的是請求的 JSON 字串和實體的映射。以一個簡單的實體為例:Person Person.java/** * @author solverpeng * @create 2016-08-12-10:50 */public class Person {    private String name;    private Integer age;    public Person() {    }    public Person(String name, Integer age) {        this.name = name;        this.age = age;    }    @NotBlank(message = "人名不可為空")    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    @Override    public String toString() {        return "Person{" +                "name=‘" + name + ‘\‘‘ +                ", age=" + age +                ‘}‘;    }}(1)對於簡單的一個Person 對象來說,我們甚至都不需要藉助於 JSON 就可以完成請求的資料與實體之間的映射。請求:$("#testJson").click(function () {    $.ajax({        url: "testJson",        type: "post",        data: {            name : "abc",            age : "23"        },        success: function (result) {            console.log(result);        }    });});handler 方法:@RequestMapping("/testJson")public Person testJson(Person person) {    System.out.println("person:" + person);    return person;}(2)對於Person數組來說,需要發送什麼樣的格式才能被 SpringMVC 直接處理?請求:$("#testJson6").click(function () {    $.ajax({        url: "testJson6",        type: "post",        data:‘[{ "name": "Brett", "age":"12" }, { "name": "Jason", "age":"23" }, { "name": "Elliotte", "age":"33" }]‘,        contentType: "application/json; charset=utf-8",        success: function (result) {            console.log(result);        }    });});handler 方法:@RequestMapping("/testJson6")public String testJson6(@RequestBody List<Person> persons) {    System.out.println("persons:" + persons);    return "success";}注意:(1)需要指定 "contentType",同時需要注意的是:發送的請求資料不在 Form data 中,而是在 Request Payload 中。關於 [Request Payload] ,在後面說明。(2)必須要指定 @RequestBody ,否則無法解析。 四、第三個問題:如何組織這些資料以及SpringMVC 如何處理這些資料,做好映射。(1)說明:上面說的兩個例子,僅僅是最簡單的一種形式。現在對其進行擴充,在四裡,所說的 SpringMVC 如何處理這些資料,不僅僅指的是SpringMVC,也包括SpringMVC處理不了,使用第三方來處理,或者第三方處理不了,我自己來處理。同時這裡的資料也不僅僅指的 JSON 類型的資料。(2)對於非表單的 Ajax 提交,這裡只提供比較簡單的一種方式。還是以上面的 Person 為例。e1:資料的組織與請求的發送:var personList = [];personList.push({name: "李四",age: "23"});personList.push({name: "張三",age: "12"});$("#testJson5").click(function () {    $.ajax({        type: "POST",        url: "testJson5",        data: JSON.stringify(personList),//將對象序列化成JSON字串        contentType: ‘application/json;charset=utf-8‘, //佈建要求頭資訊        success: function (data) {        },        error: function (res) {        }    });});handler 方法:@RequestMapping("/testJson5")public String testJson5(@RequestBody List<Person> persons) {    System.out.println(persons);    return "success";}(3)基於表單的 Ajax 提交。提供一個序列化方法:$.fn.serializeObject = function(){    var o = {};    var a = this.serializeArray();    $.each(a, function() {        if (o[this.name] !== undefined) {            if (!o[this.name].push) {                o[this.name] = [o[this.name]];            }            o[this.name].push(this.value || ‘‘);        } else {            o[this.name] = this.value || ‘‘;        }    });    return o;};還有一種序列化方式:★單表單情況:表單:<form action="" method="post">    First Name:<input type="text" name="firstName" maxlength="12" size="12"/> <br/>    Last Name:<input type="text" name="lastName" maxlength="36" size="12"/> <br/>    Gender:<br/>    Male:<input type="radio" name="gender" value="1"/><br/>    Female:<input type="radio" name="gender" value="0"/><br/>    Favorite Food:<br/>    Steak:<input type="checkbox" name="foods" value="Steak"/><br/>    Pizza:<input type="checkbox" name="foods" value="Pizza"/><br/>    Chicken:<input type="checkbox" name="foods" value="Chicken"/><br/>    <textarea wrap="physical" cols="20" name="quote" rows="5">Enter your favorite quote!</textarea><br/>    Select a Level of Education:<br/>    <select name="education">        <option value="Jr.High">Jr.High</option>        <option value="HighSchool">HighSchool</option>        <option value="College">College</option>    </select><br/>    Select your favorite time of day:<br/>    <select size="3" name="tOfD">        <option value="Morning">Morning</option>        <option value="Day">Day</option>        <option value="Night">Night</option>    </select>    <p><input type="submit"/></p></form>對應的實體: Student.java/** * @author solverpeng * @create 2016-08-16-11:14 */public class Student {    private String firstName;    private String lastName;    private Integer gender;    private List<String> foods;    private String quote;    private String education;    private String tOfD;    public String getFirstName() {        return firstName;    }    public void setFirstName(String firstName) {        this.firstName = firstName;    }    public String getLastName() {        return lastName;    }    public void setLastName(String lastName) {        this.lastName = lastName;    }    public Integer getGender() {        return gender;    }    public void setGender(Integer gender) {        this.gender = gender;    }    public List<String> getFoods() {        return foods;    }    public void setFoods(List<String> foods) {        this.foods = foods;    }    public String getQuote() {        return quote;    }    public void setQuote(String quote) {        this.quote = quote;    }    public String getEducation() {        return education;    }    public void setEducation(String education) {        this.education = education;    }    public String gettOfD() {        return tOfD;    }    public void settOfD(String tOfD) {        this.tOfD = tOfD;    }    @Override    public String toString() {        return "Student{" +                "firstName=‘" + firstName + ‘\‘‘ +                ", lastName=‘" + lastName + ‘\‘‘ +                ", gender=" + gender +                ", foods=" + foods +                ", quote=‘" + quote + ‘\‘‘ +                ", education=‘" + education + ‘\‘‘ +                ", tOfD=‘" + tOfD + ‘\‘‘ +                ‘}‘;    }}e1:使用 serializeObject()序列化後的值:JSON.stringify($(‘form‘).serializeObject()):{"firstName":"jack","lastName":"lily","gender":"1","foods":["Pizza","Chicken"],"quote":"hello hello","education":"Jr.High","tOfD":"Day"}請求:$(function() {    $(‘form‘).submit(function() {        $.ajax({            url : "testStudent",            data : JSON.stringify($(‘form‘).serializeObject()),            contentType : "application/json;charset=utf-8",            type : "post",            success : function (result) {                console.log(result);            }        });        return false;    });});e11:SpringMVC自身進行處理handler 方法:@RequestMapping("/testStudent")public String testStudent(@RequestBody Student student) {    System.out.println(student);    return "success";}e12:引入第三方 Jar 包進行處理。準備:匯入 sl4j jar 包,同時添加 JsonUtil 工具類。 JsonUtil.javapublic final class JsonUtil {    private static final Logger LOGGER = LoggerFactory.getLogger(JsonUtil.class);    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();    /**     * 將 POJO 轉換為 JSON     */    public static <T> String toJson(T obj) {        String json;        try {            json = OBJECT_MAPPER.writeValueAsString(obj);        } catch(JsonProcessingException e) {            LOGGER.error("convert POJO to JSON failure", e);            throw new RuntimeException(e);        }        return json;    }    /**     * 將 JSON 轉換為 POJO     */    public static <T> T fromJson(String json, Class<T> type) {        T pojo;        try {            pojo = OBJECT_MAPPER.readValue(json, type);        } catch(IOException e) {            LOGGER.error("convert JSON to POJO failure", e);            throw new RuntimeException(e);        }        return pojo;    }}後端處理:@RequestMapping("/testStudent")public String testStudent(@RequestBody String inputBody) {    Student student = JsonUtil.fromJson(inputBody, Student.class);    System.out.println(student);    return "success";}都可以正常列印 Student 對象。e2:使用 serialize()序列化後的值:$(‘form‘).serialize():firstName=jack&lastName=lily&gender=1&foods=Pizza&foods=Chicken&quote=hello+hello&education=Jr.High&tOfD=Day請求:$(function() {    $(‘form‘).submit(function() {        $.ajax({            url : "testStudent",            data : $(‘form‘).serialize(),            type : "post",            success : function (result) {                console.log(result);            }        });        return false;    });});handler 方法:@RequestMapping("/testStudent")public String testStudent(Student student) {    System.out.println(student);    return "success";}可以正常列印 Student 對象。e1 和 e2 對比說明:e1提交的 JSON 資料,e2 提交的不是 JSON 格式的資料。e1 的請求參數存放在 [Request Payload] 中,而 e2 的請求參數存放在 Form Data 中。★單表單複雜資料表單還是上面的 Student 表單,但是在表單外增加了:<span id="amount">33</span>需求是:通過 Ajax 發送表單資料的同時,同時發送 "amount" 。經過測試,就直接說結論了。結論:不能對這樣的資料,指定 "contentType:application/json",否則後端SpringMVC或者第三方的Jar 包 不能進行自動的解析,增加瞭解析的複雜度,所以將 json 串傳入後台,在後台進行解析。e1:serializeObject()請求:$(function() {    $(‘form‘).submit(function() {        $.ajax({            url : "testStudent",            data : {                amount : $("#amount").text(),                student : JSON.stringify($(‘form‘).serializeObject())            },            type : "post",            success : function (result) {                console.log(result);            }        });        return false;    });});後端處理:使用第三方工具類進行解析@RequestMapping("/testStudent")public String testStudent(@RequestParam("student") String studentStr, String amount) {    Student student = JsonUtil.fromJson(studentStr, Student.class);    System.out.println("student:" + student);    System.out.println("amount:" + amount);    return "success";}可以正常列印。e2:serialize()請求:$(function() {    $(‘form‘).submit(function() {        $.ajax({            url : "testStudent",            data : {                amount : $("#amount").text(),                student : $(‘form‘).serialize()            },            type : "post",            success : function (result) {                console.log(result);            }        });        return false;    });});Handler 方法:e1:嘗試讓 SpringMVC 來解析:@RequestMapping("/testStudent")public String testStudent(@RequestParam("student") Student student, String amount) {    System.out.println("student:" + student);    System.out.println("amount:" + amount);    return "success";}結果:請求無法到達 handler 方法e2:@RequestMapping("/testStudent")public String testStudent(Student student, String amount) {    System.out.println("student:" + student);    System.out.println("amount:" + amount);    return "success";}結果:請求可以正常到達目標 Handler 方法,但是無法映射 Student 對象。方案:自己解析,編寫自訂的類型轉換器:public class String2StudentConverter implements Converter<String, Student>{    @Override    public Student convert(String source) {        return InjectUtil.convert2Obj(source, Student.class);    }}

  

SpringMVC—對Ajax的處理(含 JSON 類型)(1)

相關文章

Alibaba Cloud 10 Year Anniversary

With You, We are Shaping a Digital World, 2009-2019

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。