I managed to build a small REST API using eclipse. The following code works:
#Path("Info")
public class Rest {
#POST
#Path("/stats/{j}")
#Produces("application/json")
public Response Status(#PathParam("j") String j) throws JSONException{
JSONObject jsonObject = new JSONObject();
String status = j;
.
.
return Response.status(200).entity(result).build();
}
}
Could you advise me on how make this a multithreaded? I have an idea of what is multithreaded but I need some input on how to go about creating this code as multithreaded. was thinking of creating another class that implements Runnable:
class Demo implements Runnable {
.
.
}
Then, in my function Status(#PathParam("j") String j), I create an object of class Demo, For example:
public Response Status(#PathParam("j") String j) throws JSONException{
Demo newThread = new Demo();
JSONObject jsonObject = new JSONObject();
String status = j;
.
.
return Response.status(200).entity(result).build();
}
}
Thank you in advance!
It already is multithreaded.
When deploying the application into an application server such as Jetty or Tomcat the thread pool of the application determines how many threads will be used to serve web request. Every time a user makes a new web request against your controller method, one of the available threads from the application server threadpool will be used.
Related
I'm using JAVA/Spring MVC and I need to make a Connection Pool for a Third Party Application integration in my application becouse when i try to connect it multiple time my application and server System utilize 100% RAM.
here i have to problem, when users start to hit a specific method (callGenerationService()) multiple time, my Heap memory(RAM space) increases and becomes 100% and application going to slow becouse of it connect third party application multiple times ? here i need to create a connection only once and get it multiple times. where my connection like,
public class ClickToCallServiceImpl implements ClickToCallServiceInterface {
Client client = null;
#Override
public ClickToCall callGenerationService(ClickToCall clickToCall) {
client = new Client();
client.connect("127.0.0.1", 8021 , "password", 10); //Every time Connection Connect.
client.setEventSubscriptions("plain", "all");
// client.sendSyncApiCommand("",""); //here i run command on every hit like.
client.sendSyncApiCommand(clickToCall.command1, clickToCall.command2);
client.close();
}
}
and here 'ClickToCall' is a #Component Bean/POJO Class with variables setters and getters.
Is there, how to we create a connection (either pool or only once connect) for above connection where i connect only once and hit clickToCall.Command1 and clickToCall.Command2 multiple times and utilize less RAM? Thanks in advance.
Please note that I'm not an expert of freeswitch esl so you must check the code properly. Anyway this is what I would do.
First I create a Factory for Client
public class FreeSwitchEslClientFactory extends BasePooledObjectFactory<Client> {
#Override
public Client create() throws Exception {
//Create and connect: NOTE I'M NOT AN EXPERT OF ESL FREESWITCH SO YOU MUST CHECK IT PROPERLY
Client client = new Client();
client.connect("127.0.0.1", 8021 , "password", 10);
client.setEventSubscriptions("plain", "all");
return client;
}
#Override
public PooledObject<Client> wrap(Client obj) {
return new DefaultPooledObject<Client>(obj);
}
}
Then I create a shareable GenericObjectPool:
#Configuration
#ComponentScan(basePackages= {"it.olgna.spring.pool"})
public class CommonPoolConfig {
#Bean("clientPool")
public GenericObjectPool<Client> clientPool(){
GenericObjectPool<Client> result = new GenericObjectPool<Client>(new FreeSwitchEslClientFactory());
//Pool config e.g. max pool dimension
result.setMaxTotal(20);
return result;
}
}
Finally I use the created pool in order to get the Client obj:
#Component
public class FreeSwitchEslCommandSender {
#Autowired
#Qualifier("clientPool")
private GenericObjectPool<Client> pool;
public void sendCommand(String command, String param) throws Exception{
Client client = null;
try {
client = pool.borrowObject();
client.sendSyncApiCommand(command, param);
} finally {
if( client != null ) {
client.close();
}
pool.returnObject(client);
}
}
}
I didn't test (also because I can't) it but it should work. In any case I pray you to properly check the configuration. I don't know if it's OK to always create a Client object and connect or if it's better to connect when you want to send command
I hope it can be useful
EDIT INFORMATION
Sorry I made an error early. You must return the client to the pool
I updated my FreeSwitchEslCommandSender class
Angelo
I'm doing an API in my web system because of a task in university. The problem is that I'm not able to do a specific part and I think that it's very easy.
The statement says:
*GET /rest/api/v1/tfg?State = ${state}
List of all TFGs in the indicated state. You can indicate different states at the same time. To do this, you must repeat the state parameter multiple times (such as: "?State=state1&State=state2&State=state3"), and the web service will return all those who are in any of these states.*
I have a DB with projects (TFGs) and I know how to get this data, but the problems are that I don't know what to do to detect ? in URL, and how can I do to read different parameters depending on the quantity. It's possible to have one state or N states. How can I do it?
The current code is this:
#Path("/rest/api/v1/tfg")
public class TfgREST {
#GET
#Path("")
#Produces(MediaType.APPLICATION_JSON)
public Response findAll() throws ServletException, IOException {
TfgDao dao = new TfgDao();
LinkedList<Projecte> llista = dao.findAll(true); //TRUE because of API
JsonArrayBuilder array = Json.createArrayBuilder();
for(Projecte p : llista){
array.add(p.getTitol());
}
return Response.ok(array.build()).build();
}
#GET
#Path("/?state={state}")
#Produces(MediaType.APPLICATION_JSON)
public Response findByState(#PathParam("state") String state) throws ServletException, IOException {
TfgDao dao = new TfgDao();
LinkedList<String> llista = dao.findByState(state);
//JsonObjectBuilder jo = Json.createObjectBuilder();
JsonArrayBuilder array = Json.createArrayBuilder();
for(String p : llista){
array.add(p);
}
return Response.ok(array.build()).build();
}
If I call http://...../rest/api/v1/tfg?State=XXXX, web invokes the first one (findAll) but, if I use /rest/api/v1/tfg/State=XXX it works...
Thanks for all! I'm waiting for your answers.
Miquel
Because REST API follows resource.
if "state" is a object, you can use /rest/api/v1/tfg/State=XXX
BUT if "state" is only a property of tfg, you use /rest/api/v1/tfg?State=XXX
Ok guys, now it's working. I publish the solution in order to contribute with you and try to solve this problem in a future for other people.
I mixed both methods in one implemeting an if.
The code is the following:
#Path("/rest/api/v1/tfg")
public class TfgREST {
#GET
#Path("")
#Produces(MediaType.APPLICATION_JSON)
public Response findAll(#QueryParam("state") List<String> state) throws ServletException, IOException {
TfgDao dao = new TfgDao();
JsonArrayBuilder array = Json.createArrayBuilder();
if(state.isEmpty()){
LinkedList<Projecte> llista = dao.findAll(true); //TRUE because of API
for(Projecte p : llista){
array.add(p.getTitol());
}
}
else{
LinkedList<String> projs;
for (String s : state){
projs = dao.findByState(s);
for (String x : projs){
array.add(x);
}
}
}
return Response.ok(array.build()).build();
}
}
Thanks for your contributions, I finally got it, and it has been very easy!
I have a REST Service method and need to load test it.
Unfortunately i don't have admin rights to my laptop and can not install/download any tool.
Need to know the capacity of the REST service (web project in tomcat) like how many concurrent requests it can handle. I don't require any other information or details.
Here are some details about the REST api:
Method: POST
Technology: Spring MVC
Response object is very complex and huge form, requiring 100's of objects.
Is there any way to do it using core java application (post to a REST URL, get the response, and find maximum concurrent requests supported by API)
In core java i can use apache http, spring or core java 7/8
I am able to do load testing using following code using java 7 Executors and URLConnection :
public class POSTProcessor {
class ManagedProcessor implements Callable {
public void postMessage() {
//Test execute single call for REST web service with URLConnection
}
#Override
public Object call() throws Exception {
postMessage();
return null;
}
}
public static void main(String[] args) {
long time1 = System.currentTimeMillis();
int size = 200;
ExecutorService loadExecutor = Executors.newFixedThreadPool(size);
POSTProcessor threadRunner = new POSTProcessor();
List jobs = new ArrayList();
for(int i=0;i<size;i++){
ManagedProcessor exec = threadRunner.new ManagedProcessor() ;
jobs.add(exec);
}
try {
loadExecutor.invokeAll(jobs);
} catch (InterruptedException e) {
e.printStackTrace();
}
long time2 = System.currentTimeMillis();
System.out.println("Time delay: " + ( (time2 - time1)/size));
loadExecutor.shutdown();
}
}
I am trying to follow the first part of jersey tutorial using Grizzly as the web container. I am just at the "Hello World!" part and trying to run my code. This is the main of the web services that I am trying to deploy.
public class Main {
public static void main(String [] args) throws IOException {
final String baseUri = "http://localhost:9998";
final Map<String, String > initParams = new HashMap<String, String>();
initParams.put("com.sun.jersey.config.property.packages", "com.sun.ws.rest.samples.helloworld.resources");
System.out.println("Starting grizzly");
SelectorThread threadSelector = GrizzlyWebContainerFactory.create(baseUri,initParams);
System.out.println(String.format("Jersey app started with WADL available at %sapplication.wadl Try out %shelloworld. Hit enter to stop it...", baseUri, baseUri));
System.in.read();
threadSelector.stopEndpoint();
System.exit(0);
}
}
When I run this, I always get
Exception in thread "main" java.lang.IllegalArgumentException: The URI path, of the URI http://localhost:9998, must be present
at com.sun.jersey.api.container.grizzly.GrizzlyWebContainerFactory.create(GrizzlyWebContainerFactory.java:236)
at com.sun.jersey.api.container.grizzly.GrizzlyWebContainerFactory.create(GrizzlyWebContainerFactory.java:138)
at com.sun.jersey.api.container.grizzly.GrizzlyWebContainerFactory.create(GrizzlyWebContainerFactory.java:105)
at Main.main(Main.java:29)
Does anyone know what is happening? I have made sure that my packages are all correct. I do not know how to configure grizzly and just trying to learn how to use Jersey
final String baseUri = "http://localhost:9998/";
Note the / on the end; you're missing it.
I want to generate a client program using the service
I am unable to display the results, how can I do so?
import java.rmi.RemoteException;
public class searchtry {
public static void main(String[] args) throws RemoteException {
SearchRequest request=new SearchRequest();
SearchRequestType1 type1=new SearchRequestType1();
query.setAppId("*********************************"); //Windows Live gave this id for using that service
query.setSources(new SourceType[]{SourceType.Web});
query.setQuery("Java");
aratip.setParameters(request);
SearchResponseType0 answer= client.search(type1);
System.out.println(answer.toString());
}
For starters, calling
answer.toString();
May or may not result in anything (usually won't). You might just get a string that represents the instance, not the string you're expecting. You need to find a method on SearchResponseType0 that will give you the string representation of the response. Perhaps a method like getContent() or getResponse() or something like that but without understanding more about the web service it's difficult to give you more help. Bottom line, you're using the wrong method to attempt to get the string content of the result.
It looks like your are using the bing-search-java-sdk. They have a very nice example on their homepage you might want to look at:
BingSearchServiceClientFactory factory = BingSearchServiceClientFactory.newInstance();
BingSearchClient client = factory.createBingSearchClient();
SearchRequestBuilder builder = client.newSearchRequestBuilder();
builder.withAppId(applicationId);
builder.withQuery("msdn blogs");
builder.withSourceType(SourceType.WEB);
builder.withVersion("2.0");
builder.withMarket("en-us");
builder.withAdultOption(AdultOption.MODERATE);
builder.withSearchOption(SearchOption.ENABLE_HIGHLIGHTING);
builder.withWebRequestCount(10L);
builder.withWebRequestOffset(0L);
builder.withWebRequestSearchOption(WebSearchOption.DISABLE_HOST_COLLAPSING);
builder.withWebRequestSearchOption(WebSearchOption.DISABLE_QUERY_ALTERATIONS);
SearchResponse response = client.search(builder.getResult());
for (WebResult result : response.getWeb().getResults()) {
System.out.println(result.getTitle());
System.out.println(result.getDescription());
System.out.println(result.getUrl());
System.out.println(result.getDateTime());
}