[Java][PlayFramework] Added some CLI Options + many fixes (#5180)

* First commit of the Java Play Framework server generator. It is highly based on Spring so there might me a couple of things that don't make sense (like options or parameters) for the Play Framework.

* Fix suggestions in the PR discussion + add .bat and .sh file as requested.

* Updated Readme.md file

* Remove unused mustache file + fix baseName vs paramName in all the mustache files.

* Fix the compilation error when we have a body which is a list or map. Doesn't fix the problem with the annotation itself.

* Fix the problem with the Http.MultipartFormData.FilePart

* - Add "wrapCalls" and "useSwaggerUI" CLI Options and updated what handleException does to follow Play Framework lifecycle more closely
- Updated all mustache files accordingly
- Updated the sample
- Updates Play Framework version to the latest 2.5.13
This commit is contained in:
Jean-François Côté 2017-03-25 02:36:01 -04:00 committed by wing328
parent 65b6660c55
commit 282b22744c
25 changed files with 230 additions and 94 deletions

View File

@ -19,6 +19,8 @@ public class JavaPlayFrameworkCodegen extends AbstractJavaCodegen implements Bea
public static final String CONTROLLER_ONLY = "controllerOnly";
public static final String USE_INTERFACES = "useInterfaces";
public static final String HANDLE_EXCEPTIONS = "handleExceptions";
public static final String WRAP_CALLS = "wrapCalls";
public static final String USE_SWAGGER_UI = "useSwaggerUI";
protected String title = "swagger-petstore";
protected String configPackage = "io.swagger.configuration";
@ -27,6 +29,8 @@ public class JavaPlayFrameworkCodegen extends AbstractJavaCodegen implements Bea
protected boolean useInterfaces = true;
protected boolean useBeanValidation = true;
protected boolean handleExceptions = true;
protected boolean wrapCalls = true;
protected boolean useSwaggerUI = true;
public JavaPlayFrameworkCodegen() {
super();
@ -56,7 +60,9 @@ public class JavaPlayFrameworkCodegen extends AbstractJavaCodegen implements Bea
cliOptions.add(createBooleanCliWithDefault(CONTROLLER_ONLY, "Whether to generate only API interface stubs without the server files.", controllerOnly));
cliOptions.add(createBooleanCliWithDefault(USE_BEANVALIDATION, "Use BeanValidation API annotations", useBeanValidation));
cliOptions.add(createBooleanCliWithDefault(USE_INTERFACES, "Makes the controllerImp implements an interface to facilitate automatic completion when updating from version x to y of your spec", useInterfaces));
cliOptions.add(createBooleanCliWithDefault(HANDLE_EXCEPTIONS, "Add a wrapper to each controller to handle exceptions that pop in the controller", handleExceptions));
cliOptions.add(createBooleanCliWithDefault(HANDLE_EXCEPTIONS, "Add a 'throw exception' to each controller function. Add also a custom error handler where you can put your custom logic", handleExceptions));
cliOptions.add(createBooleanCliWithDefault(WRAP_CALLS, "Add a wrapper to each controller function to handle things like metrics, response modification, etc..", wrapCalls));
cliOptions.add(createBooleanCliWithDefault(USE_SWAGGER_UI, "Add a route to /api which show your documentation in swagger-ui. Will also import needed dependencies", useSwaggerUI));
}
@Override
@ -120,6 +126,18 @@ public class JavaPlayFrameworkCodegen extends AbstractJavaCodegen implements Bea
writePropertyBack(HANDLE_EXCEPTIONS, handleExceptions);
}
if (additionalProperties.containsKey(WRAP_CALLS)) {
this.setWrapCalls(convertPropertyToBoolean(WRAP_CALLS));
} else {
writePropertyBack(WRAP_CALLS, wrapCalls);
}
if (additionalProperties.containsKey(USE_SWAGGER_UI)) {
this.setUseSwaggerUI(convertPropertyToBoolean(USE_SWAGGER_UI));
} else {
writePropertyBack(USE_SWAGGER_UI, useSwaggerUI);
}
//We don't use annotation anymore
importMapping.remove("ApiModelProperty");
importMapping.remove("ApiModel");
@ -128,7 +146,6 @@ public class JavaPlayFrameworkCodegen extends AbstractJavaCodegen implements Bea
supportingFiles.add(new SupportingFile("README.mustache", "", "README"));
supportingFiles.add(new SupportingFile("LICENSE.mustache", "", "LICENSE"));
supportingFiles.add(new SupportingFile("build.mustache", "", "build.sbt"));
supportingFiles.add(new SupportingFile("swagger.mustache", "public", "swagger.json"));
//Project folder
supportingFiles.add(new SupportingFile("buildproperties.mustache", "project", "build.properties"));
@ -142,11 +159,18 @@ public class JavaPlayFrameworkCodegen extends AbstractJavaCodegen implements Bea
//App/Utils folder
supportingFiles.add(new SupportingFile("swaggerUtils.mustache", "app/swagger", "SwaggerUtils.java"));
if (this.handleExceptions) {
supportingFiles.add(new SupportingFile("errorHandler.mustache", "app/swagger", "ErrorHandler.java"));
}
if(this.wrapCalls) {
supportingFiles.add(new SupportingFile("apiCall.mustache", "app/swagger", "ApiCall.java"));
}
//App/Controllers
supportingFiles.add(new SupportingFile("apiDocController.mustache", "app/controllers", "ApiDocController.java"));
if(this.useSwaggerUI) {
//App/Controllers
supportingFiles.add(new SupportingFile("swagger.mustache", "public", "swagger.json"));
supportingFiles.add(new SupportingFile("apiDocController.mustache", "app/controllers", "ApiDocController.java"));
}
//We remove the default api.mustache that is used
apiTemplateFiles.remove("api.mustache");
@ -210,6 +234,14 @@ public class JavaPlayFrameworkCodegen extends AbstractJavaCodegen implements Bea
this.handleExceptions = handleExceptions;
}
public void setWrapCalls(boolean wrapCalls) {
this.wrapCalls = wrapCalls;
}
public void setUseSwaggerUI(boolean useSwaggerUI) {
this.useSwaggerUI = useSwaggerUI;
}
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");

View File

@ -13,18 +13,15 @@ public class ApiCall extends Action<SwaggerUtils.ApiAction> {
@Inject
private ApiCall() {}
public CompletionStage <Result> call(Http.Context ctx) {
public CompletionStage<Result> call(Http.Context ctx) {
try {
//TODO: Do stuff you want to handle with each API call (metrics, logging, etc..)
return delegate.call(ctx);
} catch (Throwable t) {
//TODO: handle error the way you want
return CompletableFuture.completedFuture(handleExceptions(t));
//TODO: log the error in your metric
//We rethrow this error so it will be caught in the ErrorHandler
throw t;
}
}
private Result handleExceptions(Throwable t) {
//TODO: Handle exception that need special response (return a special apimodel, etc..)
return ok();
}
}

View File

@ -15,6 +15,10 @@
# HOCON will fall back to substituting environment variable:
#mykey = ${JAVA_HOME}
{{#handleExceptions}}
play.http.errorHandler="swagger.ErrorHandler"
{{/handleExceptions}}
## Akka
# https://www.playframework.com/documentation/latest/ScalaAkka#Configuration
# https://www.playframework.com/documentation/latest/JavaAkka#Configuration
@ -35,8 +39,6 @@ akka {
#log-config-on-start = true
}
api.version="1.0"
## Secret key
# http://www.playframework.com/documentation/latest/ApplicationSecret
# ~~~~~

View File

@ -9,8 +9,8 @@ scalaVersion := "2.11.7"
libraryDependencies ++= Seq(
javaJdbc,
cache,
javaWs,
"org.webjars" % "swagger-ui" % "2.2.10-1"{{#useBeanValidation}},
javaWs{{#useSwaggerUI}},
"org.webjars" % "swagger-ui" % "2.2.10-1"{{/useSwaggerUI}}{{#useBeanValidation}},
"javax.validation" % "validation-api" % "1.1.0.Final"
{{/useBeanValidation}}
)

View File

@ -0,0 +1,49 @@
package swagger;
import play.*;
import play.api.OptionalSourceMapper;
import play.api.UsefulException;
import play.api.routing.Router;
import play.http.DefaultHttpErrorHandler;
import play.mvc.Http.*;
import play.mvc.*;
import javax.inject.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import static play.mvc.Results.*;
@Singleton
public class ErrorHandler extends DefaultHttpErrorHandler {
@Inject
public ErrorHandler(Configuration configuration, Environment environment, OptionalSourceMapper sourceMapper, Provider<Router> routes) {
super(configuration, environment, sourceMapper, routes);
}
@Override
protected CompletionStage<Result> onDevServerError(RequestHeader request, UsefulException exception) {
return CompletableFuture.completedFuture(
handleExceptions(exception)
);
}
@Override
protected CompletionStage<Result> onProdServerError(RequestHeader request, UsefulException exception) {
return CompletableFuture.completedFuture(
handleExceptions(exception)
);
}
@Override
protected void logServerError(RequestHeader request, UsefulException usefulException) {
//Since the error is already handled, we don't want to print anything on the console
//But if you want to have the error printed in the console, just delete this override
}
private Result handleExceptions(Throwable t) {
//TODO: Handle exception that need special response (return a special apimodel, notFound(), etc..)
return ok();
}
}

View File

@ -14,7 +14,7 @@ import javax.validation.constraints.*;
{{#operations}}
public class {{classname}}ControllerImp {{#useInterfaces}}implements {{classname}}ControllerImpInterface{{/useInterfaces}} {
{{#operation}}
public {{>returnTypes}} {{operationId}}({{#allParams}}{{>pathParams}}{{>queryParams}}{{>bodyParams}}{{>formParams}}{{>headerParams}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {
public {{>returnTypes}} {{operationId}}({{#allParams}}{{>pathParams}}{{>queryParams}}{{>bodyParams}}{{>formParams}}{{>headerParams}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {{#handleExceptions}}throws Exception{{/handleExceptions}} {
//Do your magic!!!
{{#returnType}}return new {{>returnTypesNoVoidNoAbstract}}();{{/returnType}}
}

View File

@ -19,9 +19,9 @@ import com.fasterxml.jackson.core.type.TypeReference;
import javax.validation.constraints.*;
{{/useBeanValidation}}
{{#handleExceptions}}
{{#wrapCalls}}
import swagger.SwaggerUtils.ApiAction;
{{/handleExceptions}}
{{/wrapCalls}}
{{>generatedAnnotation}}
{{#operations}}
@ -38,8 +38,8 @@ public class {{classname}}Controller extends Controller {
{{#operation}}
{{#handleExceptions}}@ApiAction{{/handleExceptions}}
public Result {{operationId}}({{#pathParams}}{{>pathParams}}{{#hasMore}},{{/hasMore}}{{/pathParams}}) {{#bodyParams}}throws IOException{{/bodyParams}} {
{{#wrapCalls}}@ApiAction{{/wrapCalls}}
public Result {{operationId}}({{#pathParams}}{{>pathParams}}{{#hasMore}},{{/hasMore}}{{/pathParams}}) {{^handleExceptions}}{{#bodyParams}}throws IOException{{/bodyParams}}{{/handleExceptions}}{{#handleExceptions}}throws Exception{{/handleExceptions}} {
{{#bodyParams}}
{{#collectionFormat}}
//TODO: Maybe implement this in the future if we can support collection in the body params: see bug in swagger-play: https://github.com/swagger-api/swagger-play/issues/130

View File

@ -15,7 +15,7 @@ import javax.validation.constraints.*;
{{#operations}}
public interface {{classname}}ControllerImpInterface {
{{#operation}}
{{>returnTypes}} {{operationId}}({{#allParams}}{{>pathParams}}{{>queryParams}}{{>bodyParams}}{{>formParams}}{{>headerParams}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{>returnTypes}} {{operationId}}({{#allParams}}{{>pathParams}}{{>queryParams}}{{>bodyParams}}{{>formParams}}{{>headerParams}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {{#handleExceptions}}throws Exception{{/handleExceptions}};
{{/operation}}
}

View File

@ -1,2 +1,2 @@
// The Play plugin
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.10")
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.13")

View File

@ -2,7 +2,9 @@
# This file defines all application routes (Higher priority routes first)
# ~~~~
{{#useSwaggerUI}}
GET /api controllers.ApiDocController.api
{{/useSwaggerUI}}
{{#apiInfo}}
{{#apis}}

View File

@ -61,6 +61,10 @@ public class JavaPlayFrameworkOptionsTest extends JavaClientOptionsTest {
times = 1;
clientCodegen.setHandleExceptions(Boolean.valueOf(JavaPlayFrameworkOptionsProvider.HANDLE_EXCEPTIONS));
times = 1;
clientCodegen.setWrapCalls(Boolean.valueOf(JavaPlayFrameworkOptionsProvider.WRAP_CALLS));
times = 1;
clientCodegen.setUseSwaggerUI(Boolean.valueOf(JavaPlayFrameworkOptionsProvider.USE_SWAGGER_UI));
times = 1;
}};
}
}

View File

@ -13,6 +13,8 @@ public class JavaPlayFrameworkOptionsProvider extends JavaOptionsProvider {
public static final String USE_BEANVALIDATION = "true";
public static final String USE_INTERFACES = "true";
public static final String HANDLE_EXCEPTIONS = "true";
public static final String WRAP_CALLS = "true";
public static final String USE_SWAGGER_UI = "true";
@Override
public String getLanguage() {
@ -29,6 +31,8 @@ public class JavaPlayFrameworkOptionsProvider extends JavaOptionsProvider {
options.put(JavaPlayFrameworkCodegen.USE_BEANVALIDATION, USE_BEANVALIDATION);
options.put(JavaPlayFrameworkCodegen.USE_INTERFACES, USE_INTERFACES);
options.put(JavaPlayFrameworkCodegen.HANDLE_EXCEPTIONS, HANDLE_EXCEPTIONS);
options.put(JavaPlayFrameworkCodegen.WRAP_CALLS, WRAP_CALLS);
options.put(JavaPlayFrameworkCodegen.USE_SWAGGER_UI, USE_SWAGGER_UI);
return options;
}

View File

@ -33,7 +33,7 @@ public class PetApiController extends Controller {
@ApiAction
public Result addPet() throws IOException {
public Result addPet() throws Exception {
JsonNode nodebody = request().body().asJson();
Pet body;
if (nodebody != null) {
@ -48,7 +48,7 @@ public class PetApiController extends Controller {
}
@ApiAction
public Result deletePet(Long petId) {
public Result deletePet(Long petId) throws Exception {
String valueapiKey = request().getHeader("api_key");
String apiKey;
if (valueapiKey != null) {
@ -63,7 +63,7 @@ public class PetApiController extends Controller {
}
@ApiAction
public Result findPetsByStatus() {
public Result findPetsByStatus() throws Exception {
//TODO: Maybe implement this in the future if we can support collection in the body params: see bug in swagger-play: https://github.com/swagger-api/swagger-play/issues/130
//TODO: Tt seems it is not detected that it's a list based on the collectionFormat field?
//WIP when both bugs will be fixed
@ -79,7 +79,7 @@ public class PetApiController extends Controller {
}
@ApiAction
public Result findPetsByTags() {
public Result findPetsByTags() throws Exception {
//TODO: Maybe implement this in the future if we can support collection in the body params: see bug in swagger-play: https://github.com/swagger-api/swagger-play/issues/130
//TODO: Tt seems it is not detected that it's a list based on the collectionFormat field?
//WIP when both bugs will be fixed
@ -95,7 +95,7 @@ public class PetApiController extends Controller {
}
@ApiAction
public Result getPetById(Long petId) {
public Result getPetById(Long petId) throws Exception {
Pet obj = imp.getPetById(petId);
JsonNode result = mapper.valueToTree(obj);
return ok(result);
@ -103,7 +103,7 @@ public class PetApiController extends Controller {
}
@ApiAction
public Result updatePet() throws IOException {
public Result updatePet() throws Exception {
JsonNode nodebody = request().body().asJson();
Pet body;
if (nodebody != null) {
@ -118,7 +118,7 @@ public class PetApiController extends Controller {
}
@ApiAction
public Result updatePetWithForm(String petId) {
public Result updatePetWithForm(String petId) throws Exception {
String valuename = ((String[]) request().body().asMultipartFormData().asFormUrlEncoded().get("name"))[0];
String name;
if (valuename != null) {
@ -141,7 +141,7 @@ public class PetApiController extends Controller {
}
@ApiAction
public Result uploadFile(Long petId) {
public Result uploadFile(Long petId) throws Exception {
String valueadditionalMetadata = ((String[]) request().body().asMultipartFormData().asFormUrlEncoded().get("additionalMetadata"))[0];
String additionalMetadata;
if (valueadditionalMetadata != null) {

View File

@ -10,42 +10,42 @@ import java.util.HashMap;
import javax.validation.constraints.*;
public class PetApiControllerImp implements PetApiControllerImpInterface {
public void addPet(Pet body) {
public void addPet(Pet body) throws Exception {
//Do your magic!!!
}
public void deletePet(Long petId, String apiKey) {
public void deletePet(Long petId, String apiKey) throws Exception {
//Do your magic!!!
}
public List<Pet> findPetsByStatus( List<String> status) {
public List<Pet> findPetsByStatus( List<String> status) throws Exception {
//Do your magic!!!
return new ArrayList<Pet>();
}
public List<Pet> findPetsByTags( List<String> tags) {
public List<Pet> findPetsByTags( List<String> tags) throws Exception {
//Do your magic!!!
return new ArrayList<Pet>();
}
public Pet getPetById(Long petId) {
public Pet getPetById(Long petId) throws Exception {
//Do your magic!!!
return new Pet();
}
public void updatePet(Pet body) {
public void updatePet(Pet body) throws Exception {
//Do your magic!!!
}
public void updatePetWithForm(String petId, String name, String status) {
public void updatePetWithForm(String petId, String name, String status) throws Exception {
//Do your magic!!!
}
public void uploadFile(Long petId, String additionalMetadata, Http.MultipartFormData.FilePart file) {
public void uploadFile(Long petId, String additionalMetadata, Http.MultipartFormData.FilePart file) throws Exception {
//Do your magic!!!
}

View File

@ -11,20 +11,20 @@ import java.util.HashMap;
import javax.validation.constraints.*;
public interface PetApiControllerImpInterface {
void addPet(Pet body);
void addPet(Pet body) throws Exception;
void deletePet(Long petId, String apiKey);
void deletePet(Long petId, String apiKey) throws Exception;
List<Pet> findPetsByStatus( List<String> status);
List<Pet> findPetsByStatus( List<String> status) throws Exception;
List<Pet> findPetsByTags( List<String> tags);
List<Pet> findPetsByTags( List<String> tags) throws Exception;
Pet getPetById(Long petId);
Pet getPetById(Long petId) throws Exception;
void updatePet(Pet body);
void updatePet(Pet body) throws Exception;
void updatePetWithForm(String petId, String name, String status);
void updatePetWithForm(String petId, String name, String status) throws Exception;
void uploadFile(Long petId, String additionalMetadata, Http.MultipartFormData.FilePart file);
void uploadFile(Long petId, String additionalMetadata, Http.MultipartFormData.FilePart file) throws Exception;
}

View File

@ -33,14 +33,14 @@ public class StoreApiController extends Controller {
@ApiAction
public Result deleteOrder(String orderId) {
public Result deleteOrder(String orderId) throws Exception {
imp.deleteOrder(orderId);
return ok();
}
@ApiAction
public Result getInventory() {
public Result getInventory() throws Exception {
Map<String, Integer> obj = imp.getInventory();
JsonNode result = mapper.valueToTree(obj);
return ok(result);
@ -48,7 +48,7 @@ public class StoreApiController extends Controller {
}
@ApiAction
public Result getOrderById(String orderId) {
public Result getOrderById(String orderId) throws Exception {
Order obj = imp.getOrderById(orderId);
JsonNode result = mapper.valueToTree(obj);
return ok(result);
@ -56,7 +56,7 @@ public class StoreApiController extends Controller {
}
@ApiAction
public Result placeOrder() throws IOException {
public Result placeOrder() throws Exception {
JsonNode nodebody = request().body().asJson();
Order body;
if (nodebody != null) {

View File

@ -10,22 +10,22 @@ import java.util.HashMap;
import javax.validation.constraints.*;
public class StoreApiControllerImp implements StoreApiControllerImpInterface {
public void deleteOrder(String orderId) {
public void deleteOrder(String orderId) throws Exception {
//Do your magic!!!
}
public Map<String, Integer> getInventory() {
public Map<String, Integer> getInventory() throws Exception {
//Do your magic!!!
return new HashMap<String, Integer>();
}
public Order getOrderById(String orderId) {
public Order getOrderById(String orderId) throws Exception {
//Do your magic!!!
return new Order();
}
public Order placeOrder(Order body) {
public Order placeOrder(Order body) throws Exception {
//Do your magic!!!
return new Order();
}

View File

@ -11,12 +11,12 @@ import java.util.HashMap;
import javax.validation.constraints.*;
public interface StoreApiControllerImpInterface {
void deleteOrder(String orderId);
void deleteOrder(String orderId) throws Exception;
Map<String, Integer> getInventory();
Map<String, Integer> getInventory() throws Exception;
Order getOrderById(String orderId);
Order getOrderById(String orderId) throws Exception;
Order placeOrder(Order body);
Order placeOrder(Order body) throws Exception;
}

View File

@ -33,7 +33,7 @@ public class UserApiController extends Controller {
@ApiAction
public Result createUser() throws IOException {
public Result createUser() throws Exception {
JsonNode nodebody = request().body().asJson();
User body;
if (nodebody != null) {
@ -48,7 +48,7 @@ public class UserApiController extends Controller {
}
@ApiAction
public Result createUsersWithArrayInput() throws IOException {
public Result createUsersWithArrayInput() throws Exception {
JsonNode nodebody = request().body().asJson();
List<User> body;
if (nodebody != null) {
@ -63,7 +63,7 @@ public class UserApiController extends Controller {
}
@ApiAction
public Result createUsersWithListInput() throws IOException {
public Result createUsersWithListInput() throws Exception {
JsonNode nodebody = request().body().asJson();
List<User> body;
if (nodebody != null) {
@ -78,14 +78,14 @@ public class UserApiController extends Controller {
}
@ApiAction
public Result deleteUser(String username) {
public Result deleteUser(String username) throws Exception {
imp.deleteUser(username);
return ok();
}
@ApiAction
public Result getUserByName(String username) {
public Result getUserByName(String username) throws Exception {
User obj = imp.getUserByName(username);
JsonNode result = mapper.valueToTree(obj);
return ok(result);
@ -93,7 +93,7 @@ public class UserApiController extends Controller {
}
@ApiAction
public Result loginUser() {
public Result loginUser() throws Exception {
String valueusername = request().getQueryString("username");
String username;
if (valueusername != null) {
@ -117,14 +117,14 @@ public class UserApiController extends Controller {
}
@ApiAction
public Result logoutUser() {
public Result logoutUser() throws Exception {
imp.logoutUser();
return ok();
}
@ApiAction
public Result updateUser(String username) throws IOException {
public Result updateUser(String username) throws Exception {
JsonNode nodebody = request().body().asJson();
User body;
if (nodebody != null) {

View File

@ -10,42 +10,42 @@ import java.util.HashMap;
import javax.validation.constraints.*;
public class UserApiControllerImp implements UserApiControllerImpInterface {
public void createUser(User body) {
public void createUser(User body) throws Exception {
//Do your magic!!!
}
public void createUsersWithArrayInput(List<User> body) {
public void createUsersWithArrayInput(List<User> body) throws Exception {
//Do your magic!!!
}
public void createUsersWithListInput(List<User> body) {
public void createUsersWithListInput(List<User> body) throws Exception {
//Do your magic!!!
}
public void deleteUser(String username) {
public void deleteUser(String username) throws Exception {
//Do your magic!!!
}
public User getUserByName(String username) {
public User getUserByName(String username) throws Exception {
//Do your magic!!!
return new User();
}
public String loginUser( String username, String password) {
public String loginUser( String username, String password) throws Exception {
//Do your magic!!!
return new String();
}
public void logoutUser() {
public void logoutUser() throws Exception {
//Do your magic!!!
}
public void updateUser(String username, User body) {
public void updateUser(String username, User body) throws Exception {
//Do your magic!!!
}

View File

@ -11,20 +11,20 @@ import java.util.HashMap;
import javax.validation.constraints.*;
public interface UserApiControllerImpInterface {
void createUser(User body);
void createUser(User body) throws Exception;
void createUsersWithArrayInput(List<User> body);
void createUsersWithArrayInput(List<User> body) throws Exception;
void createUsersWithListInput(List<User> body);
void createUsersWithListInput(List<User> body) throws Exception;
void deleteUser(String username);
void deleteUser(String username) throws Exception;
User getUserByName(String username);
User getUserByName(String username) throws Exception;
String loginUser( String username, String password);
String loginUser( String username, String password) throws Exception;
void logoutUser();
void logoutUser() throws Exception;
void updateUser(String username, User body);
void updateUser(String username, User body) throws Exception;
}

View File

@ -13,18 +13,15 @@ public class ApiCall extends Action<SwaggerUtils.ApiAction> {
@Inject
private ApiCall() {}
public CompletionStage <Result> call(Http.Context ctx) {
public CompletionStage<Result> call(Http.Context ctx) {
try {
//TODO: Do stuff you want to handle with each API call (metrics, logging, etc..)
return delegate.call(ctx);
} catch (Throwable t) {
//TODO: handle error the way you want
return CompletableFuture.completedFuture(handleExceptions(t));
//TODO: log the error in your metric
//We rethrow this error so it will be caught in the ErrorHandler
throw t;
}
}
private Result handleExceptions(Throwable t) {
//TODO: Handle exception that need special response (return a special apimodel, etc..)
return ok();
}
}

View File

@ -0,0 +1,49 @@
package swagger;
import play.*;
import play.api.OptionalSourceMapper;
import play.api.UsefulException;
import play.api.routing.Router;
import play.http.DefaultHttpErrorHandler;
import play.mvc.Http.*;
import play.mvc.*;
import javax.inject.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import static play.mvc.Results.*;
@Singleton
public class ErrorHandler extends DefaultHttpErrorHandler {
@Inject
public ErrorHandler(Configuration configuration, Environment environment, OptionalSourceMapper sourceMapper, Provider<Router> routes) {
super(configuration, environment, sourceMapper, routes);
}
@Override
protected CompletionStage<Result> onDevServerError(RequestHeader request, UsefulException exception) {
return CompletableFuture.completedFuture(
handleExceptions(exception)
);
}
@Override
protected CompletionStage<Result> onProdServerError(RequestHeader request, UsefulException exception) {
return CompletableFuture.completedFuture(
handleExceptions(exception)
);
}
@Override
protected void logServerError(RequestHeader request, UsefulException usefulException) {
//Since the error is already handled, we don't want to print anything on the console
//But if you want to have the error printed in the console, just delete this override
}
private Result handleExceptions(Throwable t) {
//TODO: Handle exception that need special response (return a special apimodel, notFound(), etc..)
return ok();
}
}

View File

@ -15,6 +15,8 @@
# HOCON will fall back to substituting environment variable:
#mykey = ${JAVA_HOME}
play.http.errorHandler="swagger.ErrorHandler"
## Akka
# https://www.playframework.com/documentation/latest/ScalaAkka#Configuration
# https://www.playframework.com/documentation/latest/JavaAkka#Configuration
@ -35,8 +37,6 @@ akka {
#log-config-on-start = true
}
api.version="1.0"
## Secret key
# http://www.playframework.com/documentation/latest/ApplicationSecret
# ~~~~~

View File

@ -1,2 +1,2 @@
// The Play plugin
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.10")
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.13")