0

I am developing a rest server in java, netbeans.

I made my first get method and my class looks like this:

@Stateless
@Path("v1/cardapio")
public class CardapioResource {

    private Gson gson = new Gson();

    @EJB
    private CardapioRemote ejb;

    public CardapioResource() {}

    @GET
    @Produces("application/json")
    @Path("/")
    public String getCardapios(@QueryParam("key") String key) {
        Conta c = ContaDAO.busca(key);

        JsonObject obj = new JsonObject();
        if(c != null){
            JsonArray array = (JsonArray) gson.toJsonTree(ejb.findAll());
            obj.add("dados", array);
        } else{
            JsonObject status = new JsonObject();
            status.addProperty("codigo", 401);
            status.addProperty("mensagem", "Não há nenhum ID correspondente a este KEY");
            obj.add("status", status); 
        }
        return obj.toString();
    }

    @GET
    @Produces("application/json")
    @Path("/")
    public String getCardapios(@QueryParam("key") String key, @QueryParam("id") String id) {
        // second method
    }
}

The above method is responsible for validating a fkey in the database and if it is valid returns a list of menus.

So I tried to do the second method, get an id ... and after validated it would return only the menu of the given id. My class looks like this:

@Stateless
@Path("v1/cardapio")
public class CardapioResource {

    private Gson gson = new Gson();

    @EJB
    private CardapioRemote ejb;

    public CardapioResource() {}

    @GET
    @Produces("application/json")
    @Path("/")
    public String getCardapios(@QueryParam("key") String key) {
      // first method   
    }

    @GET
    @Produces("application/json")
    @Path("/")
    public String getCardapios(@QueryParam("key") String key, 
                               @QueryParam("id") String id   ) {
        Conta c = ContaDAO.busca(key);

        JsonObject obj = new JsonObject();
        if(c != null){
            JsonArray array = (JsonArray) gson.toJsonTree(ejb.findById(Integer.parseInt(id)));
            obj.add("dados", array);
        } else{  
            JsonObject status = new JsonObject();
            status.addProperty("codigo", 401);
            status.addProperty("mensagem", "Não há nenhum ID correspondente a este KEY");
            obj.add("status", status); 
        }
        return obj.toString();
    }
}

After the inclusion of this second method an exception is occurring :

WebModule[/webPlataformaCardapio]StandardWrapper.Throwable [FATAL] A resource model has ambiguous (sub-)resource method for HTTP method GET and input mime-types as defined by @Consumes and @Produces annotations at Java methods public java.lang.String ws.CardapioResource.getCardapios(java.lang.String) and public java.lang.String ws.CardapioResource.getCardapios(java.lang.String,java.lang.String) at matching regular expression /. These two methods produces and consumes exactly the same mime-types and therefore their invocation as a resource methods will always fail.; source='org.glassfish.jersey.server.model.RuntimeResource@4fef476']

Imagine I have a server url servidor:porta/api/produtos?key=1 that validates the key and returns all products ... and I can have the servidor:porta/api/produtos?key=1&id=5 that validates the key and returns only product 5. Both have the same path, with no divisions of "/".

How can I solve?

1 Answers1

1

Your error message is clear:

These two methods produces and consumes exactly the same mime-types and therefore their invocation as a resource methods will always fail

You listen to the same path, same HTTP method and mime type for input/output.

You need to make them different so your server can clearly decide which method to call

You could for example add an id to the path of the second method.

@GET
@Produces("application/json")
@Path("/id")
public String getCardapios(@QueryParam("key") String key, 
                           @QueryParam("id") String id   ) {
...
}

But if you want to have only one path, you can create two business methods, one that handles only the key and the other that handles the key and the id.

private void businessMethod1(String key) {
    // do your stuff
}

private void businessMethod2(String key, String id) {
    // do your stuff
}

@GET
@Produces("application/json")
@Path("/")
public String getCardapios(@QueryParam("key") String key, 
                           @QueryParam("id") String id   ) {
    if(id == null) {
        businessMethod1(key);
    } else {
        businessMethod2(key, id);
    }
}
Arnaud Claudel
  • 3,000
  • 19
  • 25
  • But the methods I find on the internet are usually like this... "servidor:porta/v1/consumos/?api_key=GUID&codigo=string&modo_venda=(1 à 4)&ticket_id=GUID&item_id=GUID" ... there is no "/". How can I make various methods using only "&"? – Júlio César Bindandi Aug 08 '19 at 18:10
  • `servidor:porta/v1/consumos/` is the path and `?api_key=GUID&codigo=string&modo_venda=(1 à 4)&ticket_id=GUID&item_id=GUID` are the parameters. In your case, you only have one path, which is why you get en error. - If it's unclear, post the url you want to use to access to your application – Arnaud Claudel Aug 08 '19 at 18:12
  • Got it. Imagine the following, I can do like this:"server:port/v1/consumes/?Api_key=GUID&code = string" or "server:port/v1/consumes/?Api_key= GUID&code=string&sales_modem=1... both would have the same address ... but in my head would be two methods, no? – Júlio César Bindandi Aug 08 '19 at 18:37
  • No, it's a single method but only for getCardapios. You can create two business methods, one that takes 2 parameters and one that take 3. I'll update my anwser – Arnaud Claudel Aug 09 '19 at 07:28