7a1029c8c267d7441803889522ac719190415845
[JavaForFun] /
1 package de.spring.webservices.rest.controller;
2
3 import static de.spring.webservices.rest.controller.adapters.RxJavaAdapter.deferredAdapter;
4
5 import java.util.Map;
6
7 import javax.inject.Inject;
8
9 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
11 import org.springframework.data.domain.Page;
12 import org.springframework.data.domain.PageRequest;
13 import org.springframework.http.HttpHeaders;
14 import org.springframework.http.HttpStatus;
15 import org.springframework.http.MediaType;
16 import org.springframework.http.ResponseEntity;
17 import org.springframework.web.bind.annotation.PathVariable;
18 import org.springframework.web.bind.annotation.RequestBody;
19 import org.springframework.web.bind.annotation.RequestHeader;
20 import org.springframework.web.bind.annotation.RequestMapping;
21 import org.springframework.web.bind.annotation.RequestMethod;
22 import org.springframework.web.bind.annotation.RequestParam;
23 import org.springframework.web.bind.annotation.ResponseStatus;
24 import org.springframework.web.bind.annotation.RestController;
25 import org.springframework.web.context.request.async.DeferredResult;
26
27 import de.spring.webservices.domain.Car;
28 import de.spring.webservices.rest.business.service.RxJavaBusinessLogic;
29 import io.reactivex.Observable;
30
31 @RestController
32 @RequestMapping("/api/rxjava/cars/")
33 public class RxJavaCarController {
34         private static final Logger LOGGER = LoggerFactory.getLogger(RxJavaCarController.class);
35         private static final int PAGE = 2;
36         private static final int PAGE_SIZE = 10;
37         
38         private final RxJavaBusinessLogic rxJavaBusinessLogic;
39
40         @Inject
41     public RxJavaCarController(RxJavaBusinessLogic completableFutureBusinessLogic) {
42                 this.rxJavaBusinessLogic = completableFutureBusinessLogic;
43         }
44
45         @RequestMapping(produces = { MediaType.APPLICATION_JSON_UTF8_VALUE }, method = RequestMethod.GET)
46     @ResponseStatus(HttpStatus.OK)
47     public DeferredResult<Page<Car>> cars() {
48                 
49                 // BE CAREFUL: I am returning Page object but when using io.reactivex.Observable (stream) instead of io.reactivex.Single (only one element)
50                 // if you want this code to work you will have to return DeferredResult<List<Car>> and you will have to call
51                 // the toList() method of Observable.
52                 // The toList() method is the only way I know for returning Observable (stream) perhaps in Spring 5.0.0 there will be something better.
53                 // Until then, this is the only way I know for using Observable with Spring.
54                                         
55                 return deferredAdapter(rxJavaBusinessLogic.findAll(new PageRequest(PAGE, PAGE_SIZE)) /** .toList() **/);
56     }
57
58     @RequestMapping(value = "{id}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.GET)
59     @ResponseStatus(HttpStatus.OK)
60     public DeferredResult<Car> car(@RequestHeader(value = "MY_HEADER", required = false) String specialHeader,
61                         @PathVariable("id") long id,
62                         @RequestParam Map<String, String> params,
63                         @RequestParam(value = "wheel", required = false) String[] wheelParams) {
64                 
65         if (specialHeader != null) {
66                 LOGGER.info("SPECIAL HEADER: " + specialHeader);
67         }
68          
69         if (params.get("mirror") != null) {
70                 LOGGER.info("MIRROR: " + params.get("mirror")); 
71         }
72         
73         if (params.get("window") != null) {
74                 LOGGER.info("WINDOW: " + params.get("window"));
75         }
76         
77         if (wheelParams != null) {
78                 for(String wheel : wheelParams) {
79                         LOGGER.info(wheel);
80                 }
81         }
82         
83                 // BE CAREFUL: I am returning Page object but when using io.reactivex.Observable (stream) instead of io.reactivex.Single (only one element)
84                 // if you want this code to work you will have to return DeferredResult<List<Car>> and you will have to call
85                 // the toList() method of Observable.
86                 // The toList() method is the only way I know for returning Observable (stream) perhaps in Spring 5.0.0 there will be something better.
87                 // Until then, this is the only way I know for using Observable with Spring.
88                 
89                 return deferredAdapter(rxJavaBusinessLogic.findById(id) /** .toList() **/);
90
91     }
92     
93     @RequestMapping(consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
94                 produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.POST)
95         @ResponseStatus(HttpStatus.CREATED)
96     public DeferredResult<ResponseEntity<Car>> create(@RequestBody Car car) {
97         
98         return deferredAdapter(createAsync(car));
99     }
100
101     
102     private Observable<ResponseEntity<Car>> createAsync(Car car) {
103         
104                 // BE CAREFUL: I am returning Page object but when using io.reactivex.Observable (stream) instead of io.reactivex.Single (only one element)
105                 // if you want this code to work you will have to return DeferredResult<List<Car>> and you will have to call
106                 // the toList() method of Observable.
107                 // The toList() method is the only way I know for returning Observable (stream) perhaps in Spring 5.0.0 there will be something better.
108                 // Until then, this is the only way I know for using Observable with Spring.
109         
110         return rxJavaBusinessLogic
111                         .createThrowable(car)
112                         .map(this::createResponseCar) /** .toList() **/;                
113     }
114     
115     private ResponseEntity<Car> createResponseCar(Car car) {
116                 HttpHeaders headers = new HttpHeaders();
117             headers.add(HttpHeaders.LOCATION, "/api/rxjava/cars/" + car.getId());
118             return new ResponseEntity<>(car, headers, HttpStatus.CREATED);
119     }
120 }