From jersey rest application, I can't get the right URL - java

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!!!");
}
}

Related

Method not allowed when using regex in #Path with jersey

I am trying to provide endpoints that will listen on multiple versions, i.e /v1/test and /v2/test. In order not to duplicate my code, I use jersey's ability to use patterns in the #Path annotation.
Let's assume I want to provide a GET and a POST endpoint:
#Controller
#Slf4j
#Path("/")
public class TestController {
#GET
#Path("/v{version:[12]}/test")
#Produces(MediaType.APPLICATION_JSON)
public String test1(#PathParam("version") String version) {
System.out.println(String.format("GET /v%s/test called", version));
return "{\"foo\":\"bar\"}";
}
#POST
#Path("/v{version:[12]}/test")
#Produces(MediaType.APPLICATION_JSON)
public String test2(#PathParam("version") String version) {
System.out.println(String.format("POST /v%s/test called", version));
return "{\"foo\":\"bar\"}";
}
}
That works fine.
If I, however, try to use a specific path for the GET endpoints and use a pattern for the POST endpoint, I run into trouble.
Here the controller that would not work:
#Controller
#Slf4j
#Path("/")
public class TestController {
#GET
#Path("/v1/test")
#Produces(MediaType.APPLICATION_JSON)
public String test1() {
System.out.println("GET /v1/test called");
return "{\"foo\":\"bar1\"}";
}
#GET
#Path("/v2/test")
#Produces(MediaType.APPLICATION_JSON)
public String test2() {
System.out.println("GET /v2/test called");
return "{\"foo\":\"bar2\"}";
}
#POST
#Path("/v{version:[12]}/test")
#Produces(MediaType.APPLICATION_JSON)
public String test3(#PathParam("version") String version) {
System.out.println(String.format("POST /v%s/test called", version));
return "{\"foo\":\"barPOST\"}";
}
}
Doing GET /v1/test or GET /v2/test works fine, POST /v1/test however does not.
I get a 405 Method Not Allowed Exception.
As far as I got it the exception is thrown in the MethodSelectingRouter when it recognizes the path, but cannot find a method with the appropriate HTTP verb.
The issue seems to be that it picks the most specific path (/v1/test in my case) for which it does not know the POST verb.
Does anybody have an idea how to avoid this problem?
Cheers
PS: I am using spring boot with jersey (i.e. spring-boot-starter-web and spring-boot-starter-jersey) in version 1.5.2.RELEASE

What can i use for #Path("/*") working?

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: .*}")

How to reuse a REST methods in different resources?

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.

Finding a method exists in rest service or not in Java

Hi i am new to Rest Service in Java. First i want to explain my problem and then at the end i will be asking question.
I am using Mozilla rest CLIENT. My rest class looks like:
#Path("/api1")
public class RestService {
#POST
#Path("/v1")
#Consumes("application/json")
#Produces("application/json")
public String v1(String json){
//Some code here
}
#POST
#Path("/v2")
#Consumes("application/json")
#Produces("application/json")
public String v2(String json){
//Some code here
}
}
Now in this code i have two functions.
To access v1, call will be:
http://localhost:8080/project_name/package/api1/v1
To access v2 call will be:
http://localhost:8080/project_name/package/api1/v2
Question:
Now in my rest service class i want to add a patch of code which detects that whether any function which has been called either v1,v2 or v3 exists in this service or not?
Can i do this? Or anyother way to do this?
Thanks
Well, you could add a wildcard response:
#POST
#Path("/{what}")
#Consumes("application/json")
#Produces("application/json")
public String v2(String json, #PathParameter("what") String what){
return "The path "+what+" does not exist.";
}
However, since the user will never see the direct responses, you can answer with a customized 404:
#POST
#Path("/{what}")
#Consumes("application/json")
#Produces("application/json")
public Response v2(String json, #PathParameter("what") String what){
return Response.status(Status.NOT_FOUND).entity("The path "+what+" does not exist.");
}
This way you can also detect on the client side when something is incorrect.
The best approach for you is to add a fallback response. That will be called when somebody tries to access any non existing WS method.
#RequestMapping(value = {"*"})
public String getFallback()
{
return "This is a fallback response!";
}

Grizzly Jersey - Only #Path("/") works

I try to run a Jersey(1.17) resource on a Grizzly(2.2.21) server using HTTPS and Basic Auth and get everything working except the resource.
#Path("/")
public class Helloworld {
#GET
public String helloworld2() {
return "asdf2";
}
#Path("helloworld")
#GET
public String helloworld() {
return "asdf";
}
}
Yea it's just the Helloworld example and it still freaks me out.
I can access localhost:port/ and it works fine, but localhost:port/somethingother also returns "asdf2". Especially localhost:port/helloworld also returns "asdf2".
I also tryed
#Path("/")
public class Helloworld {
#GET
#Path("/helloworld")
public String helloworld() {
return "asdf";
}
}
and
#Path("/helloworld")
public class Helloworld {
#GET
public String helloworld() {
return "asdf";
}
}
In both cases i get 404 in Firebug for every request.
Does someone has a solution?
Thx
Edit:
To create the server and so on i use this example code (without the server truststore):
https://svn.java.net/svn/jersey~svn/trunk/jersey/samples/https-clientserver-grizzly/src/main/java/com/sun/jersey/samples/https_grizzly/
adding registration.addMapping("/*"); to my initialization code worked.
Thanks ver much alexey

Categories