日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【REST】REST和JAX-RS相关知识介绍

發(fā)布時間:2025/3/21 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【REST】REST和JAX-RS相关知识介绍 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

REST

REpresentational?State?Transfer代表性狀態(tài)傳輸、具象狀態(tài)傳輸

REST定義了應該如何正確地使用Web標準,例如HTTP和URI。REST并非標準,而是一種開發(fā) Web 應用的架構(gòu)風格,可以將其理解為一種設(shè)計模式。

?

REST關(guān)鍵原則

1、為所有“事物”定義ID

含義:

在Web中,代表ID的統(tǒng)一概念是:URI。URI構(gòu)成了一個全局命名空間,使用URI標識你的關(guān)鍵資源意味著它們獲得了一個唯一、全局的ID。

使用URI標識所有值得標識的事物,特別是應用中提供的所有“高級”資源,無論這些資源代表單一數(shù)據(jù)項、數(shù)據(jù)項集合、虛擬亦或?qū)嶋H的對象還是計算結(jié)果等。

好處:

使用唯一、全局統(tǒng)一的命名規(guī)則的好處,既適用于瀏覽器中的Web應用,也適用于機對機(machine-to-machine,m2m)通信。

?

2、將所有事物鏈接在一起

含義:

任何可能的情況下,使用鏈接指引可以被標識的事物(資源)。

正式描述:“超媒體被當作應用狀態(tài)引擎(Hypermedia as the engine of application state)”,有時簡寫為HATEOAS。這個描述的核心是超媒體概念,換句話說:是鏈接的思想

好處:

超媒體原則還有一個更重要的方面——應用“狀態(tài)”。簡而言之,實際上服務器端為客戶端提供一組鏈接,使客戶端能通過鏈接將應用從一個狀態(tài)改變?yōu)榱硪粋€狀態(tài)。目前,只需要記住:鏈接是構(gòu)成動態(tài)應用的非常有效的方式.

?

[html]?view plain?copy ?print?

  • <order?self="http://example.com/customers/1234">???
  • ???<amount>23</amount>???
  • ???<product?ref="http://example.com/products/4554">???
  • ???<customer?ref="http://example.com/customers/1234">???
  • ????</customer>???
  • ????</product>??
  • </order>??
  • ?

    ?

    ?

    3、使用標準方法

    含義:

    瀏覽器知道如何去處理URI的原因在于所有的資源都支持同樣的接口,一套同樣的方法集合。標準方法集合包含GET、POST\PUT、DELETE、HEAD和OPTIONS

    為使客戶端程序能與你的資源相互協(xié)作,資源應該正確地實現(xiàn)默認的應用協(xié)議(HTTP),也就是使用標準的GET、PUT、POST和DELETE方法。

    好處:

    它使你的應用成為Web的一部分——應用程序為Web變成Internet上最成功的應用所做的貢獻,與它添加到Web中的資源數(shù)量成比例。采用RESTful方式,一個應用可能會向Web中添加數(shù)以百萬計的客戶URI

    統(tǒng)一接口也使得所有理解HTTP應用協(xié)議的組件能與你的應用交互。通用客戶程序(generic client)就是從中受益的組件的例子,例如curl、wget、代理、緩存、HTTP服務器、網(wǎng)關(guān)還有Google、Yahoo!、MSN等等。

    ?

    4、資源多重表述?

    含義:

    客戶程序如何知道該怎樣處理檢索到的數(shù)據(jù),比如作為GET或者POST請求的結(jié)果?原因是,HTTP采取的方式是允許數(shù)據(jù)處理和操作調(diào)用之間關(guān)系分離的。

    針對不同的需求提供資源多重表述

    好處:

    如果你為你的資源提供HTML和XML兩種表述方式,那這些資源不僅可以被你的應用所用,還可以被任意標準Web瀏覽器所用

    ?

    5、無狀態(tài)通信

    含義:

    REST要求狀態(tài)要么被放入資源狀態(tài)中,要么保存在客戶端上。或者換句話說,服務器端不能保持除了單次請求之外的,任何與其通信的客戶端的通信狀態(tài)。

    這樣做的最直接的理由就是可伸縮性—— 如果服務器需要保持客戶端狀態(tài),那么大量的客戶端交互會嚴重影響服務器的內(nèi)存可用空間

    好處:

    無狀態(tài)約束使服務器的變化對客戶端是不可見的,因為在兩次連續(xù)的請求中,客戶端并不依賴于同一臺服務器。

    ?

    ?

    JAX-RS

    ?

    Java?API forRESTful WebServices旨在定義一個統(tǒng)一的規(guī)范,使得?Java?程序員可以使用一套固定的接口來開發(fā) REST 應用,避免了依賴于第三方框架。是一個Java編程語言的應用程序接口,支持按照表象化狀態(tài)轉(zhuǎn)變 (REST)架構(gòu)風格創(chuàng)建Web服務Web服務。

    與傳統(tǒng)的 servlet 模型相比,JAX-RS 提供了一種可行的、更為簡便、移植性更好的方式來在 Java 內(nèi)實現(xiàn) RESTful 服務。使用注釋讓您能夠輕松提供 Java 資源的路徑位置并將 Java 方法綁定到 HTTP 請求方法。一種可移植的數(shù)據(jù)綁定架構(gòu)提供了一些本機的 Java 類型支持并允許進行序列化/反序列化處理的完全定制。javax.ws.rs.core.Application 子類的擴展以及 web.xml 內(nèi)的相應清單表明了用最少的部署描述符配置就能進行輕松部署。

    JAX-RS 的具體實現(xiàn)由第三方提供,例如 Sun 的參考實現(xiàn)?Jersey、Apache 的?CXF?以及 JBoss 的?RESTEasy

    ?

    JAX-RS標注

    JAX-RS提供了一些標注將一個資源類,一個POJO類,封裝為Web資源。標注包括:

    @Path,標注資源類或方法的相對路徑

    @GET,@PUT,@POST,@DELETE,標注方法是用的HTTP請求的類型,分別對應 4 種 HTTP 方法,用于對資源進行創(chuàng)建、檢索、更新和刪除的操作。

    • 若要創(chuàng)建資源,應該使用 POST 方法;
    • 若要檢索某個資源,應該使用 GET 方法;
    • 若要更改資源狀態(tài)或?qū)ζ溥M行更新,應該使用 PUT 方法;
    • 若要刪除某個資源,應該使用 DELETE 方法。

    @Produces,標注返回的MIME媒體類型

    @Consumes,標注可接受請求的MIME媒體類型

    @PathParam,@QueryParam,@HeaderParam,@CookieParam,@MatrixParam,@FormParam,分別標注方法的參數(shù)來自于HTTP請求的不同位置,

    ?

    • @PathParam來自于URL的路徑,
    • @QueryParam來自于URL的查詢參數(shù),
    • @HeaderParam來自于HTTP請求的頭信息,
    • @CookieParam來自于HTTP請求的Cookie。

    ?

    ?

    Resource類和Resource方法

    ?

    Web 資源作為一個?Resource 類來實現(xiàn),對資源的請求由?Resource 方法來處理。

    Resource 類或 Resource 方法被打上了 Path 標注,Path 標注的值是一個相對的 URI 路徑,用于對資源進行定位,路徑中可以包含任意的正則表達式以匹配資源。和大多數(shù) JAX-RS 標注一樣,Path 標注是可繼承的,子類或?qū)崿F(xiàn)類可以繼承超類或接口中的 Path 標注。

    Resource 類是 POJO,使用 JAX-RS 標注來實現(xiàn)相應的 Web 資源。

    Resource 類分為根 Resource 類子 Resource 類,區(qū)別在于子 Resource 類沒有打在類上的 @Path 標注。

    Resource 類的實例方法打上了@Path 標注,則為?Resource 方法子 Resource 定位器,子 Resource 定位器上沒有任何 @GET、@POST、@PUT、@DELETE 或者自定義的 @HttpMethod

    ?

    ?

    ?

    [java]?view plain?copy ?print?

  • @Path("/")???
  • public?class?BookkeepingService?{???
  • ????......???
  • ????@Path("/person/")?//資源方法;若無@POST,則為子資源定位器??
  • ????@POST???
  • ????@Consumes("application/json")???
  • ????public?Response?createPerson(Person?person)?{?//JSON?格式的請求體被自動映射為實體參數(shù)person??
  • ????????......???
  • ????}???
  • ??
  • ????@Path("/person/")???
  • ????@PUT???
  • ????@Consumes("application/json")???
  • ????public?Response?updatePerson(Person?person)?{???
  • ????????......???
  • ????}???
  • ??
  • ????@Path("/person/{id:\\d+}/")?//正則表達式??
  • ????@DELETE???
  • ????public?Response?deletePerson(@PathParam("id")???
  • ????int?id)?{???
  • ????????......???
  • ????}???
  • ??
  • ????@Path("/person/{id:\\d+}/")???
  • ????@GET???
  • ????@Produces("application/json")???
  • ????public?Person?readPerson(@PathParam("id")???
  • ????int?id)?{???
  • ????????......???
  • ????}???
  • ??
  • ????@Path("/persons/")???
  • ????@GET???
  • ????@Produces("application/json")???
  • ????public?Person[]?readAllPersons()?{?//數(shù)組類型的返回值被自動映射為?JSON?格式的響應體——???
  • ????????......???
  • ????}???
  • ??
  • ????@Path("/person/{name}/")???
  • ????@GET???
  • ????@Produces("application/json")???
  • ????public?Person?readPersonByName(@PathParam("name")???
  • ????String?name)?{???
  • ????????......???
  • }???
  • ?

    ?

    注意:

  • Subresources Locators是指一個指定了@Path annotation,但未指定HttpMethod的annotation
  • 最好是在一個interface中定義這個標注,然后實現(xiàn)這個interface
  • ?

    Resource方法參數(shù)類型、返回類型

    Resource 方法合法的參數(shù)類型包括:

  • 原生類型?——在客戶端如何發(fā)送原生類型?可否發(fā)送JSON類?
  • 構(gòu)造函數(shù)接收單個字符串參數(shù),或者包含擁有一個static的valueOf(String)方法
  • List<T>,Set<T>,SortedSet<T>(T 為以上的 2 種類型)
  • 用于映射請求體的實體參數(shù)
  • Resource 方法合法的返回值類型包括:

  • void:狀態(tài)碼 204 和空響應體
  • Response:Response 的 status 屬性指定了狀態(tài)碼,entity 屬性映射為響應體

    [java]?view plain?copy ?print?

  • return?Response.status(Status.OK).entity(JsonUtils.toString(result)).build();??
  • GenericEntity:GenericEntity 的 entity 屬性映射為響應體,entity 屬性為空則狀態(tài)碼為 204,非空則狀態(tài)碼為 200
  • 其它類型:返回的對象實例映射為響應體,實例為空則狀態(tài)碼為 204,非空則狀態(tài)碼為 200
  • 對于錯誤處理,Resource 方法可以拋出非受控異常 WebApplicationException 或者返回包含了適當?shù)腻e誤碼集合的 Response 對象。

    ?

    內(nèi)容協(xié)商與數(shù)據(jù)綁定

    ?

    Web 資源可以有不同的表現(xiàn)形式,服務端與客戶端之間需要一種稱為內(nèi)容協(xié)商(Content Negotiation)的機制:

    作為服務端,Resource 方法的@Produces?標注用于指定響應體的數(shù)據(jù)格式(MIME 類型),@Consumes?標注用于指定請求體的數(shù)據(jù)格式

    作為客戶端,Accept?請求頭用于選擇響應體的數(shù)據(jù)格式,Content-Type?請求頭用于標識請求體的數(shù)據(jù)格式。

    ——Produces=Accept?Consumes=Content-Type?

    ?

    服務端:@Produces,@Consumes

    ?

    [java]?view plain?copy ?print?

  • @GET??
  • @Path(value="/{emailAddress:.+@.+\\.[a-z]+}")??
  • @Produces(value={"text/xml",?"application/json"})??
  • public?ContactInfo?getByEmailAddress(@PathParam(value="emailAddress")???
  • ????String?emailAddress)?{??
  • ????...??
  • }?????
  • ??
  • ??
  • @POST??
  • @Consumes(value={"text/xml",?"application/json"})??
  • public?void?addContactInfo(ContactInfo?contactInfo)?{??
  • ????...??
  • }??
  • ?

    ?

    客戶端AngularJS:Accept,Content-Type

    例如AngularJS發(fā)送請求:

    [javascript]?view plain?copy ?print?

  • $http({method:?'GET',?url:?'/someUrl'}).??
  • success(function(data,?status,?headers,?config)?{??
  • //?this?callback?will?be?called?asynchronously??
  • //?when?the?response?is?available??
  • }).??
  • error(function(data,?status,?headers,?config)?{??
  • //?called?asynchronously?if?an?error?occurs??
  • //?or?server?returns?response?with?an?error?status.??
  • });??
  • ?

    ?

    ?

    AngularJS Setting HTTP Headers

    ?

    默認的HTTP頭:

    The?$http?service will automatically add certain HTTP headers to all requests. These defaultscan be fully configured by accessing the$httpProvider.defaults.headers?configurationobject, which currently contains this default configuration:

    • $httpProvider.defaults.headers.common?(headers that are common for all requests):
      • Accept: application/json, text/plain, * / *
      • X-Requested-With: XMLHttpRequest
    • $httpProvider.defaults.headers.post: (header defaults for POST requests)
      • Content-Type: application/json
    • $httpProvider.defaults.headers.put?(header defaults for PUT requests)
      • Content-Type: application/json

    如何修改HTTP頭:

    To add or overwrite these defaults, simply add or remove a property from these configuration objects. To add headers for an HTTP method other than POST or PUT, simply add a new objectwith the lowercased HTTP method name as the key, e.g.$httpProvider.defaults.headers.get['My-Header']='value'.

    Additionally, the defaults can be set at runtime via the?$http.defaults?object in the same fashion.

    ?

    e.g. 修改$httpProvider.defaults.headers(prevent angular.js $http object from sending X-Requested-With header)

    ?

    [javascript]?view plain?copy ?print?

  • angular.module('myModule',?[])??
  • ????.config(['$httpProvider',?function($httpProvider)?{??
  • ????????delete?$httpProvider.defaults.headers.common["X-Requested-With"]??
  • ????}])??
  • ?

    ?

    e.g. 使用$http.defaults

    [javascript]?view plain?copy ?print?

  • $http({??
  • ????method:?'POST',??
  • ????url:?url,??
  • ????headers:?{'Content-Type':?'application/x-www-form-urlencoded'},?//headers參數(shù)可以設(shè)置Accept、Content-Type??????
  • }).success(function?()?{});??
  • ?

    ?

    ?

    ?

    ?

    Requests與Responses的序列化和反序列化

    ?

    服務端:實現(xiàn)MessageBodyWriter、MessageBodyReader


    JAX-RS 依賴于 MessageBodyReader 和 MessageBodyWriter 的實現(xiàn)來自動完成返回值到響應體的序列化以及請求體到實體參數(shù)的反序列化工作,其中,XML 格式的請求/響應數(shù)據(jù)與 Java 對象的自動綁定依賴于 JAXB 的實現(xiàn)。
    用戶可以使用 Provider 標注來注冊使用自定義的 MessageBodyProvider,如 清單 6 所示,GsonProvider 類使用了 Google Gson 作為 JSON 格式的 MessageBodyProvider 的實現(xiàn)。

    ?

    [java]?view plain?copy ?print?

  • @Provider???
  • @Produces("application/json")???
  • @Consumes("application/json")???
  • public?class?GsonProvider?implements?MessageBodyWriter<Object>,???
  • ????MessageBodyReader<Object>?{???
  • ??
  • ????private?final?Gson?gson;???
  • ??
  • ????public?GsonProvider()?{???
  • ????????gson?=?new?GsonBuilder().excludeFieldsWithoutExposeAnnotation().setDateFormat(???
  • ????????????????"yyyy-MM-dd").create();???
  • ????}???
  • ??
  • ????public?boolean?isReadable(Class<?>?type,?Type?genericType,?Annotation[]?annotations,???
  • ????????????MediaType?mediaType)?{???
  • ????????return?true;???
  • ????}???
  • ??
  • ????//MessageBodyReader.readFrom()??
  • ????public?Object?readFrom(Class<Object>?type,?Type?genericType,???
  • ????????????Annotation[]?annotations,?MediaType?mediaType,???
  • ????????????MultivaluedMap<String,?String>?httpHeaders,?InputStream?entityStream)???
  • ????????????throws?IOException,?WebApplicationException?{???
  • ????????return?gson.fromJson(new?InputStreamReader(entityStream,?"UTF-8"),?type);???
  • ????}???
  • ??
  • ????public?boolean?isWriteable(Class<?>?type,?Type?genericType,?Annotation[]?annotations,???
  • ????????????MediaType?mediaType)?{???
  • ????????return?true;???
  • ????}???
  • ??
  • ????public?long?getSize(Object?obj,?Class<?>?type,?Type?genericType,???
  • ????????????Annotation[]?annotations,?MediaType?mediaType)?{???
  • ????????return?-1;???
  • ????}???
  • ??
  • ????//MessageBodyWriter.writeTo()??
  • ????public?void?writeTo(Object?obj,?Class<?>?type,?Type?genericType,???
  • ????????????Annotation[]?annotations,?MediaType?mediaType,???
  • ????????????MultivaluedMap<String,?Object>?httpHeaders,?OutputStream?entityStream)???
  • ????????????throws?IOException,?WebApplicationException?{???
  • ????????entityStream.write(gson.toJson(obj,?type).getBytes("UTF-8"));???
  • ????}???
  • ??
  • }???
  • ?

    配置完成后,如何讓它生效呢?——可以通過擴展 javax.ws.rs.core.Application 類實現(xiàn)

    ?

    [java]?view plain?copy ?print?

  • public?class?ContactInfoApplicaiton?extends?Application?{??
  • ????public?Set<Class<?>>?getClasses()?{??
  • ????????Set<Class<?>>?classes?=?new?HashSetSet<Class<?>>();??
  • ????????classes.add(ContactsResource.class);??
  • ????????classes.add(ContactInfoWriter.class);??
  • ????????classes.add(ContactInfoReader.class);??
  • ????}??
  • ??????
  • ????public?SetSet<Object<?>>?getSingletons()?{??
  • ????????//?nothing?to?do,?no?singletons??
  • ????}?????
  • }??
  • 然后配置web.xml

    ?

    ?

    [html]?view plain?copy ?print?

  • <web-app?id="WebApp_ID"?version="2.5">??
  • ????<servlet>??
  • ????????<servlet-name>ContactInfoServlet</servlet-name>??
  • ????????<servlet-class>com.sample.RESTSystemServlet</servlet-class>??
  • ????????<init-param>??
  • ????????????<param-name>javax.ws.rs.Application</param-name>??
  • ????????????<param-value>??
  • ????????????????com.ibm.jaxrs.sample.organization.ContactInfoApplication??
  • ????????????</param-value>??
  • ????????</init-param>??
  • ????</servlet>??
  • ????<servlet-mapping>??
  • ????????<servlet-name>ContactInfoServlet</servlet-name>??
  • ????????<url-pattern>/*</url-pattern>??
  • ????</servlet-mapping>??
  • </web-app>??
  • ?

    ?

    ?

    ?

    ?

    ?

    客戶端:$httpProvider.defaults.transformRequest/Response

    ?

    AngularJS Transforming Requests and Responses

    Both requests and responses can be transformed using transform functions. By default, Angularapplies these transformations:

    Request transformations:

    • If the?data?property of the request configuration object contains an object,serialize it intoJSON format.

    Response transformations:

    • If XSRF prefix is detected, strip it (see Security Considerations section below).
    • If JSON response is detected,?deserialize it using a JSON parser.

    To globally augment or override the default transforms, modify the?$httpProvider.defaults.transformRequest?and$httpProvider.defaults.transformResponse?properties. These properties are by default an array of transform functions, which allows you topush?or?unshift?a new transformation function into the transformation chain. You can also decide to completely override any default transformations by assigning yourtransformation functions to these properties directly without the array wrapper.

    ?

    Similarly, to?locally override the request/response transforms, augment thetransformRequestand/ortransformResponseproperties of the configuration object passed into$http.

    ?

    e.g.?local配置:在發(fā)送請求時設(shè)置transformRequest:

    ?

    ?

    ?

    [javascript]?view plain?copy ?print?

  • $http({??
  • ????method:?'POST',??
  • ????url:?url,??
  • ????headers:?{'Content-Type':?'application/x-www-form-urlencoded'},???
  • ????transformRequest:?function(obj)?{??
  • ????????var?str?=?[];??
  • ????????for(var?p?in?obj)??
  • ????????str.push(encodeURIComponent(p)?+?"="?+?encodeURIComponent(obj[p]));??
  • ????????return?str.join("&");??
  • ????},??
  • ????data:?xsrf??
  • }).success(function?()?{});??
  • ?

    ?

    e.g.?Global配置$httpProvider.defaults.transformRequest

    ?

    [javascript]?view plain?copy ?print?

  • var?module?=?angular.module('myApp');??
  • ??
  • module.config(function?($httpProvider)?{??
  • ????$httpProvider.defaults.transformRequest?=?function(data){??
  • ????????if?(data?===?undefined)?{??
  • ????????????return?data;??
  • ????????}??
  • ????????return?$.param(data);??
  • ????}??
  • });??
  • ?

    ?

    ?

    RESTEasy

    RESTEasy是JBoss提供的JAX-RS 的具體實現(xiàn)。、

    web.xml:

    ?

    [html]?view plain?copy ?print?

  • <?xml?version="1.0"?encoding="UTF-8"?>??
  • <web-app?version="2.5"?xmlns="http://java.sun.com/xml/ns/javaee"?>??
  • ????<context-param>??
  • ????????<param-name>resteasy.providers</param-name>??
  • ????????<param-value>??
  • ????????????org.jboss.resteasy.plugins.providers.DefaultTextPlain,??
  • ????????????org.jboss.resteasy.plugins.providers.ByteArrayProvider,??
  • ????????????org.jboss.resteasy.plugins.providers.InputStreamProvider,??
  • ????????????org.jboss.resteasy.plugins.providers.ByteArrayProvider,??
  • ????????????org.jboss.resteasy.plugins.providers.StringTextStar,??
  • ????????????org.jboss.resteasy.plugins.providers.FormUrlEncodedProvider??
  • ????????</param-value>??
  • ????</context-param>??
  • ????<context-param>??
  • ????????<param-name>resteasy.scan</param-name>??
  • ????????<param-value>true</param-value>??
  • ????</context-param>??
  • ????<context-param>??
  • ????????<param-name>resteasy.servlet.mapping.prefix</param-name>??
  • ????????<param-value>/web</param-value>??
  • ????</context-param>??
  • ??
  • ??
  • ????<listener>??
  • ????????<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>??
  • ????</listener>??
  • ????<servlet>??
  • ????????<servlet-name>Resteasy</servlet-name>??
  • ????????<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>??
  • ????</servlet>??
  • ????<servlet-mapping>??
  • ????????<servlet-name>Resteasy</servlet-name>??
  • ????????<url-pattern>/web/*</url-pattern>??
  • ????</servlet-mapping>??
  • ??
  • ??
  • </web-app>??
  • ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    參考資料

    http://liugang594.iteye.com/category/218423

    http://www.infoq.com/cn/articles/rest-introduction

    http://www.ibm.com/developerworks/cn/web/wa-jaxrs/ 用 Java 技術(shù)創(chuàng)建 RESTful Web 服務

    http://www.ibm.com/developerworks/cn/java/j-lo-jaxrs/ 使用 JAX-RS 簡化 REST 應用開發(fā)

    http://www.ibm.com/developerworks/cn/webservices/ws-restful/ 基于 REST 的 Web 服務:基礎(chǔ)

    總結(jié)

    以上是生活随笔為你收集整理的【REST】REST和JAX-RS相关知识介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。