RestTemplate Module|休息模板模块

2023-01-03 16:23:18 来源:51CTO博客

2.1 引言

Spring 的 RestTemplate 是一个健壮的、流行的基于 Java 的 REST 客户端。Spring for Android RestTemplate Module 提供了一个在 Android 环境中工作的 RestTemplate 版本。

2.2 概述

该类是 Spring for Android RestTemplate 库的核心。它在概念上类似于其他 Spring 项目组合项目中的其他模板类。RestTemplate 的行为是通过提供回调方法和配置用于将对象封送到 HTTP 请求正文中以及将任何响应取消封送回对象来自定义的。创建新实例时,构造函数将设置多个构成 RestTemplate 功能的支持对象。​​RestTemplate​​​​HttpMessageConverter​​​​RestTemplate​


(资料图)

下面概述了 中支持的功能。​​RestTemplate​

2.2.1 HTTP 客户端

​RestTemplate​​提供了一个用于发出 RESTful HTTP 请求的抽象,并在内部为这些请求使用本机 Android HTTP 客户端库。Android 上有两个本机 HTTP 客户端,标准 J2SE 设施和HttpComponents HttpClient。标准的 JS2SE 工具可通过 获得,而 HttpClient 可通过 使用。对原生 HttpClient 4.0 的支持已被弃用,取而代之的是 HttpClient 4.3 的 Android 端口。创建新实例时使用的默认值因运行应用程序的 Android 版本而异。​​RestTemplate​​​​SimpleClientHttpRequestFactory​​​​HttpComponentsAndroidClientHttpRequestFactory​​​​ClientHttpRequestFactory​​​​RestTemplate​

Google 建议在Android 2.3(Gingerbread)及更高版本上使用 J2SE 工具,而以前的版本应使用 HttpComponents HttpClient。根据此建议,检查运行应用的 Android 版本,并使用相应的 .若要使用特定实例,必须将新实例传递到构造函数中,或调用现有实例。​​RestTemplate​​​​ClientHttpRequestFactory​​​​ClientHttpRequestFactory​​​​RestTemplate​​​​setRequestFactory(ClientHttpRequestFactory requestFactory)​​​​RestTemplate​

Spring for Android 还包括对第三方 HTTP 客户端库的支持。适用于Android的HttpClient 4.3与所有版本的Android兼容,并且可以通过简单地将依赖项包含在项目中来用作本机客户端的替代方案。如果 Spring for Android 检测到 HttpClient 4.3,那么它会自动将其配置为默认 .HttpClient 4.3 对 Android 中包含的原生 HttpClient 4.0 进行了大量错误修复和改进。​​ClientHttpRequestFactory​

dependencies {    compile("org.apache.httpcomponents:httpclient-android:$httpClientVersion")}

基于OkHttp的附加功能可作为两个本机客户端的替代方法。 可以配置为通过构造函数或通过设置属性来使用。它在Android 2.3(Gingerbread)及更高版本上受支持,但是为了使用它,您必须在项目中包含OkHttp依赖项。​​ClientHttpRequestFactory​​​​RestTemplate​​​​OkHttpRequestFactory​​​​RestTemplate​​​​requestFactory​

dependencies {    compile("com.squareup.okhttp:okhttp-urlconnection:$okHttpVersion")}

2.2.2 Gzip 压缩

​RestTemplate​​支持发送和接收使用 gzip 压缩编码的数据。HTTP 规范允许在标头字段中使用其他值,但目前仅支持 gzip 压缩。​​Accept-Encoding​​​​RestTemplate​

2.2.3 对象到 JSON 封送处理

Spring for Android RestTemplate 中的 JSON 封送处理对象需要使用第三方 JSON 映射库。Spring for Android 支持两个库,Jackson 2.x​和Google Gson。虽然 Jackson 是一个众所周知的 JSON 解析库,但 Gson 库更小,这将导致打包时 Android 应用程序更小。

2.2.4 对象到 XML 封送处理

在 Spring for Android RestTemplate 中反对 XML 封送处理需要使用第三方 XML 映射库。简单 XML 序列化程序用于提供此封送处理功能。

2.3 如何获取

有几种方法可以在您的 Android 应用中包含外部 jar。您可以使用 Gradle 或 Maven 进行依赖关系管理,也可以手动下载它们并将其包含在应用的文件夹中。​​libs/​

2.3.1 格拉德尔

Android Studio 和New Build Systemfor Android 提供了一个用于构建Android应用程序的 Gradle 插件。Gradle 提供了内置的依赖项管理,可用于将 Spring for Android 依赖项包含在项目中。

将 spring-android-rest-template 依赖项添加到您的文件中:​​build.gradle​

dependencies {    compile("org.springframework.android:spring-android-rest-template:${version}")}

2.3.2Maven

Maven可用于管理依赖项和构建Android应用程序。有关更多信息,请参阅Spring for Android 和 Maven部分。可能需要其他依赖项,具体取决于您在 RestTemplate 中使用的 HTTP 消息转换器。有关详细信息,请参阅消息转换器部分。

将 spring-android-rest-template 依赖项添加到您的文件中:​​pom.xml​

    org.springframework.android    spring-android-rest-template    ${spring-android-version}

2.3.3 蚂蚁和日食

为了在Android应用程序中使用RestTemplate,您必须在文件夹中包含以下Spring for Android jars。​​libs/​

​spring-android-rest-template-{version}.jar​​​​spring-android-core-{version}.jar​

如果使用 Ant 构建项目,Ant 将自动包含位于项目根目录中的任何 jar。但是,在 Eclipse 中,您必须手动将 jar 添加到构建路径中。按照以下步骤将 jar 添加到 Eclipse 中的现有 Android 项目中。​​libs/​

在 Eclipse 中刷新项目,以便文件夹和 jar 显示在包资源管理器中。​​libs/​​右键单击(按住命令单击)第一个 jar。选择子菜单。​​BuildPath​​从上下文菜单中选择。​​Add to Build Path​​对每个罐子重复这些步骤。

2.4 RestTemplate 构造函数

下面列出了构造函数。默认构造函数包括一组标准的消息正文转换器。有关默认转换器的列表,请参阅HTTP 消息转换部分。​​RestTemplate​

RestTemplate();RestTemplate(ClientHttpRequestFactory requestFactory);RestTemplate(List> messageConverters);

如果要指定替代项,例如 ,则可以将其传递给参数。​​ClientHttpRequestFactory​​​​OkHttpClientHttpRequestFactory​​​​requestFactory​

OkHttpClientHttpRequestFactory requestFactory = new OkHttpClientHttpRequestFactory();RestTemplate template = new RestTemplate(ClientHttpRequestFactory requestFactory);

2.5 休息模板方法

​RestTemplate​​提供与六个主要 HTTP 方法中的每一个相对应的高级方法。这些方法可以轻松调用许多 RESTful 服务并强制实施 REST 最佳实践。

方法的名称遵循命名约定,第一部分指示正在调用的 HTTP 方法,第二部分指示返回的内容。例如,该方法将执行 GET,将 HTTP 响应转换为您选择的对象类型并返回该对象。该方法将执行 POST,将给定对象转换为 HTTP 请求,并返回响应 HTTP 位置标头,可在其中找到新创建的对象。如果处理 HTTP 请求发生异常,将引发该类型的异常。可以通过将另一个实现插入到​​RestTemplate​​​​getForObject()​​​​postForLocation()​​​​RestClientException​​​​ResponseErrorHandler​​​​RestTemplate.​

有关及其相关方法的更多信息,请参阅API Javadoc​RestTemplate​

2.5.1 HTTP 删除

public void delete(String url, Object... urlVariables) throws RestClientException;public void delete(String url, Map urlVariables) throws RestClientException;public void delete(URI url) throws RestClientException;

2.5.2HTTP GET

public  T getForObject(String url, Class responseType, Object... urlVariables) throws RestClientException;public  T getForObject(String url, Class responseType, Map urlVariables) throws RestClientException;public  T getForObject(URI url, Class responseType) throws RestClientException;public  ResponseEntity getForEntity(String url, Class responseType, Object... urlVariables);public  ResponseEntity getForEntity(String url, Class responseType, Map urlVariables);public  ResponseEntity getForEntity(URI url, Class responseType) throws RestClientException;

2.5.3HTTP HEAD

public HttpHeaders headForHeaders(String url, Object... urlVariables) throws RestClientException;public HttpHeaders headForHeaders(String url, Map urlVariables) throws RestClientException;public HttpHeaders headForHeaders(URI url) throws RestClientException;

2.5.4 HTTP 选项

public Set optionsForAllow(String url, Object... urlVariables) throws RestClientException;public Set optionsForAllow(String url, Map urlVariables) throws RestClientException;public Set optionsForAllow(URI url) throws RestClientException;

2.5.5 HTTP开机自救

public URI postForLocation(String url, Object request, Object... urlVariables) throws RestClientException;public URI postForLocation(String url, Object request, Map urlVariables);public URI postForLocation(URI url, Object request) throws RestClientException;public  T postForObject(String url, Object request, Class responseType, Object... uriVariables);public  T postForObject(String url, Object request, Class responseType, Map uriVariables);public  T postForObject(URI url, Object request, Class responseType) throws RestClientException;public  ResponseEntity postForEntity(String url, Object request, Class responseType, Object... uriVariables);public  ResponseEntity postForEntity(String url, Object request, Class responseType, Map uriVariables) throws RestClientException;public  ResponseEntity postForEntity(URI url, Object request, Class responseType) throws RestClientException;

2.5.6HTTP PUT

public void put(String url, Object request, Object... urlVariables) throws RestClientException;public void put(String url, Object request, Map urlVariables) throws RestClientException;public void put(String url, Object request, Map urlVariables) throws RestClientException;

2.6 HTTP 消息转换

传递给方法 、 和 从方法返回的对象被实例转换为 HTTP 请求和 HTTP 响应。界面如下所示,让您更好地了解其功能。​​getForObject()​​​​getForEntity()​​​​postForLocation()​​​​postForObject()​​​​put()​​​​HttpMessageConverter​​​​HttpMessageConverter​

public interface HttpMessageConverter {    // Indicates whether the given class can be read by this converter.    boolean canRead(Class clazz, MediaType mediaType);    // Indicates whether the given class can be written by this converter.    boolean canWrite(Class clazz, MediaType mediaType);    // Return the list of {@link MediaType} objects supported by this converter.    List getSupportedMediaTypes();    // Read an object of the given type form the given input message, and returns it.    T read(Class clazz, HttpInputMessage inputMessage)            throws IOException, HttpMessageNotReadableException;    // Write an given object to the given output message.    void write(T t, MediaType contentType, HttpOutputMessage outputMessage)            throws IOException, HttpMessageNotWritableException;}

框架中提供了主要媒体 (MIME) 类型的具体实现。

2.6.1 默认消息转换器

默认构造函数为主要 MIME 类型注册一组标准的消息转换器。您还可以编写自己的转换器并通过属性注册。​​RestTemplate​​​​messageConverters​

向模板注册的默认转换器实例为 、、 和 。有关详细信息,请参阅下表。​​ByteArrayHttpMessageConverter​​​​StringHttpMessageConverter​​​​ResourceHttpMessageConverter​​​​SourceHttpMessageConverter​​​​AllEncompassingFormHttpMessageConverter​

表 2.1.默认消息转换器

消息正文转换器

收录规则

ByteArrayHttpMessageConverter

始终包括在内

StringHttpMessageConverter

ResourceHttpMessageConverter

SourceHttpMessageConverter

AllEncompassingFormHttpMessageConverter

SimpleXmlHttpMessageConverter

如果存在简单 XML 序列化程序,则包括在内。

MappingJackson2HttpMessageConverter

如果存在杰克逊 2.x JSON 处理器,则包括在内。

GsonHttpMessageConverter

如果 Gson 存在,则包括在内。如果 Jackson 2.x 在类路径上都可用,则 Gson 优先于 Gson。

2.6.2 可用的消息转换器

以下实现在 Spring for Android 中可用。对于所有转换器,将使用默认媒体类型,但可以通过属性重写。​​HttpMessageConverter​​​​supportedMediaTypes​

ByteArrayHttpMessageConverter

可以从 HTTP 请求和响应读取和写入字节数组的实现。默认情况下,此转换器支持所有媒体类型 (),并且写入时为 .这可以通过设置支持的媒体类型属性和重写来覆盖。​​HttpMessageConverter​​​​*/*​​​​Content-Type​​​​application/octet-stream​​​​getContentType(byte[])​

FormHttpMessageConverter

可以从 HTTP 请求和响应读取和写入表单数据的实现。默认情况下,此转换器读取和写入媒体类型。从 .​​HttpMessageConverter​​​​application/x-www-form-urlencoded​​​​MultiValueMap

AllEncompassingFormHttpMessageConverter

的扩展,添加了对基于 XML 和 JSON 的部分的支持。​​FormHttpMessageConverter​

资源HttpMessageConverter

可以读取和写入资源的实现。默认情况下,此转换器可以读取所有媒体类型。写入资源用于 。​​HttpMessageConverter​​​​Resource​​​​application/octet-stream​​​​Content-Type​

SourceHttpMessageConverter

可以从 HTTP 请求和响应读取和写入的实现。仅支持 、 和。默认情况下,此转换器支持 和 。​​HttpMessageConverter​​​​javax.xml.transform.Source​​​​DOMSource​​​​SAXSource​​​​StreamSource​​​​text/xml​​​​application/xml​

StringHttpMessageConverter

可以从 HTTP 请求和响应读取和写入字符串的实现。默认情况下,此转换器支持所有文本媒体类型 (),并使用 .​​HttpMessageConverter​​​​text/*​​​​Content-Type​​​​text/plain​

SimpleXmlHttpMessageConverter

可以使用简单框架的 HTTP 请求和响应读取和写入 XML 的实现。XML映射可以通过使用Simple提供的注释根据需要进行自定义。当需要其他控件时,可以通过属性注入自定义。默认情况下,此转换器读取和写入媒体类型 、 和 。​​HttpMessageConverter​​​​Serializer​​​​Serializer​​​​Serializer​​​​application/xml​​​​text/xml​​​​application/*+xml​

重要的是要注意,这不是与Spring OXM兼容的消息转换器。它是一个独立的实现,通过 Spring for Android 实现 XML 序列化。

将以下依赖项添加到类路径中以启用 .​​SimpleXmlHttpMessageConverter​

格拉德尔:

dependencies {    compile("org.simpleframework:simple-xml:${version}")}

专家:

    org.simpleframework    simple-xml    ${simple-version}

MappingJackson2HttpMessageConverter

可以使用杰克逊 (2.x)的 .JSON 映射可以根据需要通过使用 Jackson 提供的注释进行自定义。当需要进一步控制时,对于需要为特定类型提供自定义 JSON 序列化程序/反序列化程序的情况,可以通过属性注入自定义。默认情况下,此转换器支持 .​​HttpMessageConverter​​​​ObjectMapper​​​​ObjectMapper​​​​ObjectMapper​​​​application/json​

请注意,默认情况下,此消息转换器和两者都支持。因此,您应该只向实例添加一个 JSON 消息转换器。 将使用它找到的第一个与指定 MIME 类型匹配的转换器,因此包括两者可能会产生意外结果。​​GsonHttpMessageConverter​​​​application/json​​​​RestTemplate​​​​RestTemplate​

在类路径中包含以下依赖项以启用 .请注意,如果您手动将 jar 复制到项目中,则还需要包含 和 jar。​​MappingJackson2HttpMessageConverter​​​​jackson-annotations​​​​jackson-core​

格拉德尔:

dependencies {    compile("com.fasterxml.jackson.core:jackson-databind:${version}")}

专家:

    com.fasterxml.jackson.core    jackson-databind    ${jackson-version}

GsonHttpMessageConverter

可以使用 Google Gson 的类读取和写入 JSON 的实现。 JSON 映射可以根据需要通过使用​​Gson​​提供的注释进行自定义。当需要进一步控制时,对于需要为特定类型提供自定义 JSON 序列化程序/反序列化程序的情况,可以通过属性注入自定义。默认情况下,此转换器支持 .​​HttpMessageConverter​​​​Gson​​​​Gson​​​​Gson​​​​application/json​

请注意,默认情况下,此消息转换器和两者都支持。因此,您应该只向实例添加一个 JSON 消息转换器。 将使用它找到的第一个与指定 MIME 类型匹配的转换器,因此包括两者可能会产生意外结果。​​MappingJackson2HttpMessageConverter​​​​application/json​​​​RestTemplate​​​​RestTemplate​

在类路径中包含以下依赖项以启用 .​​GsonHttpMessageConverter​

格拉德尔:

dependencies {    compile("com.google.code.gson:gson:${version}")}

专家:

    com.google.code.gson    gson    ${gson-version}

2.7 使用示例

使用 ,很容易调用 RESTful API。下面是几个使用示例,说明了发出 RESTful 请求的不同方法。​​RestTemplate​

以下所有示例均基于示例 Android 应用程序。可以使用以下命令检索示例应用的源代码:

$ git clone git://github.com/spring-projects/spring-android-samples.git

2.7.1 基本使用示例

以下示例显示了对搜索词“Spring Framework”的搜索向 google 的查询。

String url = "https://ajax.googleapis.com/ajax/services/search/web?v=1.0&q={query}";      // Create a new RestTemplate instanceRestTemplate restTemplate = new RestTemplate();// Make the HTTP GET request, marshaling the response to a StringString result = restTemplate.getForObject(url, String.class, "Spring Framework");

2.7.2 使用 gzip 压缩

Gzip 压缩可以显著减小 REST 请求中返回的响应数据的大小。Gzip 必须由向其发出请求的 Web 服务器支持。通过将标头的内容编码类型设置为 ,您将请求服务器使用 gzip 压缩进行响应。如果 gzip 可用或在服务器上启用,则它应返回压缩响应。RestTemplate 检查响应中的标头,以确定响应实际上是否经过 gzip 压缩。目前,RestTemplate 仅支持标头中的 gzip 内容编码类型。如果响应数据被确定为 gzip 压缩,则使用​​GZIPInputStream​对其进行解压缩。​​Accept-Encoding​​​​gzip​​​​Content-Encoding​​​​Content-Encoding​

以下示例演示如何从服务器请求 gzip 压缩响应。

// Add the gzip Accept-Encoding headerHttpHeaders requestHeaders = new HttpHeaders();requestHeaders.setAcceptEncoding(ContentCodingType.GZIP);HttpEntity requestEntity = new HttpEntity(requestHeaders);// Create a new RestTemplate instanceRestTemplate restTemplate = new RestTemplate();// Make the HTTP GET request, marshaling the response to a StringResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);

需要注意的一点是,当将 J2SE 工具与 、Gingerbread 和更新版本一起使用时,会自动设置接受编码标头以请求 gzip 响应。这是较新版本的Android内置功能。如果要禁用 gzip,则必须在标头中设置值。​​SimpleClientHttpRequestFactory​​​​identity​

// Add the identity Accept-Encoding headerHttpHeaders requestHeaders = new HttpHeaders();requestHeaders.setAcceptEncoding(ContentCodingType.IDENTITY);HttpEntity requestEntity = new HttpEntity(requestHeaders);// Create a new RestTemplate instanceRestTemplate restTemplate = new RestTemplate();// Make the HTTP GET request, marshaling the response to a StringResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);

2.7.3 通过 HTTP GET 检索 JSON 数据

假设您已经定义了一个 Java 对象,您希望从返回 JSON 内容的 RESTful Web 请求中填充。封送处理 JSON 内容需要 Jackson 或 Gson 在类路径上可用。

根据从 RESTful 请求返回的 JSON 数据定义对象:

public class Event {    private Long id;    private String title;        public Long getId() {        return id;    }    public void setId(Long id) {        this.id = id;    }    public String getTitle() {        return title;    }        public String setTitle(String title) {        this.title = title;    }}

发出 REST 请求:

// Create a new RestTemplate instanceRestTemplate restTemplate = new RestTemplate();// Make the HTTP GET request, marshaling the response from JSON to an array of EventsEvent[] events = restTemplate.getForObject(url, Event[].class);

您还可以设置请求的标头:​​Accept​

// Set the Accept headerHttpHeaders requestHeaders = new HttpHeaders();requestHeaders.setAccept(Collections.singletonList(new MediaType("application","json")));HttpEntity requestEntity = new HttpEntity(requestHeaders);// Create a new RestTemplate instanceRestTemplate restTemplate = new RestTemplate();// Make the HTTP GET request, marshaling the response from JSON to an array of EventsResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, Event[].class);Event[] events = responseEntity.getBody();

2.7.4 通过 HTTP GET 检索 XML 数据

使用我们之前定义的相同 Java 对象,我们可以修改检索 XML 的请求。

根据从 RESTful 请求返回的 XML 数据定义对象。请注意 Simple 用于封送对象的注释:

@Rootpublic class Event {    @Element    private Long id;    @Element    private String title;    public Long getId() {        return id;    }    public void setId(Long id) {        this.id = id;    }    public String getTitle() {        return title;    }    public String setTitle(String title) {        this.title = title;    }}

若要从 xml 封送事件数组,需要为列表定义一个包装类:

@Root(name="events")public class EventList {   @ElementList(inline=true)   private List events;   public List getEvents() {      return events;   }   public void setEvents(List events) {       this.events = events;   }}

发出 REST 请求:

// Create a new RestTemplate instanceRestTemplate restTemplate = new RestTemplate();// Make the HTTP GET request, marshaling the response from XML to an EventList objectEventList eventList = restTemplate.getForObject(url, EventList.class);

您还可以指定请求的标头:​​Accept​

// Set the Accept headerHttpHeaders requestHeaders = new HttpHeaders();requestHeaders.setAccept(Collections.singletonList(new MediaType("application","xml")));HttpEntity requestEntity = new HttpEntity(requestHeaders);// Create a new RestTemplate instanceRestTemplate restTemplate = new RestTemplate();// Make the HTTP GET request, marshaling the response from XML to an EventListResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, EventList.class);EventList eventList = responseEntity.getBody();

2.7.5 通过 HTTP POST 发送 JSON 数据

将您定义的 Java 对象发布到接受 JSON 数据的 RESTful 服务。

根据 RESTful 请求所需的 JSON 数据定义对象:

public class Message {    private long id;    private String subject;    private String text;    public void setId(long id) {        this.id = id;    }    public long getId() {        return id;    }    public void setSubject(String subject) {        this.subject = subject;    }    public String getSubject() {        return subject;    }    public void setText(String text) {        this.text = text;    }    public String getText() {        return text;    }}

发出 REST 请求。在此示例中,请求以字符串值响应:

// Create and populate a simple object to be used in the requestMessage message = new Message();message.setId(555);message.setSubject("test subject");message.setText("test text");// Create a new RestTemplate instanceRestTemplate restTemplate = new RestTemplate();// Make the HTTP POST request, marshaling the request to JSON, and the response to a StringString response = restTemplate.postForObject(url, message, String.class);

您还可以在请求中指定标头:​​Content-Type​

// Create and populate a simple object to be used in the requestMessage message = new Message();message.setId(555);message.setSubject("test subject");message.setText("test text");// Set the Content-Type headerHttpHeaders requestHeaders = new HttpHeaders();requestHeaders.setContentType(new MediaType("application","json"));HttpEntity requestEntity = new HttpEntity(message, requestHeaders);// Create a new RestTemplate instanceRestTemplate restTemplate = new RestTemplate();// Make the HTTP POST request, marshaling the request to JSON, and the response to a StringResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);String result = responseEntity.getBody();

2.7.6 HTTP 基本身份验证

此示例说明如何使用用户名和密码填充HTTP 基本身份验证标头。如果用户名和密码被接受,您将收到请求的响应。如果它们不被接受,则服务器应该返回HTTP 401未授权响应。在内部,RestTemplate 处理响应,然后抛出 .通过调用此异常,可以确定确切原因并适当处理它。​​HttpClientErrorException​​​​getStatusCode()​

// Set the username and password for creating a Basic Auth requestHttpAuthentication authHeader = new HttpBasicAuthentication(username, password);HttpHeaders requestHeaders = new HttpHeaders();requestHeaders.setAuthorization(authHeader);HttpEntity requestEntity = new HttpEntity(requestHeaders);// Create a new RestTemplate instanceRestTemplate restTemplate = new RestTemplate();try {    // Make the HTTP GET request to the Basic Auth protected URL    ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);    return response.getBody();} catch (HttpClientErrorException e) {    Log.e(TAG, e.getLocalizedMessage(), e);    // Handle 401 Unauthorized response}                
              
            
            

标签: 构造函数 应用程序 您还可以

上一篇:从实战开始,零基础Docker入门教程
下一篇:焦点观察:vue切换中英语言制作方法(Element+i18n的使用)