zhou-hao %!s(int64=5) %!d(string=hai) anos
pai
achega
226e1ad944

+ 4 - 0
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/CommonErrorControllerAdvice.java

@@ -7,6 +7,8 @@ import org.hswebframework.web.exception.BusinessException;
 import org.hswebframework.web.exception.NotFoundException;
 import org.hswebframework.web.exception.ValidationException;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
 import org.springframework.core.codec.DecodingException;
 import org.springframework.http.HttpStatus;
 import org.springframework.validation.BindException;
@@ -29,6 +31,7 @@ import java.util.stream.Collectors;
 @RestControllerAdvice
 @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
 @Slf4j
+@Order
 public class CommonErrorControllerAdvice {
 
     @ExceptionHandler
@@ -123,6 +126,7 @@ public class CommonErrorControllerAdvice {
 
     @ExceptionHandler
     @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
+    @Order
     public Mono<ResponseMessage<?>> handleException(RuntimeException e) {
         log.error(e.getMessage(), e);
         return Mono.just(ResponseMessage.error(e.getMessage()));

+ 42 - 3
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/ResponseMessageWrapper.java

@@ -2,11 +2,16 @@ package org.hswebframework.web.crud.web;
 
 import org.springframework.core.MethodParameter;
 import org.springframework.core.ReactiveAdapterRegistry;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
 import org.springframework.http.codec.HttpMessageWriter;
+import org.springframework.util.MimeType;
+import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.reactive.HandlerResult;
 import org.springframework.web.reactive.accept.RequestedContentTypeResolver;
 import org.springframework.web.reactive.result.method.annotation.ResponseBodyResultHandler;
 import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 
 import java.util.List;
@@ -34,20 +39,54 @@ public class ResponseMessageWrapper extends ResponseBodyResultHandler {
 
     @Override
     public boolean supports(HandlerResult result) {
-        boolean isAlreadyResponse = result.getReturnType().resolveGeneric(0) == ResponseMessage.class;
-        boolean isMono = result.getReturnType().resolve() == Mono.class;
-        return isMono && super.supports(result) && !isAlreadyResponse;
+        Class gen = result.getReturnType().resolveGeneric(0);
+
+        boolean isAlreadyResponse = gen == ResponseMessage.class || gen == ResponseEntity.class;
+
+        boolean isStream = result.getReturnType().resolve() == Mono.class
+                || result.getReturnType().resolve() == Flux.class;
+
+        RequestMapping mapping = result.getReturnTypeSource()
+                .getMethodAnnotation(RequestMapping.class);
+        if (mapping == null) {
+            return false;
+        }
+        for (String produce : mapping.produces()) {
+            MimeType mimeType = MimeType.valueOf(produce);
+            if (MediaType.TEXT_EVENT_STREAM.includes(mimeType) ||
+                    MediaType.APPLICATION_STREAM_JSON.includes(mimeType)) {
+                return false;
+            }
+        }
+        return isStream
+                && super.supports(result)
+                && !isAlreadyResponse;
     }
 
     @Override
     @SuppressWarnings("all")
     public Mono<Void> handleResult(ServerWebExchange exchange, HandlerResult result) {
         Object body = result.getReturnValue();
+
+        if (exchange
+                .getRequest()
+                .getHeaders()
+                .getAccept()
+                .contains(MediaType.TEXT_EVENT_STREAM)) {
+            return writeBody(body, param, exchange);
+        }
+
         if (body instanceof Mono) {
             body = ((Mono) body)
                     .switchIfEmpty(Mono.just(ResponseMessage.ok()))
                     .map(ResponseMessage::ok);
         }
+        if (body instanceof Flux) {
+            body = ((Flux) body)
+                    .collectList()
+                    .switchIfEmpty(Mono.just(ResponseMessage.ok()))
+                    .map(ResponseMessage::ok);
+        }
         if (body == null) {
             body = Mono.just(ResponseMessage.ok());
         }

+ 1 - 1
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/reactive/ReactiveSaveController.java

@@ -57,7 +57,7 @@ public interface ReactiveSaveController<E, K> {
                 .as(getRepository()::save);
     }
 
-    @PostMapping("/batch")
+    @PostMapping("/_batch")
     @SaveAction
     default Mono<Integer> add(@RequestBody Flux<E> payload) {
 

+ 1 - 1
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/reactive/ReactiveServiceSaveController.java

@@ -54,7 +54,7 @@ public interface ReactiveServiceSaveController<E,K>  {
                 .as(getService()::save);
     }
 
-    @PostMapping("/batch")
+    @PostMapping("/_batch")
     @SaveAction
     default Mono<Integer> add(@RequestBody Flux<E> payload) {