我在 Quarkus (1.8.1) 服务中有一个 Rest 客户端,定义如下:
@RegisterRestClient
@Path("/")
@Produces("application/json")
@Consumes("application/json")
public interface MyClient {
@POST
@Path("/{entity}")
Response postEntity(@HeaderParam(value = "Authorization") String auth,
@PathParam("entity") String entity, Object payload) throws MyException;
}
Run Code Online (Sandbox Code Playgroud)
我已经ResponseExceptionMapper
在同一个包中实现了这样的:
public class MyExceptionMapper implements ResponseExceptionMapper<MyException> {
@Override
public MyException toThrowable(Response r) {
return new DynamicsException(r.getStatus() + " - " + r.readEntity(String.class));
}
}
Run Code Online (Sandbox Code Playgroud)
MyExceptionMapper
当我调用该服务时,它当前返回 404 错误,并且我期望调用类中的代码。然而它没有,而是javax.ws.rs.WebApplicationException
抛出了 a 。堆栈跟踪包括对DefaultResponseExceptionMapper
. 看来我的映射器尚未注册。
如何注册我的处理程序以处理对服务的调用的无效响应?
我试图了解这是一个功能还是一个错误...:-)
对于下面的控制器和异常映射器,对于将因 401 响应而失败的其余客户端,我希望在这两种情况下都会调用异常处理程序。但是,不会针对 WebApplicationException 调用它。为什么会这样以及您打算如何为这些情况注册异常处理程序。这是使用 Quarkus 版本 0.21.2
@Path("/failable")
public class FailableResource {
@Inject
@RestClient
private SomeHttpClient httpClient;
@GET
@Path("fails")
@Produces(MediaType.TEXT_PLAIN)
public String fails() {
try {
return httpClient.someQuery();
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@GET
@Path("works")
@Produces(MediaType.TEXT_PLAIN)
public String works() {
try {
return httpClient.someQuery();
} catch (Exception e) {
e.printStackTrace();
throw new IllegalStateException("Not a WebApplicationException");
}
}
}
Run Code Online (Sandbox Code Playgroud)
和异常映射器
@Provider
public class HandleMySillyError implements ExceptionMapper<Throwable> {
@Override
public Response toResponse(Throwable e) {
e.printStackTrace(); …
Run Code Online (Sandbox Code Playgroud) 我正在从带注释的 Java 代码生成 OpenAPI 3.0 文档。但问题是,当我添加 @Schema 注释来枚举所有值时,所有值都消失了。我正在使用带有 microprofile-openapi 分数的 Thorntail 2.3.0.Final。
我知道我可以只更改 .yaml 文件,但我需要直接从 Java 代码生成我的 yaml。
这是我在 github 上的最小示例:https : //github.com/pkristja/openApiEnumSchema
枚举的源代码:
package com.example.openapiexample.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
@Schema(description = "<div class=\\\"renderedMarkdown\\\"><p>Rank of developer.</p>\\n\" +\n" +
" \"<p>Valid values are:</p>\\n\" +\n" +
" \"<ul>\\n\" +\n" +
" \"<li>'JUNIOR_DEVELOPER_1': Text for junior 1.\\n\" +\n" +
" \"<li>'JUNIOR_DEVELOPER_2': Text for junior 2.\\n\" +\n" +
" \"<li>'JUNIOR_DEVELOPER_3': Text for junior 3.\\n\" +\n" +
" \"<li>'SENIOR_DEVELOPER_1': Text for senior …
Run Code Online (Sandbox Code Playgroud) 我正在开发使用 microprofile Rest 客户端的应用程序。该 REST 客户端应发送带有各种 http 标头的 REST 请求。某些标头名称会动态更改。我的微配置文件休息客户端应该是通用的,但我没有找到如何实现这种行为。根据文档,您需要通过注释指定实现中的所有标头名称,但这不是通用的。有什么方法可以“破解”它并以编程方式添加 HTTP 标头吗?
提前致谢
GenericRestClient genericRestClient = null;
Map<String, Object> appConfig = context.appConfigs();
String baseUrl = (String) appConfig.get("restClient.baseUrl");
path = (String) appConfig.get("restClient.path");
try {
genericRestClient = RestClientBuilder.newBuilder()
.baseUri(new URI(baseUrl)).build(GenericRestClient.class);
}catch(URISyntaxException e){
logger.error("",e);
throw e;
}
Response response = genericRestClient.sendMessage(path, value);
logger.info("Status: "+response.getStatus());
logger.info("Response body: "+response.getEntity().toString());
Run Code Online (Sandbox Code Playgroud)
通用休息客户端代码:
@RegisterRestClient
public interface GenericRestClient {
@POST
@Path("{path}")
@Produces("application/json")
@Consumes("application/json")
public Response sendMessage(<here should go any map of custom headers>, @PathParam("path") String pathParam, String jsonBody);
}
Run Code Online (Sandbox Code Playgroud) 我读了很多关于如何在payara 5上将jackson替换为moxy但从未实现过一个好的解决方案,所以我创建了一个小项目,希望有人可以帮助我。
pom.xml
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>${version.javaee}</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-json-jackson -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.27</version>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile</groupId>
<artifactId>microprofile</artifactId>
<type>pom</type>
<version>1.4</version>
</dependency>
<dependencies>
Run Code Online (Sandbox Code Playgroud)
应用程序.java
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import org.glassfish.jersey.jackson.JacksonFeature;
@ApplicationPath("/api")
public class App extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new java.util.HashSet<>();
resources.add(JacksonFeature.class);
resources.add(SimpleService.class);
return resources;
}
}
Run Code Online (Sandbox Code Playgroud)
简单服务.java
@Path("sample")
public class SimpleService {
@Path("greet2")
@GET
@Produces(MediaType.APPLICATION_JSON)
public PojoEntity doGreet2() {
PojoEntity pojoEntity = new PojoEntity();
pojoEntity.setTeste1("TesteValue1");
pojoEntity.setTeste2("TesteValue2");
return pojoEntity;
}
}
Run Code Online (Sandbox Code Playgroud)
PojoEntity.java …
我有一个看起来像这样的请求:
@Path("/v1")
@RegisterRestClient
@Produces("application/json")
public interface VaultClient {
@POST
@Path("/auth/jwt/login")
@Consumes("application/json")
String getVaultToken(LoginPayload loginPayload);
}
Run Code Online (Sandbox Code Playgroud)
LoginPayload 只是一个简单的 POJO:
public class LoginPayload {
private String jwt;
final private String role = "some-service";
public void setJwt(String _jwt) {
this.jwt = _jwt;
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试通过服务调用此端点时:
public String getServiceJwt() {
String loginJwt = getLoginJwt();
LoginPayload loginPayload = new LoginPayload();
loginPayload.setJwt(loginJwt);
try {
System.out.println(loginPayload.toString());
String tokenResponse = vaultClient.getVaultToken(loginPayload);
System.out.println("##################");
System.out.println(tokenResponse);
} catch (Exception e) {
System.out.println(e);
}
return vaultJwt;
}
Run Code Online (Sandbox Code Playgroud)
我得到一个 400:
javax.ws.rs.WebApplicationException: Unknown error, …
Run Code Online (Sandbox Code Playgroud) 我正在尝试构建一个简单的应用程序,该应用程序使用quarkus-rest-client
. 我必须注入一个 API 密钥作为标头,这对于 API 的所有资源都是相同的。所以我想把这个 API Key 的值(取决于环境dev/qa/prod
)放在application.properties
位于src/main/resources
.
我尝试了不同的方法来实现这一目标:
com.acme.Configuration.getKey
到@ClientHeaderParam
value 属性最后,我找到了下面描述的方法来使它工作。
我的问题是:有没有更好的方法来做到这一点?
这是我的代码:
@Path("/stores")
@RegisterRestClient
@ClientHeaderParam(name = "ApiKey", value = "{com.acme.Configuration.getStoresApiKey}")
public interface StoresService {
@GET
@Produces("application/json")
Stores getStores();
}
Run Code Online (Sandbox Code Playgroud)
@ApplicationScoped
public class Configuration {
@ConfigProperty(name = "apiKey.stores")
private String storesApiKey;
public String getKey() {
return storesApiKey;
}
public static String getStoresApiKey() {
return CDI.current().select(Configuration.class).get().getKey(); …
Run Code Online (Sandbox Code Playgroud) 我正在重写旧系统的异常,一切正常,但我需要进行BAD_REQUEST
配置。
private static final String BAD_REQUEST = "BDRQ";
Run Code Online (Sandbox Code Playgroud)
我尝试只放置 ConfigProperty,但它不起作用。
import javax.ws.rs.core.Response.Status;
import org.eclipse.microprofile.config.inject.ConfigProperty;
public class SXClientException extends RuntimeException {
@ConfigProperty(name = "greeting.error", defaultValue = "BDRQ")
public String BAD_REQUEST;
private final RuntimeException runtimeException;
public SXClientException(RuntimeException e) {
super(e);
this.runtimeException = e;
}
public Status getStatus() {
if (BAD_REQUEST.equals(runtimeException.getMessage())) {
return Status.BAD_REQUEST;
}
return Status.INTERNAL_SERVER_ERROR;
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
它可能不起作用,因为我在没有任何 CDI 的情况下制作它们。
catch (LegacyOMException e) {
throw new SXClientException(e);
}
Run Code Online (Sandbox Code Playgroud)
我宁愿避免创建另一个 bean(并传递值)只是为了比较一个字符串。知道如何读取静态值的配置值吗?
Quarkus using Rest Client,解释了如何使用 MicroProfile REST Client。对于基本 URL application.properties 可以使用。
org.acme.restclient.CountriesService/mp-rest/url=https://restcountries.eu/rest #
Run Code Online (Sandbox Code Playgroud)
使用上述方法,不能有动态基本 URL。
能够通过使用 RestClientBuilder 来实现它,如MicroProfile Rest Client 中所述。这种方法的缺点是没有自动协商功能。
SimpleGetApi simpleGetApi = RestClientBuilder.newBuilder().baseUri(getApplicationUri()).build(SimpleGetApi.class);
Run Code Online (Sandbox Code Playgroud)
有没有其他或更好的方法来实现这一目标?谢谢。
我正在使用 Quarkus 和 Microprofile OpenAPI 来映射 REST API 中的实体。我可以通过以下方式将我的驼峰命名属性转换为带下划线的小写:
@Schema(name = "first_name")
private String firstName;
Run Code Online (Sandbox Code Playgroud)
但是这很不方便,因为我必须在整个项目的任何地方都这样做。
问题:有没有一种方法可以自动为所有属性执行此操作,而无需在注释中指定映射?
我浏览了 Quarkus 和 Microprofile 的文档,但还没有找到它是如何实现的。