Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Java Add ServiceStack Reference

Demis Bellot edited this pageOct 25, 2016 ·24 revisions

This page has moved todocs.servicestack.net


Like the existing IDE integrations before it, the ServiceStack IDEA plugin provides Add ServiceStack Reference functionality toAndroid Studio - the official Android IDE.

TheServiceStackIDEA plugin also includes support forIntelliJ Maven projects giving Java devs a productive and familiar development experience whether they're creating Android Apps or pure cross-platform Java clients.

Install ServiceStack IDEA from the Plugin repository

The ServiceStack IDEA is now available to install directly from within IntelliJ or Android Studio IDE Plugins Repository, to Install Go to:

  1. File -> Settings... Main Menu Item
  2. SelectPlugins on left menu then clickBrowse repositories... at bottom
  3. Search forServiceStack and clickInstall plugin
  4. Restart to load the installed ServiceStack IDEA plugin

Download and Install ServiceStack IDEA Manually

TheServiceStack AndroidStudio Plugin can also be downloaded directly from the JetBrains plugins website at:

After downloading the plugin above, install it in Android Studio by:

  1. Click onFile -> Settings in the Main Menu to open theSettings Dialog
  2. SelectPlugins settings screen
  3. Click onInstall plugin from disk... to open theFile Picker Dialog
  4. Browse and select the downloadedServiceStackIDEA.zip
  5. ClickOK then Restart Android Studio

See theServiceStack Eclipse Home Page for instructions on installing theServiceStackEclipse Plugin from the Eclipse MarketPlace and how to Add and Update ServiceStack References directly from within the Eclipse IDE.

Manually adding a dependency in Android Studio

Whilst the ServiceStack IDEA Plugin will automatically add the Gradle reference to your projectsbuild.gradle, you can also manually add the reference by adding thenet.servicestack:android dependency as seen below:

dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    compile 'net.servicestack:android:1.0.21'}

This also lets you to change which ServiceStack Client library version you want to use, the example above uses1.0.21.

If you've previously usedAdd ServiceStack Reference in any of the supported IDE's before, you'll be instantly familiar with Add ServiceStack Reference in Android Studio. The only additional field isPackage, required in order to comply with Java's class definition rules.

To add a ServiceStack Reference, right-click (or pressCtrl+Alt+Shift+R) on thePackage folder in your Java sources where you want to add the POJO DTO's. This will bring up theNew > Items Context Menu where you can click on theServiceStack Reference... Menu Item to open theAdd ServiceStack Reference Dialog:

Add ServiceStack Reference Java Context Menu

TheAdd ServiceStack Reference Dialog will be partially populated with the selectedPackage with the package where the Dialog was launched from and theFile Name defaulting todto.java where the Plain Old Java Object (POJO) DTO's will be added to. All that's missing is the url of the remote ServiceStack instance you wish to generate the DTO's for, e.g:http://techstacks.io:

ClickingOK will add thedto.java file to your project and modifies the current Project'sbuild.gradle file dependencies list with the newnet.servicestack:android dependency containing the Java JSON ServiceClients which is used together with the remote Servers DTO's to enable its typed Web Services API:

As the Module'sbuild.gradle file was modified you'll need to click on theSync Now link in the top yellow banner to sync thebuild.gradle changes which will install or remove any modified dependencies.

Update ServiceStack Reference

Like other Native Type languages, the generated DTO's can be further customized by modifying any of the options available in the header comments:

/* Options:Date: 2015-04-17 15:16:08Version: 1BaseUrl: http://techstacks.ioPackage: org.layoric.myapplicationGlobalNamespace: techstackdtos//AddPropertyAccessors: True//SettersReturnThis: True//AddServiceStackTypes: True//AddResponseStatus: False//AddImplicitVersion: //IncludeTypes: //ExcludeTypes: //DefaultImports: java.math.*,java.util.*,net.servicestack.client.*,com.google.gson.annotations.**/...

For example the package name can be changed by uncommenting thePackage: option with the new package name, then either right-click on the file to bring up the file context menu or use Android Studio'sAlt+Enter keyboard shortcut then click onUpdate ServiceStack Reference to update the DTO's with any modified options:

JsonServiceClient API

The goal of Native Types is to provide a productive end-to-end typed API to facilitate consuming remote services with minimal effort, friction and cognitive overhead. One way we achieve this is by promoting a consistent, forwards and backwards-compatible message-based API that's works conceptually similar on every platform where each language consumes remote services by sendingTyped DTO's using a reusableGeneric Service Client and a consistent client library API.

To maximize knowledge sharing between different platforms, the Java ServiceClient API is modelled after the.NET Service Clients API closely, as allowed within Java's language and idiomatic-style constraints.

Thanks to C#/.NET being heavily inspired by Java, the resulting JavaJsonServiceClient ends up bearing a close resemblance with .NET's Service Clients. The primary differences being due to language limitations like Java's generic type erasure and lack of language features like property initializers making Java slightly more verbose to work with, however asAdd ServiceStack Reference is able to take advantage of code-gen we're able to mitigate most of these limitations to retain a familiar developer UX.

TheServiceClient.java interface provides a good overview on the API available on the concreteJsonServiceClient class:

publicinterfaceServiceClient {booleangetAlwaysSendBasicAuthHeaders();voidsetAlwaysSendBasicAuthHeaders(booleanvalue);voidsetCredentials(StringuserName,Stringpassword);    <TResponse>TResponsesend(IReturn<TResponse>request);voidsend(IReturnVoidrequest);    <TResponse>TResponseget(IReturn<TResponse>request);voidget(IReturnVoidrequest);    <TResponse>TResponseget(IReturn<TResponse>request,Map<String,String>queryParams);    <TResponse>TResponseget(Stringpath,ClassresponseType);    <TResponse>TResponseget(Stringpath,TyperesponseType);HttpURLConnectionget(Stringpath);    <TResponse>TResponsepost(IReturn<TResponse>request);voidpost(IReturnVoidrequest);    <TResponse>TResponsepost(Stringpath,Objectrequest,ClassresponseType);    <TResponse>TResponsepost(Stringpath,Objectrequest,TyperesponseType);    <TResponse>TResponsepost(Stringpath,byte[]requestBody,StringcontentType,ClassresponseType);    <TResponse>TResponsepost(Stringpath,byte[]requestBody,StringcontentType,TyperesponseType);HttpURLConnectionpost(Stringpath,byte[]requestBody,StringcontentType);    <TResponse>TResponseput(IReturn<TResponse>request);voidput(IReturnVoidrequest);    <TResponse>TResponseput(Stringpath,Objectrequest,ClassresponseType);    <TResponse>TResponseput(Stringpath,Objectrequest,TyperesponseType);    <TResponse>TResponseput(Stringpath,byte[]requestBody,StringcontentType,ClassresponseType);    <TResponse>TResponseput(Stringpath,byte[]requestBody,StringcontentType,TyperesponseType);HttpURLConnectionput(Stringpath,byte[]requestBody,StringcontentType);    <TResponse>TResponsedelete(IReturn<TResponse>request);voiddelete(IReturnVoidrequest);    <TResponse>TResponsedelete(IReturn<TResponse>request,Map<String,String>queryParams);    <TResponse>TResponsedelete(Stringpath,ClassresponseType);    <TResponse>TResponsedelete(Stringpath,TyperesponseType);HttpURLConnectiondelete(Stringpath);}

The primary concession is due to Java's generic type erasure which forces the addition overloads that include aClass parameter for specifying the response type to deserialize into as well as aType parameter overload which does the same for generic types. These overloads aren't required for API's that accept a Request DTO annotated withIReturn<T> interface marker as we're able to encode the Response Type in code-generated Request DTO classes.

JsonServiceClient Usage

To get started you'll just need an instance ofJsonServiceClient initialized with theBaseUrl of the remote ServiceStack instance you want to access, e.g:

JsonServiceClientclient =newJsonServiceClient("http://techstacks.io");

The JsonServiceClient is made available after thenet.servicestack:android package is automatically added to yourbuild.gradle when adding a ServiceStack reference.

Typical usage of the Service Client is the same in .NET where you just need to send a populated Request DTO and the Service Client will return a populated Response DTO, e.g:

AppOverviewResponser =client.get(newAppOverview());ArrayList<Option>allTiers =r.getAllTiers();ArrayList<TechnologyInfo>topTech =r.getTopTechnologies();

As Java doesn't have type inference you'll need to specify the Type when declaring a variable. Whilst the public instance fields of the Request and Response DTO's are accessible directly, the convention in Java is to use theproperty getters and setters that are automatically generated for each DTO property as seen above.

Custom Example Usage

We'll now go through some of the other API's to give you a flavour of what's available. When preferred you can also consume Services using a custom route by supplying a string containing the route and/or Query String. As no type info is available you'll need to specify the Response DTO class to deserialize the response into, e.g:

OverviewResponseresponse =client.get("/overview",OverviewResponse.class);

The path can either be a relative or absolute url in which case theBaseUrl is ignored and the full absolute url is used instead, e.g:

OverviewResponseresponse =client.get("http://techstacks.io/overview",OverviewResponse.class);

When initializing the Request DTO you can take advantage of the generated setters which by default returnthis allowing them to be created and chained in a single expression, e.g:

GetTechnologyrequest =newGetTechnology().setSlug("servicestack");GetTechnologyResponseresponse =client.get(request);

AutoQuery Example Usage

You can also send requests composed of both a Typed DTO and untyped String Dictionary by providing a Java Map of additional args. This is typically used when queryingimplicit conventions in AutoQuery services, e.g:

QueryResponse<Technology>response =client.get(newFindTechnologies(),Utils.createMap("DescriptionContains","framework"));

TheUtils.createMap() API is included in theUtils.java static class which contains a number of helpers to simplify common usage patterns and reduce the amount of boiler plate required for common tasks, e.g they can also simplify reading raw bytes or raw String from a HTTP Response. Here's how you can download an image bytes using a customJsonServiceClient HTTP Request and load it into an Android ImageBitmap:

HttpURLConnectionhttpRes =client.get("https://servicestack.net/img/logo.png");byte[]imgBytes =Utils.readBytesToEnd(httpRes);Bitmapimg =BitmapFactory.decodeByteArray(imgBytes,0,imgBytes.length);

Integrated Basic Auth

HTTP Basic Auth is supported inJsonServiceClient following the implementation in .NET Service Clientwhere you can specify the users credentials and whether you always want to send Basic Auth with each request by:

client.setCredentials(userName,password);client.setAlwaysSendBasicAuthHeaders(true);TestAuthResponseresponse =client.get(newTestAuth());

It also supports processing challenged 401 Auth HTTP responses where it will transparently replay the failedrequest with the Basic Auth Headers:

client.setCredentials(userName,password);TestAuthResponseresponse =client.get(newTestAuth());

Although this has the additional latency of waiting for a failed 401 response before sending an authenticated request.

Cookies-enabled Service Client

TheJsonServiceClient initializes aCookieManager in its constructor to enable any Cookies received tobe added on subsequent requests to allow you to make authenticated requests after authenticating, e.g:

AuthenticateResponseauthResponse =client.post(newAuthenticate()    .setProvider("credentials")    .setUserName(userName)    .setPassword(password));TestAuthResponseresponse =client.get(newTestAuth());

AndroidServiceClient

Unlike .NET, Java doesn't have an established Async story or any language support that simplifies execution and composition of Async tasks, as a result the Async story on Android is fairly fragmented with multiple options built-in for executing non-blocking tasks on different threads including:

  • Thread
  • Executor
  • HandlerThread
  • AsyncTask
  • Service
  • IntentService
  • AsyncQueryHandler
  • Loader

JayWay's Oredev presentation onEfficient Android Threading provides a good overview of the different threading strategies above with their use-cases, features and pitfalls. Unfortunately none of the above options enable a Promise/Future-like API which would've been ideal in maintaining a consistent Task-based Async API across all ServiceStack Clients. Of all the above options the new AndroidAsyncTask ended up the most suitable option, requiring the least effort for the typical Service Client use-case of executing non-blocking WebService Requests and having their results called back on the Main UI thread.

AsyncResult

To enable an even simpler Async API decoupled from Android, we've introduced a higher-levelAsyncResult class which allows capturing of Async callbacks using an idiomatic anonymous Java class.AsyncResult is modelled afterjQuery.ajax and allows specifyingsuccess(),error() andcomplete() callbacks as needed.

AsyncServiceClient API

Using AsyncResult lets us define a pure JavaAsyncServiceClient interface that's decoupled from any specific threading implementation, i.e:

publicinterfaceAsyncServiceClient {public <T>voidgetAsync(IReturn<T>request,finalAsyncResult<T>asyncResult);public <T>voidgetAsync(IReturn<T>request,finalMap<String,String>queryParams,finalAsyncResult<T>asyncResult);public <T>voidgetAsync(Stringpath,finalClassresponseType,finalAsyncResult<T>asyncResult);public <T>voidgetAsync(Stringpath,finalTyperesponseType,finalAsyncResult<T>asyncResult);publicvoidgetAsync(Stringpath,finalAsyncResult<byte[]>asyncResult);public <T>voidpostAsync(IReturn<T>request,finalAsyncResult<T>asyncResult);public <T>voidpostAsync(Stringpath,finalObjectrequest,finalClassresponseType,finalAsyncResult<T>asyncResult);public <T>voidpostAsync(Stringpath,finalObjectrequest,finalTyperesponseType,finalAsyncResult<T>asyncResult);public <T>voidpostAsync(Stringpath,finalbyte[]requestBody,finalStringcontentType,finalClassresponseType,finalAsyncResult<T>asyncResult);public <T>voidpostAsync(Stringpath,finalbyte[]requestBody,finalStringcontentType,finalTyperesponseType,finalAsyncResult<T>asyncResult);publicvoidpostAsync(Stringpath,finalbyte[]requestBody,finalStringcontentType,finalAsyncResult<byte[]>asyncResult);public <T>voidputAsync(IReturn<T>request,finalAsyncResult<T>asyncResult);public <T>voidputAsync(Stringpath,finalObjectrequest,finalClassresponseType,finalAsyncResult<T>asyncResult);public <T>voidputAsync(Stringpath,finalObjectrequest,finalTyperesponseType,finalAsyncResult<T>asyncResult);public <T>voidputAsync(Stringpath,finalbyte[]requestBody,finalStringcontentType,finalClassresponseType,finalAsyncResult<T>asyncResult);public <T>voidputAsync(Stringpath,finalbyte[]requestBody,finalStringcontentType,finalTyperesponseType,finalAsyncResult<T>asyncResult);publicvoidputAsync(Stringpath,finalbyte[]requestBody,finalStringcontentType,finalAsyncResult<byte[]>asyncResult);public <T>voiddeleteAsync(IReturn<T>request,finalAsyncResult<T>asyncResult);public <T>voiddeleteAsync(IReturn<T>request,finalMap<String,String>queryParams,finalAsyncResult<T>asyncResult);public <T>voiddeleteAsync(Stringpath,finalClassresponseType,finalAsyncResult<T>asyncResult);public <T>voiddeleteAsync(Stringpath,finalTyperesponseType,finalAsyncResult<T>asyncResult);publicvoiddeleteAsync(Stringpath,finalAsyncResult<byte[]>asyncResult);}

TheAsyncServiceClient interface is implemented by theAndroidServiceClient concrete class which behind-the-scenes uses an AndroidAsyncTask to implement its Async API's.

Whilst theAndroidServiceClient is contained in thenet.servicestack:android dependency and only works in Android, theJsonServiceClient instead is contained in a seperate pure Javanet.servicestack:client dependency which can be used independently to provide a typed Java API for consuming ServiceStack Services from any Java application.

Async API Usage

To make use of Async API's in an Android App (which you'll want to do to keep web service requests off the Main UI thread), you'll instead need to use an instance ofAndroidServiceClient which as it inheritsJsonServiceClient can be used to perform both Sync and Async requests:

AndroidServiceClientclient =newAndroidServiceClient("http://techstacks.io");

Like other Service Clients, there's an equivalent Async API matching their Sync counterparts which differs by ending with anAsync suffix which instead of returning a typed response, fires asuccess(TResponse) orerror(Exception) callback with the typed response, e.g:

client.getAsync(newAppOverview(),newAsyncResult<AppOverviewResponse>(){@Overridepublicvoidsuccess(AppOverviewResponser) {ArrayList<Option>allTiers =r.getAllTiers();ArrayList<TechnologyInfo>topTech =r.getTopTechnologies();    }});

Which just like theJsonServiceClient examples above also provide a number of flexible options to execute Custom Async Web Service Requests, e.g:

client.getAsync("/overview",OverviewResponse.class,newAsyncResult<OverviewResponse>(){@Overridepublicvoidsuccess(OverviewResponseresponse) {    }});

Example calling a Web Service with an absolute url:

client.getAsync("http://techstacks.io/overview",OverviewResponse.class,newAsyncResult<OverviewResponse>() {@Overridepublicvoidsuccess(OverviewResponseresponse) {    }});

Async AutoQuery Example

Example calling an untyped AutoQuery Service with additional Dictionary String arguments:

client.getAsync(request,Utils.createMap("DescriptionContains","framework"),newAsyncResult<QueryResponse<Technology>>() {@Overridepublicvoidsuccess(QueryResponse<Technology>response) {        }    });

Download Raw Image Async Example

Example downloading raw Image bytes and loading it into an Android ImageBitmap:

client.getAsync("https://servicestack.net/img/logo.png",newAsyncResult<byte[]>() {@Overridepublicvoidsuccess(byte[]imgBytes) {Bitmapimg =BitmapFactory.decodeByteArray(imgBytes,0,imgBytes.length);    }});

Send Raw String or byte[] Requests

You can easily get the raw string Response from Request DTO's that return are annotated withIReturn<string>, e.g:

publicstaticclassHelloStringimplementsIReturn<String> { ... }Stringresponse =client.get(newHelloString().setName("World"));

You can also specify that you want the raw UTF-8byte[] orString response instead of a the deserialized Response DTO by specifyingthe Response class you want returned, e.g:

byte[]response =client.get("/hello?Name=World",byte[].class);

Java HTTP Marker Interfaces

Like the .NET and Swift Service Clients, the HTTP Interface markers are also annotated on Java DTO's and let you use the samesend API to send Requests via different HTTP Verbs, e.g:

publicstaticclassHelloByGetimplementsIReturn<HelloResponse>,IGet { ... }publicstaticclassHelloByPutimplementsIReturn<HelloResponse>,IPut { ... }HelloResponseresponse =client.send(newHelloByGet().setName("World"));//GETclient.sendAsync(newHelloByPut().setName("World"),//PUTnewAsyncResult<HelloResponse>() {@Overridepublicvoidsuccess(HelloResponseresponse) { }    });

IReturnVoid Support

New Sync/Async overloads have been added forIReturnVoid Request DTO's:

client.delete(newDeleteCustomer().setId(1));

Typed Error Handling

Thanks to Java also using typed Exceptions for error control flow, error handling in Java will be instantly familiar to C# devs which also throws a typedWebServiceException containing the remote servers structured error data:

ThrowTyperequest =newThrowType()    .setType("NotFound")    .setMessage("not here");try {ThrowTypeResponseresponse =testClient.post(request);}catch (WebServiceExceptionwebEx) {ResponseStatusstatus =webEx.getResponseStatus();status.getMessage();//= not herestatus.getStackTrace();//= (Server StackTrace)}

Likewise structured Validation Field Errors are also accessible from the familiarResponseStatus DTO, e.g:

ThrowValidationrequest =newThrowValidation()    .setEmail("invalidemail");try {client.post(request);}catch (WebServiceExceptionwebEx){ResponseStatusstatus =webEx.getResponseStatus();ResponseErrorfirstError =status.getErrors().get(0);firstError.getErrorCode();//= InclusiveBetweenfirstError.getMessage();//= 'Age' must be between 1 and 120. You entered 0.firstError.getFieldName();//= Age}

Async Error Handling

Async Error handling differs where in order to access theWebServiceException you'll need to implement theerror(Exception) callback, e.g:

client.postAsync(request,newAsyncResult<ThrowTypeResponse>() {@Overridepublicvoiderror(Exceptionex) {WebServiceExceptionwebEx = (WebServiceException)ex;ResponseStatusstatus =webEx.getResponseStatus();status.getMessage();//= not herestatus.getStackTrace();//= (Server StackTrace)    }});

Async Validation Errors are also handled in the same way:

client.postAsync(request,newAsyncResult<ThrowValidationResponse>() {@Overridepublicvoiderror(Exceptionex) {WebServiceExceptionwebEx = (WebServiceException)ex;ResponseStatusstatus =webEx.getResponseStatus();ResponseErrorfirstError =status.getErrors().get(0);firstError.getErrorCode();//= InclusiveBetweenfirstError.getMessage();//= 'Age' must be between 1 and 120. You entered 0.firstError.getFieldName();//= Age    }}

JsonServiceClient Error Handlers

To make it easier to generically handle Web Service Exceptions, the Java Service Clients also support static Global Exception handlers by assigningAndroidServiceClient.GlobalExceptionFilter, e.g:

AndroidServiceClient.GlobalExceptionFilter =newExceptionFilter() {@Overridepublicvoidexec(HttpURLConnectionres,Exceptionex) {//...    }};

As well as local Exception Filters by specifying a handler forclient.ExceptionFilter, e.g:

client.ExceptionFilter =newExceptionFilter() {@Overridepublicvoidexec(HttpURLConnectionres,Exceptionex) {//...    }};

Java generated DTO Types

Our goal withJava Add ServiceStack Reference is to ensure a high-fidelity, idiomatic translation within the constraints of Java language and its built-in libraries, where .NET Server DTO's are translated into clean, conventional Java POJO's where .NET built-in Value Types mapped to their equivalent Java data Type.

To see what this ends up looking up we'll go through some of theGenerated Test Services to see how they're translated in Java.

.NET Attributes translated into Java Annotations

By inspecting theHelloAllTypes Request DTO we can see that C# Metadata Attributes e.g.[Route("/all-types")] are also translated into the typed Java Annotations defined in thenet.servicestack:client dependency. But as Java only supports defining a single Annotation of the same type, any subsequent .NET Attributes of the same type are emitted in comments.

Terse, typed API's with IReturn interfaces

Java Request DTO's are also able to take advantage of theIReturn<TResponse> interface marker to provide its terse, typed generic API but due to Java's Type erasure the Response Type also needs to be encoded in the Request DTO as seen by theresponseType field andgetResponseType() getter:

@Route("/all-types")publicstaticclassHelloAllTypesimplementsIReturn<HelloAllTypesResponse>{publicStringname =null;publicAllTypesallTypes =null;publicStringgetName() {returnname; }publicHelloAllTypessetName(Stringvalue) {this.name =value;returnthis; }publicAllTypesgetAllTypes() {returnallTypes; }publicHelloAllTypessetAllTypes(AllTypesvalue) {this.allTypes =value;returnthis; }privatestaticObjectresponseType =HelloAllTypesResponse.class;publicObjectgetResponseType() {returnresponseType; }}

Getters and Setters generated for each property

Another noticeable feature is the Java getters and setters property convention are generated for each public field with setters returning itself allowing for multiple setters to be chained within a single expression.

To comply with Gson JSON Serialization rules, the public DTO fields are emitted in the same JSON naming convention as the remote ServiceStack server which for thetest.servicestack.net Web Services, follows itscamelCase naming convention that is configured in its AppHost with:

JsConfig.EmitCamelCaseNames=true;

Whilst the public fields match the remote server JSON naming convention, the getters and setters are always emitted in Java'scamelCase convention to maintain a consistent API irrespective of the remote server configuration. To minimize API breakage they should be the preferred method to access DTO fields.

Java Type Conversions

By inspecting theAllTypes DTO fields we can see what Java Type each built-in .NET Type gets translated into. In each case it selects the most suitable concrete Java datatype available, inc. generic collections. We also see only reference types are used (i.e. instead of their primitive types equivalents) since DTO properties are optional and need to be nullable.

publicstaticclassAllTypes{publicIntegerid =null;publicIntegernullableId =null;@SerializedName("byte")publicShortByte =null;@SerializedName("short")publicShortShort =null;@SerializedName("int")publicIntegerInt =null;@SerializedName("long")publicLongLong =null;publicIntegeruShort =null;publicLonguInt =null;publicBigIntegeruLong =null;@SerializedName("float")publicFloatFloat =null;@SerializedName("double")publicDoubleDouble =null;publicBigDecimaldecimal =null;publicStringstring =null;publicDatedateTime =null;publicTimeSpantimeSpan =null;publicDatedateTimeOffset =null;publicUUIDguid =null;@SerializedName("char")publicStringChar =null;publicDatenullableDateTime =null;publicTimeSpannullableTimeSpan =null;publicArrayList<String>stringList =null;publicArrayList<String>stringArray =null;publicHashMap<String,String>stringMap =null;publicHashMap<Integer,String>intStringMap =null;publicSubTypesubType =null;    ...}

The only built-in Value Type that didn't have a suitable built-in Java equivalent wasTimeSpan. In this case it uses our newTimeSpan.java class which implements the same familiar API available in .NET'sTimeSpan.

Something else you'll notice is that some fields are annotated with the@SerializedName() Gson annotation. This is automatically added for Java keywords - required since Java doesn't provide anyway to escape keyword identifiers. The first time a Gson annotation is referenced it also automatically includes the required Gson namespace imports. If needed, this can also be explicitly added by with:

JavaGenerator.AddGsonImport =true;

Java Enums

.NET enums are also translated into typed Java enums where basic enums end up as a straightforward translation, e.g:

publicstaticenumBasicEnum{Foo,Bar,Baz;}

Whilst as Java doesn't support integer Enum flags directly the resulting translation ends up being a bit more convoluted:

@Flags()publicstaticenumEnumFlags{@SerializedName("1")Value1(1),@SerializedName("2")Value2(2),@SerializedName("4")Value3(4);privatefinalintvalue;EnumFlags(finalintintValue) {value =intValue; }publicintgetValue() {returnvalue; }}

The Core Java Functional Utils required to runC#'s 101 LINQ Samples in Javaare included in thenet.servicestack:client Java package which as its compatible with Java 1.7,also runs on Android:

Whilst noticeably more verbose than most languages, it enables a functional style of programming that providesan alternative to imperative programming with mutating collections and eases porting efforts of functional codewhich can be mapped to its equivalent core functional method.

Java Configuration

The header comments in the generated DTO's allows for further customization of how the DTO's are generated which can then be updated with any custom Options provided using theUpdate ServiceStack Reference Menu Item in Android Studio. Options that are preceded by a single line Java comment// are defaults from the server which can be overridden.

To override a value, remove the// and specify the value to the right of the:. Any value uncommented will be sent to the server to override any server defaults.

/* Options:Date: 2015-04-10 12:41:14Version: 1BaseUrl: http://techstacks.ioPackage: net.servicestack.techstacks//GlobalNamespace: dto//AddPropertyAccessors: True//SettersReturnThis: True//AddServiceStackTypes: True//AddResponseStatus: False//AddImplicitVersion://IncludeTypes://ExcludeTypes://DefaultImports: java.math.*,java.util.*,net.servicestack.client.*,com.google.gson.annotations.**/

We'll go through and cover each of the above options to see how they affect the generated DTO's:

Package

Specify the package name that the generated DTO's are in:

Package: net.servicestack.techstacks

Will generate the package name for the generated DTO's as:

packagenet.servicestack.techstacks;

GlobalNamespace

Change the name of the top-level Java class container that all static POJO classes are generated in, e.g changing theGlobalNamespace to:

GlobalNamespace: techstacksdto

Will change the name of the top-level class totechstacksdto, e.g:

publicclasstechstacksdto{    ...}

Where all static DTO classes can be imported using the wildcard import below:

importnet.servicestack.techstacksdto.*;

AddPropertyAccessors

By defaultgetters andsetters are generated for each DTO property, you can prevent this default with:

AddPropertyAccessors: false

Which will no longer generate any property accessors, leaving just public fields, e.g:

publicstaticclassAppOverviewResponse{publicDateCreated =null;publicArrayList<Option>AllTiers =null;publicArrayList<TechnologyInfo>TopTechnologies =null;publicResponseStatusResponseStatus =null;}

SettersReturnThis

To allow for chaining DTO fieldsetters returns itself by default, this can be changed to returnvoid with:

SettersReturnThis: false

Which will change the return type of each setter tovoid:

publicstaticclassGetTechnologyimplementsIReturn<GetTechnologyResponse>{publicStringSlug =null;publicStringgetSlug() {returnSlug; }publicvoidsetSlug(Stringvalue) {this.Slug =value; }}

AddServiceStackTypes

Lets you exclude built-in ServiceStack Types and DTO's from being generated with:

AddServiceStackTypes: false

This will prevent Request DTO's for built-in ServiceStack Services likeAuthenticate from being emitted.

AddImplicitVersion

Lets you specify the Version number to be automatically populated in all Request DTO's sent from the client:

AddImplicitVersion: 1

Which will embed the specified Version number in each Request DTO, e.g:

publicstaticclassGetTechnologyimplementsIReturn<GetTechnologyResponse>{publicIntegerVersion =1;publicIntegergetVersion() {returnVersion; }publicGetTechnologysetVersion(Integervalue) {this.Version =value;returnthis; }}

This lets you know what Version of the Service Contract that existing clients are using making it easy to implementServiceStack's recommended versioning strategy.

IncludeTypes

Is used as a Whitelist that can be used to specify only the types you would like to have code-generated:

/* Options:IncludeTypes: GetTechnology,GetTechnologyResponse

Will only generateGetTechnology andGetTechnologyResponse DTO's, e.g:

publicclassdto{publicstaticclassGetTechnologyResponse { ... }publicstaticclassGetTechnologyimplementsIReturn<GetTechnologyResponse> { ... }}

ExcludeTypes

Is used as a Blacklist where you can specify which types you would like to exclude from being generated:

/* Options:ExcludeTypes: GetTechnology,GetTechnologyResponse

Will excludeGetTechnology andGetTechnologyResponse DTO's from being generated.

DefaultImports

Lets you override the default import packages included in the generated DTO's:

java.math.*,java.util.*,net.servicestack.client.*,com.acme.custom.*

Will override the default imports with the ones specified, i.e:

importjava.math.*;importjava.util.*;importnet.servicestack.client.*;importcom.acme.custom.*;

By default the generated DTO's do not require any Google's Gson-specific serialization hints, but when they're needed e.g. if your DTO's use Java keywords or are attributed with[DataMember(Name=...)] the required Gson imports are automatically added which can also be added explicitly with:

JavaGenerator.AddGsonImport=true;

Which will add the following Gson imports:

importcom.google.gson.annotations.*;importcom.google.gson.reflect.*;

TreatTypesAsStrings

Due to theunusual encoding of Guid bytes it may be instead bepreferential to treat Guids as opaque strings so they are easier to compare back to their original C# Guids.This can be enabled with the newTreatTypesAsStrings option:

/* Options:...TreatTypesAsStrings: Guid*/

To demonstrate Java Native Types in action we've ported the SwiftTechStacks iOS App to a native Java Android App to showcase the responsiveness and easy-of-use of leveraging Java Add ServiceStack Reference in Android Projects.

Checkout theTechStacks Android App repository for a nice overview of how it leverages Java Native Types, Functional Java Utils and iOS-inspired Data Binding to easily develop services-heavy Mobile Apps.



  1. Getting Started

    1. Creating your first project
    2. Create Service from scratch
    3. Your first webservice explained
    4. Example Projects Overview
    5. Learning Resources
  2. Designing APIs

    1. ServiceStack API Design
    2. Designing a REST-ful service with ServiceStack
    3. Simple Customer REST Example
    4. How to design a Message-Based API
    5. Software complexity and role of DTOs
  3. Reference

    1. Order of Operations
    2. The IoC container
    3. Configuration and AppSettings
    4. Metadata page
    5. Rest, SOAP & default endpoints
    6. SOAP support
    7. Routing
    8. Service return types
    9. Customize HTTP Responses
    10. Customize JSON Responses
    11. Plugins
    12. Validation
    13. Error Handling
    14. Security
    15. Debugging
    16. JavaScript Client Library (ss-utils.js)
  4. Clients

    1. Overview
    2. C#/.NET client
      1. .NET Core Clients
    3. Add ServiceStack Reference
      1. C# Add Reference
      2. F# Add Reference
      3. VB.NET Add Reference
      4. Swift Add Reference
      5. Java Add Reference
    4. Silverlight client
    5. JavaScript client
      1. Add TypeScript Reference
    6. Dart Client
    7. MQ Clients
  5. Formats

    1. Overview
    2. JSON/JSV and XML
    3. HTML5 Report Format
    4. CSV Format
    5. MessagePack Format
    6. ProtoBuf Format
  6. View Engines4.Razor & Markdown Razor

    1. Markdown Razor
  7. Hosts

    1. IIS
    2. Self-hosting
    3. Messaging
    4. Mono
  8. Security

    1. Authentication
    2. Sessions
    3. Restricting Services
    4. Encrypted Messaging
  9. Advanced

    1. Configuration options
    2. Access HTTP specific features in services
    3. Logging
    4. Serialization/deserialization
    5. Request/response filters
    6. Filter attributes
    7. Concurrency Model
    8. Built-in profiling
    9. Form Hijacking Prevention
    10. Auto-Mapping
    11. HTTP Utils
    12. Dump Utils
    13. Virtual File System
    14. Config API
    15. Physical Project Structure
    16. Modularizing Services
    17. MVC Integration
    18. ServiceStack Integration
    19. Embedded Native Desktop Apps
    20. Auto Batched Requests
    21. Versioning
    22. Multitenancy
  10. Caching

  11. Caching Providers

  12. HTTP Caching1.CacheResponse Attribute2.Cache Aware Clients

  13. Auto Query

  14. Overview

  15. Why Not OData

  16. AutoQuery RDBMS

  17. AutoQuery Data1.AutoQuery Memory2.AutoQuery Service3.AutoQuery DynamoDB

  18. Server Events

    1. Overview
    2. JavaScript Client
    3. C# Server Events Client
    4. Redis Server Events
  19. Service Gateway

    1. Overview
    2. Service Discovery
  20. Encrypted Messaging

    1. Overview
    2. Encrypted Client
  21. Plugins

    1. Auto Query
    2. Server Sent Events
    3. Swagger API
    4. Postman
    5. Request logger
    6. Sitemaps
    7. Cancellable Requests
    8. CorsFeature
  22. Tests

    1. Testing
    2. HowTo write unit/integration tests
  23. ServiceStackVS

    1. Install ServiceStackVS
    2. Add ServiceStack Reference
    3. TypeScript React Template
    4. React, Redux Chat App
    5. AngularJS App Template
    6. React Desktop Apps
  24. Other Languages

    1. FSharp
      1. Add ServiceStack Reference
    2. VB.NET
      1. Add ServiceStack Reference
    3. Swift
    4. Swift Add Reference
    5. Java
      1. Add ServiceStack Reference
      2. Android Studio & IntelliJ
      3. Eclipse
  25. Amazon Web Services

  26. ServiceStack.Aws

  27. PocoDynamo

  28. AWS Live Demos

  29. Getting Started with AWS

  30. Deployment

    1. Deploy Multiple Sites to single AWS Instance
      1. Simple Deployments to AWS with WebDeploy
    2. Advanced Deployments with OctopusDeploy
  31. Install 3rd Party Products

    1. Redis on Windows
    2. RabbitMQ on Windows
  32. Use Cases

    1. Single Page Apps
    2. HTML, CSS and JS Minifiers
    3. Azure
    4. Connecting to Azure Redis via SSL
    5. Logging
    6. Bundling and Minification
    7. NHibernate
  33. Performance

    1. Real world performance
  34. Other Products

    1. ServiceStack.Redis
    2. ServiceStack.OrmLite
    3. ServiceStack.Text
  35. Future

    1. Roadmap

Clone this wiki locally


[8]ページ先頭

©2009-2025 Movatter.jp