知識庫 / Spring RSS 訂閱

Spring 與 Jackson 的 JSON-P 支持

Data,Jackson,REST,Spring
HongKong
13
09:57 PM · Dec 05 ,2025

1. 概述

如果您在Web上進行過任何開發,您應該知道瀏覽器在處理AJAX請求時所遵循的同源策略。該策略的簡單概述是,來自不同域、協議或端口的任何請求都將被拒絕。

使用JSON填充(JSON-P)來緩解瀏覽器限制的一種方法是使用JSON-P。

本文討論了Spring對使用JSON-P數據(藉助AbstractJsonpResponseBodyAdvice)的支持。

2. JSON-P in Action

相同的源站策略並不會應用於<script>標籤,允許腳本在不同域之間加載。JSON-P 技術利用了這一點,通過將 JSON 響應作為 JavaScript 函數的參數傳遞。

2.1. 準備

在我們的示例中,我們將使用這個簡單的 Company 類:

public class Company {
 
    private long id;
    private String name;
 
    // standard setters and getters
}

此類將綁定請求參數,並從服務器端返回以 JSON 格式表示的結果。

控制器方法是一個簡單的實現——返回 Company 實例:

@RestController
public class CompanyController {

    @RequestMapping(value = "/companyRest",
      produces = MediaType.APPLICATION_JSON_VALUE)
    public Company getCompanyRest() {
        Company company = new Company(1, "Xpto");
        return company;
    }
}

在客户端,我們可以使用 jQuery 庫來創建併發送 AJAX 請求:

$.ajax({
    url: 'http://localhost:8080/spring-mvc-java/companyRest',
    data: {
        format: 'json'
    },
    type: 'GET',
    ...
});

考慮向以下 URL 發送一個 AJAX 請求:

http://localhost:8080/spring-mvc-java/companyRest

服務器返回的內容如下:

{"id":1,"name":"Xpto"}

由於請求針對相同的模式、域和端口發送,因此響應不會被阻止,瀏覽器將允許接收 JSON 數據。

2.2. 跨域請求

通過將請求 URL 更改為:

http://127.0.0.1:8080/spring-mvc-java/companyRest

請求將被瀏覽器阻止,因為請求是從 localhost127.0.0.1 發送的,這被認為是不同的域名,從而違反了同源策略。

使用 JSON-P,我們可以為請求添加一個回調參數:

http://127.1.1.1:8080/spring-mvc-java/companyRest?callback=getCompanyData

在客户端,只需將以下參數添加到 AJAX 請求中即可:

$.ajax({
    ...
    jsonpCallback:'getCompanyData',
    dataType: 'jsonp',
    ...
});

getCompanyData 將在收到響應時被調用的函數。

如果服務器以以下格式格式化響應:

getCompanyData({"id":1,"name":"Xpto"});

瀏覽器不會阻止它,因為它會將響應視為客户端和服務器之間協商並就匹配的 getCompanyData 在請求和響應中達成一致的腳本。

3. @ControllerAdvice 註解

標註了 @ControllerAdvice 註解的 Bean 能夠輔助所有或特定子集 Controller,並用於封裝不同 Controller 之間共享的橫切關注點。 典型的用法與異常處理、為模型添加屬性或註冊 Binder 相關。

從 Spring 4.1 開始@ControllerAdvice 能夠註冊 ResponseBodyAdvice 接口的實現,從而允許在控制器方法返回後,但在合適的轉換器寫入之前更改響應。

4. 通過使用 AbstractJsonpResponseBodyAdvice 修改響應

從 Spring 4.1 開始,我們現在可以訪問 AbstractJsonpResponseBodyAdvice 類——它根據 JSON-P 標準格式化響應。

本節將解釋如何讓該基類發揮作用,並在不修改現有控制器的情況下更改響應。

為了啓用 Spring 對 JSON-P 的支持,我們首先從配置開始:

@ControllerAdvice
public class JsonpControllerAdvice 
  extends AbstractJsonpResponseBodyAdvice {

    public JsonpControllerAdvice() {
        super("callback");
    }
}

支持是通過 AbstractJsonpResponseBodyAdvice 類實現的。在父類方法中傳遞的鍵將用於 JSON-P 數據請求的 URL。

通過此控制器建議,我們自動將響應轉換為 JSON-P 格式。

5. 使用 Spring 實現 JSON-P

在前面討論的配置已就位後,我們能夠使我們的 REST 應用程序返回 JSON-P 格式的數據。 在下面的示例中,我們將返回公司的相關數據,因此我們的 AJAX 請求 URL 應該類似於以下內容:

http://127.0.0.1:8080/spring-mvc-java/companyRest?callback=getCompanyData

由於之前的配置,響應將如下所示:

getCompanyData({"id":1,"name":"Xpto"});

正如我們討論的,這種格式的響應不會被阻止,即使它來自不同的域。

JsonpControllerAdvice 可以輕鬆應用於任何返回帶有 @ResponseBodyResponseEntity 註解的響應的方法。

應傳入同名的函數 getCompanyData 來處理所有響應。

6. 結論

本文介紹瞭如何利用 Spring 4.1 中的新功能,簡化了將響應格式化以利用 JSON-P 的過程。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.