I have an applicationPath called: /web, and after the /web, i want to use a single class, every put,delete,post,update method in code looks like:
#ApplicationPath("/web")
public class If3WebApplication extends Application {
}
And in this class i would like to handle the all http method:
#Path("/*") //this is not working...
public class OAuthToken{
private HashMap<String, String> endpointMap = new LinkedHashMap<>();
#PostConstruct
public void init(){
endpointMap.put("token", "/token"); // hre will be all urls
}
#POST
#Consumes("application/x-www-form-urlencoded")
#Produces("text/plain")
public void get(){
.....
}
So i want to the OAuthToken handle all post method wich comes tto /web/url and post method...but the #Path("/*") not working...what is the best way to do the magic? Thanks for the helps!
You can try using the expression for Jersey as below
#Path("{any: .*}")
Related
As seen in the documentation, the standard way of declaring a route in Quarkus is with the #Path() annotation, like so :
#Path("myPath")
public class Endpoint {
#GET
public String hello() {
return "Hello, World!";
}
}
This will create the route GET /MyPath. However, #Path being an annotation, I have to give it constant expression.
I would like to be able to declare a route with a non constant expression, something like #Path(MyClass.class.getSimpleName())
I tried to implement something like this:
public class Endpoint {
public void initialize(#Observes StartupEvent ev) {
declareRoute(MyClass.class.getSimpleName(), HttpMethod.GET, this::hello);
}
public String hello() {
return "Hello, World!";
}
public void declareRoute(String path, HttpMethod method, Consumer handler) {
// TODO implement
}
}
This would create the route GET /MyClass But I have no idea how to implement declareRoute(). I tried to inject the Vertx Router since Quarkus seems to use it, but I did not find a way to add a route. Is this doable, and if so, how ?
You essentially need to do something like:
#ApplicationScoped
public class BeanRegisteringRoute {
void init(#Observes Router router) {
router.route("/my-path").handler(rc -> rc.response().end("Hello, World!"));
}
}
See this for more information
I'm trying to build a simple app that calls an API with quarkus-rest-client.
I have to inject an API Key as a header which is the same for all resources of the API.
So I would like to put the value of this API Key (that depends on the environment dev/qa/prod) in the application.properties file located in src/main/resources.
I tried different ways to achieve this:
Use directly com.acme.Configuration.getKey into #ClientHeaderParam value property
Create a StoresClientHeadersFactory class which implements ClientHeadersFactory interface to inject the configuration
Finally, I found the way described below to make it work.
My question is: Is there a better way to do it?
Here's my code:
StoreService.java which is my client to reach the API
#Path("/stores")
#RegisterRestClient
#ClientHeaderParam(name = "ApiKey", value = "{com.acme.Configuration.getStoresApiKey}")
public interface StoresService {
#GET
#Produces("application/json")
Stores getStores();
}
Configuration.java
#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();
}
}
StoresController.java which is the REST controller
#Path("/stores")
public class StoresController {
#Inject
#RestClient
StoresService storesService;
#GET
#Produces(MediaType.APPLICATION_JSON)
public Stores getStores() {
return storesService.getStores();
}
}
Late to the party, but putting this here for my own reference. There seems to be a difference in using #ClientHeaderParam and #HeaderParam, so I investigated a little further:
According to the Microprofile docs, you can put a compute method for the value in curly braces. This method can extract the property value.
See link for more examples.
EDIT: What I came up with resembles the original, but uses a default method on the interface, so you can at least discard the Configuration class. Also, using the org.eclipse.microprofile.config.Config and ConfigProvider classes to get the config value:
#RegisterRestClient
#ClientHeaderParam(name = "Authorization", value = "{getAuthorizationHeader}")
public interface StoresService {
default String getAuthorizationHeader(){
final Config config = ConfigProvider.getConfig();
return config.getValue("apiKey.stores", String.class);
}
#GET
#Produces("application/json")
Stores getStores();
I will get rid of the Configuration class and use an #HeaderParam to pass your configuration property from your rest endpoint to your rest client. The annotation will then send this property as an HTTP header to the remote service.
Somthing like this should works:
#Path("/stores")
#RegisterRestClient
public interface StoresService {
#GET
#Produces("application/json")
Stores getStores(#HeaderParam("ApiKey") storesApiKey);
}
#Path("/stores")
public class StoresController {
#ConfigProperty(name = "apiKey.stores")
private String storesApiKey;
#Inject
#RestClient
StoresService storesService;
#GET
#Produces(MediaType.APPLICATION_JSON)
public Stores getStores() {
return storesService.getStores(storesApiKey);
}
}
We have Rest services implemented using Jersy,my question is when invoking some soap service from our rest implementation, we are creating object for delegate like below,
#POST
#Path("/forgotuserid/validate/mobilenumber")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public ServiceResponse validateMobileNumber(CommunicationDTO commonDTO)
throws ApplicationException, Exception {
ChMTYWebservicesProvidersWsMTY service = new ChMTYWebservicesProvidersWsMTY();
WsMTYPortType portType = service.getChMTYWebservicesProvidersWsMTYPort();
//TODO : other stuffs go here
return response;
}
is there any way to avoid new object creation and have single here?
If you are using Spring framework then there is an option Dependency Injection , You can use that feature.
You can code something like this:
public class SoapWSUtil{
private static WsMTYPortType type;
static {
type = (new ChMTYWebservicesProvidersWsMTY()).getChMTYWebservicesProvidersWsMTYPort();
}
public static WsMTYPortType getType(){
return type;
}
}
And then use it as SoapWSUtil.getType(). It will be thread safe in case, if you won't add state to SoapWSUtil
Hi,
I am building a REST-api using Jersey and Java. I wonder if it is possible to reuse a method in many resources.
As an example If I have this code:
#Path("/users")
public class UserResource {
#GET
#Path("/{uid}/comments")
#Produces(MediaType.APPLICATION_JSON)
public List<Comment> getComments() {
return commentService.getOnEntity("User", uid);
}
}
and this:
#Path("/items")
public class ItemResource {
#GET
#Path("/{uid}/comments")
#Produces(MediaType.APPLICATION_JSON)
public List<Comment> getComments() {
return commentService.getOnEntity("Item", uid);
}
}
Is it possible to reuse the code for specifying the method "/{uid}/comments/" so I do not need to write it in every resource that is going to need it?
I guess I could extend a CommentResource with the method, but the I can only add one set of methods. If I use Interface I could specify more than one set of methods but would have to rewrite the code inside the methods in every resource.
Edit
After a tips from #thomas.mc.work I rewrote my code using a sub resource. It is better than the first solution since I get all methods from my sub resource and it only takes 4 lines of code per resource. This is how it looks like:
#Path("/users")
public class UserResource {
#Path("/{uid}/comments")
public CommentSubResource getCommentSubResource(#PathParam("uid") String uid) {
return new CommentSubResource("User", uid);
}
}
and this:
#Path("/items")
public class ItemResource {
#Path("/{uid}/comments")
public CommentSubResource getCommentSubResource(#PathParam("uid") String uid) {
return new CommentSubResource("Item", uid);
}
}
and this:
public class CommentSubResource {
private String entity;
private String entityUid;
public CommentSubResource(String entity, String entityUid) {
this.entity = entity;
this.entityUid = entityUid;
}
#GET
#Path("/")
#Produces(MediaType.APPLICATION_JSON)
public List<Comment> getComments() {
return commentService.getOnEntity(entity, entityUid);
}
#DELETE
#Path("/")
#Produces(MediaType.APPLICATION_JSON)
public List<Comment> deleteComment(#PathParam("uid") String uid) {
return commentService.delete(uid);
}
}
This is much better. I have an idea to use java 8 and default implementation interfaces to be able to just implmenet an interface to get the functionality, but I am not sure if I am able to determine which resource the default implemented method is called from.
Edit
After some laboration I think subresources is the way to go, even if it´s not (according to me) the perfect solution.
There is a similar feature called "Subresource Locators". You can decide in runtime which Resource is selected to process the request that is matching your JAX-RS method.
I'm new with Jersey Rest Framework and I wrote an simple demo to learn this skill. Here is my problem: I tried to reach my helloworld with this URL---
http://localhost:8080/PayInterface/query/helloworld
but didn't work. Would you please tell me what I did wrong?
I wrote a class:
#Component
//Declaring that all it will handle all requests starting by /TestCaseDto
#Path("query")
public class QueryApi {
#Path("/helloworld")
#GET
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public String test(){
return new String("Hello World!!!");
}
}
and I
A little more detail about this "dint work" would be nice
for starters- try changing your path above your class name like this
#Path("/query")
I think in here you return string. so you can't give produce type as xml,Try this
#Stateless
#Path("query")
public class QueryApi {
#Path("/helloworld")
#GET
#Produces({MediaType.APPLICATION_JSON})
public String test(){
return new String("Hello World!!!");
}
}