- Notifications
You must be signed in to change notification settings - Fork1.6k
Java Add ServiceStack Reference
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.
The ServiceStack IDEA is now available to install directly from within IntelliJ or Android Studio IDE Plugins Repository, to Install Go to:
File -> Settings...Main Menu Item- SelectPlugins on left menu then clickBrowse repositories... at bottom
- Search forServiceStack and clickInstall plugin
- Restart to load the installed ServiceStack IDEA plugin

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:
- Click on
File -> Settingsin the Main Menu to open theSettings Dialog - SelectPlugins settings screen
- Click onInstall plugin from disk... to open theFile Picker Dialog
- Browse and select the downloadedServiceStackIDEA.zip
- 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.
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:

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.
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:

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.
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.
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);
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);
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.
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());
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.
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.
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.
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) { }});
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) { } });
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); }});
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);
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) { } });
New Sync/Async overloads have been added forIReturnVoid Request DTO's:
client.delete(newDeleteCustomer().setId(1));
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 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 }}
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) {//... }};
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.
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.
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; }}
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.
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;
.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.
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:
Specify the package name that the generated DTO's are in:
Package: net.servicestack.techstacksWill generate the package name for the generated DTO's as:
packagenet.servicestack.techstacks;
Change the name of the top-level Java class container that all static POJO classes are generated in, e.g changing theGlobalNamespace to:
GlobalNamespace: techstacksdtoWill 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.*;
By defaultgetters andsetters are generated for each DTO property, you can prevent this default with:
AddPropertyAccessors: falseWhich 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;}
To allow for chaining DTO fieldsetters returns itself by default, this can be changed to returnvoid with:
SettersReturnThis: falseWhich will change the return type of each setter tovoid:
publicstaticclassGetTechnologyimplementsIReturn<GetTechnologyResponse>{publicStringSlug =null;publicStringgetSlug() {returnSlug; }publicvoidsetSlug(Stringvalue) {this.Slug =value; }}
Lets you exclude built-in ServiceStack Types and DTO's from being generated with:
AddServiceStackTypes: falseThis will prevent Request DTO's for built-in ServiceStack Services likeAuthenticate from being emitted.
Lets you specify the Version number to be automatically populated in all Request DTO's sent from the client:
AddImplicitVersion: 1Which 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.
Is used as a Whitelist that can be used to specify only the types you would like to have code-generated:
/* Options:IncludeTypes: GetTechnology,GetTechnologyResponseWill only generateGetTechnology andGetTechnologyResponse DTO's, e.g:
publicclassdto{publicstaticclassGetTechnologyResponse { ... }publicstaticclassGetTechnologyimplementsIReturn<GetTechnologyResponse> { ... }}
Is used as a Blacklist where you can specify which types you would like to exclude from being generated:
/* Options:ExcludeTypes: GetTechnology,GetTechnologyResponseWill excludeGetTechnology andGetTechnologyResponse DTO's from being generated.
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.*;
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*/ExampleTechStacks Android App
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.
- Why ServiceStack?
- Important role of DTOs
- What is a message based web service?
- Advantages of message based web services
- Why remote services should use separate DTOs
Getting Started
Designing APIs
Reference
Clients
Formats
View Engines4.Razor & Markdown Razor
Hosts
Security
Advanced
- Configuration options
- Access HTTP specific features in services
- Logging
- Serialization/deserialization
- Request/response filters
- Filter attributes
- Concurrency Model
- Built-in profiling
- Form Hijacking Prevention
- Auto-Mapping
- HTTP Utils
- Dump Utils
- Virtual File System
- Config API
- Physical Project Structure
- Modularizing Services
- MVC Integration
- ServiceStack Integration
- Embedded Native Desktop Apps
- Auto Batched Requests
- Versioning
- Multitenancy
Caching
Auto Query
AutoQuery Data1.AutoQuery Memory2.AutoQuery Service3.AutoQuery DynamoDB
Server Events
Service Gateway
Encrypted Messaging
Plugins
Tests
ServiceStackVS
Other Languages
Amazon Web Services
Deployment
Install 3rd Party Products
Use Cases
Performance
Other Products
Future



