How to keep the values of class variables in jersey web services - java

I have created a jersey web service as following,
#Path("/myservice")
class MywebService{
private int requestNum = 0;
#GET
#Path("/mymethod")
#Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public void myMethod(){
System.out.println("Request number : "+(++requestNum));
}
}
But each time when I call that myMethod through the web service , I get the request number as 1. Seems like the requestNum always resets to 0. Can anyone help me to solve this problem?

Try making it static, i.e.
static private int requestNum = 0;
The container (Jersey) is responsible for creating instances of your service. Thus you may have multiple different instances. Using an instance variable will not work well. The value of that variable will represent the number of times that instance has received a request.
If you use a static variable, that will count the number of requests sent to all instances of your web service class.

Related

How to get the count of number of active client requests for a GET method

Is there a way to find the number of active client requests currently accessing a GET method(getProducts()) in REST?
What I have is:
#GET
#Path("/products")
#Produces({ "application/xml" })
public Response getProducts(){
//My business logic to retrieve products go here
}
Now, I issue a GET request from the browser:
http://localhost:8080/v1/products
How to find the number of active client requests currently accessing getProducts() method at any point in time on the server side?
Pick one:
Write a Servlet Listener (implementing ServletRequestListener) that increments and decrements when the request is initialized and destroyed
Put the logic of counting directly into getProducts() method
Create an AOP advice that wraps getProducts() around and increments/decrements when the method is entered and exited
There are tools already written that can measure the performance (and the request counts). One of them: JETM.

Use variable between JAX-WS requests

I'm trying to do a web application using JAX -WS. My problem seems to be very simple, however I cannot understand how to resolve it. I have class variables which values I need to use in GET and POST requests. For example, I initiate 'response' in GET methode and I need to use it then in POST methode, but when I call POST api/conversation from js I receive an error because 'response' is still null. How can I save value for variables? Here is my code
import javax.ws.rs.*;
#ApplicationPath("api")
#Path("conversation")
public class Conversation {
private final String conversationWorkspace = "myworkspace";
private final static String CONVERSATION_ID = "myid";
private final static String CONVERSATION_PASS = "mypass";
private MessageRequest request;
private MessageResponse response;
private ConversationService service;
#GET
#Produces("application/text")
public String getInitiatePhrase(){
service = new ConversationService("2017-05-26", CONVERSATION_ID, CONVERSATION_PASS);
response = service.message(conversationWorkspace, null).execute(); //here response gets its value
return response.getText().get(0);
}
#POST
#Produces("application/text")
#Consumes("application/text")
public String getBotAnswer(String userText){
System.out.println("response " + response);
request = new MessageRequest.Builder().inputText(userText).context(response.getContext()).build(); //response must not be null
response = service.message(conversationWorkspace, request).execute();
return response.getText().get(0);
}
}
The Java class in question does not seem to be a container managed bean. When you make a rest service call to the GET and subsequently the POST methods, two separate instances of the Conversation class are created. Hence, the class field response will be null in the second POST call.
There are multiple ways to solve this problem. However, the approach to take depends on answering the question: Should the service really be aware of two separate client requests? Or should the client make one GET call and then provide the subsequent POST with the required information.
I would use approach 1 noted below, unless there is a good reason to use either 2, 3 or 4. (2, 3 and 4 are similar just they are different specifications / frameworks)
The client caches the response of the GET and sends the required information back with the POST request
Use an EE stateful session bean (http://docs.oracle.com/javaee/6/tutorial/doc/gipjg.html)
Use a CDI session scoped bean (http://docs.oracle.com/javaee/6/tutorial/doc/gjbbk.html)
Use spring session scoped bean (http://springinpractice.com/2008/05/08/session-scoped-beans-in-spring / https://tuhrig.de/making-a-spring-bean-session-scoped/)

CXF-Proxy Client and #Suspended AsyncResponse

I recently learned that with JAX-RS 2.0 long running service endpoints can make use of the #Suspended annotation and AsyncResponse to free resources for incoming requests while the actual work is done in the background. All client examples - at least the ones I found so far - are either calling such endpoints directly (plain http-call) or make use of the JAX-RS client API. However I was not able to figure out how to use this with the proxy-based API.
Given a REST endpoint that uses #Suspended:
public interface HeavyLiftingService {
#GET
#Path("/heavylifting")
public void heavyLifting(#Suspended final AsyncResponse aResponse);
}
its implementation using Spring:
#Component
public class HeavyLiftingServiceImpl implements HeavyLiftingService {
#Override
#Async
public void heavyLifting(#Suspended final AsyncResponse aResponse) {
final Result result = doHeavyLifting();
aResponse.resume(result);
}
}
And a proxy-based client, that wants to obtain the result:
HeavyLiftingService proxy = JAXRSClientFactory.create("https://some-server.xyz", HeavyLiftingService.class);
proxy.heavyLifting(null); // what to put in here?
Result result = null; // how can I get the result?
Obviously there are two problems:
What do I need to provide to the heavyLifting method as value for the AsyncResponse parameter?
How can I get the result as the return type of methods using #Suspended has to be void?
And another question is how exceptions in the service method are handled. Will an exception automatically resume the response and return a corresponding error status?

How to use two web methods for two different operations using Restful webservices?

I am using Jersey Restful webservices. I have below web method to get the results.
#Path("/persons")
public class PersonWS {
private final static Logger logger = LoggerFactory.getLogger(PersonWS.class);
#Autowired
private PersonService personService;
#GET
#Path("/{id}")
#Produces({MediaType.APPLICATION_XML})
public Person fetchPerson(#PathParam("id") Integer id) {
return personService.fetchPerson(id);
}
#DELETE
#Path("/{id}")
public void deletePerson(#PathParam("id") Integer id) {
return personService.deletePerson(id);
}
}
In above Jersey RESTful webservice, i have two web methods one for get and one more for delete with same number of parameters. In above case will there be any ambiguity? If not what should be the URIs for both of the methods? Thanks!
Thanks!
Jersey decides which method to call based on the HTTP method specified in the request. If you use multiple methods with the same HTTP method like GET, then the choice is made by more Annotations like Consumes or Produces etc.
BTW: If you use the URI /persons/{id} for all endpoints, then you can annotate your class with #Path("/persons/{id}") instead of annotating every method with this sub-URI.
There is no ambiguity as the HTTP Method is different (GET vs DELETE).
The same url would also be used to update the object, using the HTTP method PUT
No ambiguity since the HTTP methods used are different i.e GET and DELETE
And the urls will be same as the param required is "id" for both
IN Jersey client program use GET http method for fetching person info, Use DELETE http method for deleting the person.

Save Web Service variable into MuleSoft Message

I have an http endpoint redirecting to a REST Java web service.
I am receiving a application/x-www-form-urlencoded request with some attributes embedded within the body of the request.
Inside the web service I would like to update the mule message status with those attributes.
Since RequestContext.getEventContext() is now deprecated and Doc says to implement Callable instead, however seems not working to me.The onCall method is never invoked.
Any idea ?
Below my code:
enter code here
#Path("/restClass")
public class HelloREST implements Callable{
private String industry;
private String lob;
private String nuixlegalentity;
private org.apache.log4j.Logger log = Logger.getLogger(LoadClass.class);
#POST
#Path("/setPayload")
#Consumes("application/x-www-form-urlencoded")
public void setMessage(#FormParam("industry") String industryParam, #FormParam("lob") String lobParam,#FormParam("nuixlegalentity") String nuixlegalentityParam){
log.debug("**************INSIDE SETMESSAGE******************");
industry=industryParam;
lob=lobParam;
nuixlegalentity=nuixlegalentityParam;
}
#Override
public Object onCall(MuleEventContext eventContext) throws Exception{
log.debug("**************INSIDE ONCALL******************");
eventContext.getSession().setProperty("industry","industry");
eventContext.getSession().setProperty("lob",lob);
eventContext.getSession().setProperty("nuixlegalentity",nuixlegalentity);
return eventContext.getMessage();
}
}
}
I assume you're using this class as a resource with the Jersey transport. In that case, Mule will call the JAX-RS annotated methods, based on the incoming request, and thus will not call onCall. Therefore implementing Callable is of no use.
Using RequestContext.getEventContext() is the only way possible to get the EventContext in a Jersey-handled resource.
To this date, MuleSoft hasn't provided a workable replacement for cases like this one so, even if RequestContext.getEventContext() is deprecated, you unfortunately have no other choice than using it.

Categories