Support Observable as @Controller return value

This commit is contained in:
Rossen Stoyanchev
2015-05-26 12:29:07 -04:00
parent dbe9762831
commit 28e72cc479
7 changed files with 83 additions and 12 deletions

View File

@@ -10,6 +10,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import rx.Observable;
import rx.functions.Func1;
@RestController
@@ -24,14 +26,14 @@ public class AccountController {
}
@RequestMapping(method = RequestMethod.POST)
public DeferredResult<CreateAccountResponse> createAccount(@RequestBody CreateAccountRequest request) {
return DeferredUtils.toDeferredResult(accountService.openAccount(request.getInitialBalance()).map(new Func1<EntityWithIdAndVersion<Account>, CreateAccountResponse>() {
public Observable<CreateAccountResponse> createAccount(@RequestBody CreateAccountRequest request) {
return accountService.openAccount(request.getInitialBalance()).map(new Func1<EntityWithIdAndVersion<Account>, CreateAccountResponse>() {
@Override
public CreateAccountResponse call(EntityWithIdAndVersion<Account> entityAndEventInfo) {
return new CreateAccountResponse(entityAndEventInfo.getEntityIdentifier().getId());
}
}));
});
}
}

View File

@@ -1,13 +1,24 @@
package net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts;
import java.util.List;
import net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.accounts.AccountConfiguration;
import net.chrisrichardson.eventstore.javaexamples.banking.web.util.ObservableReturnValueHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@Import({AccountConfiguration.class})
@ComponentScan
public class CommandSideWebAccountsConfiguration {
public class CommandSideWebAccountsConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
handlers.add(new ObservableReturnValueHandler());
}
}

View File

@@ -1,12 +1,24 @@
package net.chrisrichardson.eventstore.javaexamples.banking.web.queryside;
import java.util.List;
import net.chrisrichardson.eventstore.javaexamples.banking.backend.queryside.accounts.QuerySideAccountConfiguration;
import net.chrisrichardson.eventstore.javaexamples.banking.web.util.ObservableReturnValueHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@Import({QuerySideAccountConfiguration.class})
@ComponentScan
public class QuerySideWebConfiguration {
public class QuerySideWebConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
handlers.add(new ObservableReturnValueHandler());
}
}

View File

@@ -9,6 +9,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;
import rx.Observable;
import rx.functions.Func1;
import java.math.BigDecimal;
@@ -24,13 +26,13 @@ public class AccountQueryController {
}
@RequestMapping(value="/accounts/{accountId}", method = RequestMethod.GET)
public DeferredResult<GetAccountResponse> get(@PathVariable String accountId) {
return DeferredUtils.toDeferredResult(accountInfoQueryService.findByAccountId(new EntityIdentifier(accountId)).map(new Func1<AccountInfo, GetAccountResponse>() {
public Observable<GetAccountResponse> get(@PathVariable String accountId) {
return accountInfoQueryService.findByAccountId(new EntityIdentifier(accountId)).map(new Func1<AccountInfo, GetAccountResponse>() {
@Override
public GetAccountResponse call(AccountInfo accountInfo) {
return new GetAccountResponse(accountInfo.getId(), new BigDecimal(accountInfo.getBalance()));
}
}));
});
}
@ResponseStatus(value= HttpStatus.NOT_FOUND, reason="account not found")

View File

@@ -0,0 +1,31 @@
package net.chrisrichardson.eventstore.javaexamples.banking.web.util;
import rx.Observable;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.async.DeferredResult;
import org.springframework.web.context.request.async.WebAsyncUtils;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
public class ObservableReturnValueHandler implements HandlerMethodReturnValueHandler {
@Override
public boolean supportsReturnType(MethodParameter returnType) {
return Observable.class.equals(returnType.getParameterType());
}
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest) throws Exception {
if (returnValue == null) {
return;
}
DeferredResult<?> d = DeferredUtils.toDeferredResult((Observable<?>) returnValue);
WebAsyncUtils.getAsyncManager(webRequest).startDeferredResultProcessing(d);
}
}

View File

@@ -1,13 +1,24 @@
package net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.transactions;
import java.util.List;
import net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.transactions.MoneyTransferConfiguration;
import net.chrisrichardson.eventstore.javaexamples.banking.web.util.ObservableReturnValueHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@Import({MoneyTransferConfiguration.class})
@ComponentScan
public class CommandSideWebTransactionsConfiguration {
public class CommandSideWebTransactionsConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
handlers.add(new ObservableReturnValueHandler());
}
}

View File

@@ -12,6 +12,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import rx.Observable;
import rx.functions.Func1;
@RestController
@@ -26,16 +28,16 @@ public class MoneyTransferController {
}
@RequestMapping(method = RequestMethod.POST)
public DeferredResult<CreateMoneyTransferResponse> createMoneyTransfer(@RequestBody CreateMoneyTransferRequest request) {
public Observable<CreateMoneyTransferResponse> createMoneyTransfer(@RequestBody CreateMoneyTransferRequest request) {
TransferDetails transferDetails = new TransferDetails(new EntityIdentifier(request.getFromAccountId()), new EntityIdentifier(request.getToAccountId()), request.getAmount());
return DeferredUtils.toDeferredResult(moneyTransferService.transferMoney(transferDetails).map(new Func1<EntityWithIdAndVersion<MoneyTransfer>, CreateMoneyTransferResponse>() {
return moneyTransferService.transferMoney(transferDetails).map(new Func1<EntityWithIdAndVersion<MoneyTransfer>, CreateMoneyTransferResponse>() {
@Override
public CreateMoneyTransferResponse call(EntityWithIdAndVersion<MoneyTransfer> entityAndEventInfo) {
return new CreateMoneyTransferResponse(entityAndEventInfo.getEntityIdentifier().getId());
}
}));
});
}
}