寻找更好的解决方案来处理 micronaut 中的全局异常https://docs.micronaut.io/latest/guide/index.html#errorHandling
控制器
@Controller("/category")
public class CategoryController {
@Delete(uri = "/{id}")
public Maybe<HttpResponse> delete(@NotBlank String id) {
LOG.info(String.format("API --> Deleting the specified category"));
return iCategoryManager.Count(id).flatMap(item -> {
if (item > 0) {
iCategoryManager.Delete(id).subscribe();
return Maybe.just(HttpResponse.noContent());
} else
return Maybe.just(HttpResponse.notFound());
});
}
}
Run Code Online (Sandbox Code Playgroud)
iCategoryManager.Count(id)导致如下异常,如何捕获GlobalExceptionHandler上的异常
io.micronaut.core.serialize.exceptions.SerializationException: Incorrect message body size to deserialize to a Long
at io.micronaut.rabbitmq.serdes.JavaLangRabbitMessageSerDes$LongSerDes.deserialize(JavaLangRabbitMessageSerDes.java:314)
at io.micronaut.rabbitmq.serdes.JavaLangRabbitMessageSerDes$LongSerDes.deserialize(JavaLangRabbitMessageSerDes.java:306)
at io.micronaut.rabbitmq.serdes.JavaLangRabbitMessageSerDes.deserialize(JavaLangRabbitMessageSerDes.java:81)
at io.micronaut.rabbitmq.intercept.RabbitMQIntroductionAdvice.deserialize(RabbitMQIntroductionAdvice.java:323)
at io.micronaut.rabbitmq.intercept.RabbitMQIntroductionAdvice.lambda$intercept$22(RabbitMQIntroductionAdvice.java:268)
at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.onNext(FlowableFlatMap.java:132)
at io.micronaut.reactive.rxjava2.RxInstrumentedSubscriber.onNext(RxInstrumentedSubscriber.java:59)
at io.reactivex.internal.operators.flowable.FlowableTimeoutTimed$TimeoutSubscriber.onNext(FlowableTimeoutTimed.java:101)
at io.micronaut.reactive.rxjava2.RxInstrumentedSubscriber.onNext(RxInstrumentedSubscriber.java:59)
at io.reactivex.internal.subscriptions.DeferredScalarSubscription.complete(DeferredScalarSubscription.java:132)
at io.reactivex.internal.operators.single.SingleToFlowable$SingleToFlowableObserver.onSuccess(SingleToFlowable.java:62)
at …Run Code Online (Sandbox Code Playgroud) 我设置了一个简单的测试控制器:
@Controller("/test")
public class SampleController {
@Get(value = "1", produces = MediaType.TEXT_PLAIN)
public String helloWorld1() {
return "Hello, World!";
}
@Get(value = "2", produces = MediaType.TEXT_PLAIN)
public HttpResponse<String> helloWorld2() {
return HttpResponse.ok("Hello, World!");
}
}
Run Code Online (Sandbox Code Playgroud)
我在单元测试中使用低级 HTTPClient,如下所示:
@MicronautTest
public class SampleControllerTest {
@Inject
EmbeddedServer server;
@Inject
@Client("/test")
HttpClient client;
@Test
void shouldReturnHelloWorld1_1() {
HttpResponse<String> response = client.toBlocking().exchange(HttpRequest.GET("/1").accept(
MediaType.TEXT_PLAIN));
assertEquals(200, response.code());
assertEquals("Hello, World!", response.body());
}
@Test
void shouldReturnHelloWorld1_2() {
String response = client.toBlocking().retrieve(HttpRequest.GET("/1").accept(MediaType.TEXT_PLAIN));
assertEquals("Hello, World!", response);
}
@Test
void shouldReturnHelloWorld2() { …Run Code Online (Sandbox Code Playgroud) 我正在尝试在 micronaut 中编写集成测试。
我有一个控制器类:
@Controller("/hello")
public class HelloController {
@Inject
private HelloRepository helloRepository;
@Get("/")
public HttpResponse get() {
return HttpResponse.ok(helloRepository.findAll());
}
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试为它编写一个集成测试,例如:
@MicronautTest
public class HelloControllerSpec {
@Inject
EmbeddedServer embeddedServer;
@BeforeEach
void setUp() {
initMocks(this);
}
@Test
public void testIndex() throws Exception {
try(RxHttpClient client = embeddedServer.getApplicationContext().createBean(RxHttpClient.class, embeddedServer.getURL())) {
client.toBlocking().exchange("/hello").status();
}
}
}
Run Code Online (Sandbox Code Playgroud)
但我不断收到错误消息:
No backing RepositoryOperations configured for repository. Check your configuration and try again
Run Code Online (Sandbox Code Playgroud)
我放在“src/test/java/resources/”下的 application.yml 文件具有以下数据源实现:
datasources:
default:
url: jdbc:h2:mem:devDb
driverClassName: org.h2.Driver
username: sa
password: 'sa' …Run Code Online (Sandbox Code Playgroud) 我的客户端应该从控制器收到一个文件。问题是客户端只接收一个字符串。如何获取控制器返回的流?
这是我的控制器:
@Get("/{databaseName}")
MutableHttpResponse < Object > createDatabaseBackup(String databaseName) {
InputStream inputStreamDatabaseBackup = backupTask.exportBackup(databaseName);
return HttpResponse.ok(new StreamedFile(inputStreamDatabaseBackup, MediaType.APPLICATION_OCTET_STREAM_TYPE));
}
Run Code Online (Sandbox Code Playgroud)
这是我的客户:
@Inject
@Client("${agent.connection-url}")
private RxHttpClient client;
public String getBackup(String dataBaseName) {
return client.toBlocking().retrieve(HttpRequest.GET("/backup/" + dataBaseName));
}
Run Code Online (Sandbox Code Playgroud) 我需要在请求中将参数设置为“不需要”。
我试过:
@Get(value = "/list/{username}")
HttpResponse<?> list(String username, @QueryValue(value = "actionCode") String actionCode) {
...
}
Run Code Online (Sandbox Code Playgroud)
当我发送请求http://localhost:8080/notification/list/00000000000时,会引发以下错误:
{
"message": "Required Parameter [actionCode] not specified",
"path": "/actionCode",
"_links": {
"self": {
"href": "/notification/list/00000000000",
"templated": false
}
}
}
Run Code Online (Sandbox Code Playgroud) 我正在努力使用Micronaut HTTPClient多次调用第三方 REST 服务,但没有收到io.micronaut.http.client.exceptions.ReadTimeoutException
要消除第三方依赖性,可以使用调用其自己的服务的简单 Micronaut 应用程序来重现该问题。
控制器示例:
@Controller("/")
public class TestController {
@Inject
private TestClient client;
@Get("service")
String service() {
return "Hello World Service";
}
@Get("mproxy")
String multiproxy() {
StringBuffer sb = new StringBuffer();
for(int i=0;i<20;i++){
sb.append(client.getService());
}
return sb.toString();
}
@Get("proxy")
String proxy() {
return client.getService();
}
}
Run Code Online (Sandbox Code Playgroud)
测试客户端:
@Client("http://localhost:8080")
public interface TestClient {
@Get("/service")
String getService();
}
Run Code Online (Sandbox Code Playgroud)
使用curl、ab 或postman 直接调用/service 端点不会产生错误。
调用 /mproxy 端点将引发异常
ERROR i.m.r.intercept.RecoveryInterceptor - Type [clienttest.TestClient$Intercepted] executed with error: Read Timeout …Run Code Online (Sandbox Code Playgroud) 我的应用程序基于 Micronaut 和 GraalVM (java 11),并对以下内容进行简单调用http://httpbin.org/get:
@Controller("/api")
class HelloWorld(
@Client("http://httpbin.org")
private val httpClient: RxHttpClient
) {
private val logger = LoggerFactory.getLogger(javaClass)
@Get("/hello")
fun hello(): String {
return "Hello World!"
}
@Get("/fb")
fun fb(): Flowable<String> {
logger.info("Trying to call FB")
logger.info("Using url http://httpbin.org/get")
try {
return httpClient.retrieve("/get")
.doOnError { logger.error("Error calling fb api flowable", it) }
.doFinally { logger.info("Finished calling FB api flowable") }
} catch (ex: Exception) {
logger.error("Error calling fb api", ex)
throw ex
} finally { …Run Code Online (Sandbox Code Playgroud)