Use servlet to connect to Elasticsearch - servlets

elasticsearch-transport-wares
I don't understand, how to use this plugin...
I want use the servlet go to connect elasticsearch and operate...
My environment only apache tomcat servlet, please help me, Thanks.

The idea is that you modify your Maven pom.xmlby adding the following dependency (make sure to use the right version depending on the version of ES you're running):
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch-transport-wares</artifactId>
<version>2.7.0</version>
</dependency>
The JAR file of elasticsearch-transport-wares will ultimately end up in your WEB-INF/lib folder.
Then in your web.xml, you add a new <servlet> and <servlet-mapping> like this:
<servlet>
<servlet-name>esnode</servlet-name>
<servlet-class>org.elasticsearch.wares.NodeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>esnode</servlet-name>
<url-pattern>/es/*</url-pattern> <---- you can change this pattern
</servlet-mapping>
This will instantiate a new servlet serving requests on the http://server:8080/es/ path and proxying them to your local embedded Elasticsearch node, which means you can query ES through your web app, .e.g.:
curl -XGET http://server:8080/es/your_index/your_type/_search?q=*
The above query will be equivalent to querying an external ES cluster directly using
curl -XGET http://localhost:9200/your_index/your_type/_search?q=*
The main difference is that you can also query ES internally from anywhere within your web app (where you have access to the ServletContext) by retrieving the Elasticsearch node that has been created in the servlet context, using:
Node node = getServletContext().getAttribute("elasticsearchNode")
Finally, you can store the Elasticsearch configuration for your node either /WEB-INF/elasticsearch.json or in /WEB-INF/elasticsearch.yml.

Related

How to handler HTTP Request with # character in URL

My customer sent one HTTP request with URL http://example.com/callback#id_token=data
Now I need handle this request and get data of "id_token".
Please help me handle this request using Java web project.
I tried with servlet but not get data of "id_token"
My servlet is below
<servlet>
<servlet-name>callback</servlet-name>
<servlet-class>com.admin.controller.CallbackServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>callback</servlet-name>
<url-pattern>/callback</url-pattern>
</servlet-mapping>
Thanks a lot.
Unless url-encoded, the hash #id_token=data usually ends up in document.location.hash on the client side.
console.log(document.location.hash);//#id_token=data
var hash = document.location.hash;
var split = hash.split('=');
console.log(split[0]);//#id_token
console.log(split[1]);//data
You can usually access the console with F12, tab "console".

Filter Liferay HttpRequest

I would like to filter (modify) HttpRequest, which is coming to target Liferay Servlet, intercept it and add some attributes. (for example User) and then redirect (forward) the request to the target servlet. I create new servlet that should work like interceptor, add the attribute (request.setAttribute("user", User)) and then either dispatcher.forward or response.redirect... This is only for testing purposes to be able to call some liferay functionality from tests.
The problem is that Liferay is filtering the request and add there its 7 attributes. I tried also create SimpleFilter, but its not called when target servlet is called, only when I create my own Servlet which extends HttpServlet.
So the question is, is it possible to tell liferay not to filter the requests or more important not to remove the attributes from the request? I have debugged the Liferay source code, catch the Filter Chain and on the 1. filter I see there original request, and at the end the requests contains those Liferay attributes.
Many thanks.
The target servlet is defined like this:
<servlet>
<servlet-name>targetServlet</servlet-name>
<servlet-class>com.liferay.portal.kernel.servlet.PortalDelegateServlet</servlet-class>
<init-param>
<param-name>servlet-class</param-name>
<param-value>org.springframework.web.context.support.HttpRequestHandlerServlet</param-value>
</init-param>
<init-param>
<param-name>sub-context</param-name>
<param-value>targetServlet</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

HTTPListener and servlet

We have an servlet which sends messages to a queue.
It gets the message from a request object it got from Paypal.
The servlet is called IPNServlet.
Note that this is a standalone servlet which is not a part of any MDB.
For some reason the following mapping in my web.xml does not work (requests to this servlet bundled in the WAR file on JBoss EAP 5.1 are not handled)
<servlet-name>IPNServlet</servlet-name>
<servlet-class>com.temenos.paypal.servlet.IPNServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<servlet-mapping>IPNServlet</servlet-mapping>
<url-pattern>/IPNServlet</url-pattern>
By the way of this web.xml, shouldnt a request made to https:// HOSTNM:8443/IPNServlet be processed as expected ?
Where HOSTNM is the name of the IP.
Is there a separate HTTP Listener that is needed ?

Collaboration from PlayN client with server

I have written a game in PlayN, which has to communicate with a JavaEE-Server with Seam.
First of all I only need the game running in HTML5.
The current issue is the communication between the PlayN-client and the JavaEE-Server
1) First I tried to communicate over the PlayN.net() interface exchanging information using JSON. Since PlayN is running on port 8888 and the server on 8080 I correctly run into problems with the same-origin-policy.
2) Now I'm looking for a working solution. Which one would you recommend? Do you have other ideas?
a) I'm trying to work with RPC as described in How to handle RPCs in client-server PlayN game?
, using GWT-syncproxy.
b) I try that playN runs on the same port as the server i.e. 8080 - so I don't have problems with the same-origin-policy any more. Question: Can the HTML5 playN app run on the same port?
So when I start the JavaEE-Server using Eclipse it should also start the PlayN web application, both on port 8080, right?
Is this possible?
c) The most hacky solution (currently working): The server writes the JSON-String into a file and the playN client reads this file out.
What do you recommend? I'd like to implement solution 2, since it is the cleanest solution, but I don't know how hard it is and how it works.
Thanks for your help!
I think the problem is that you are "running" PlayN, separated from your Seam server.
If I understood you correctly, you execute the Maven task to run your game as HTML and on the other hand you run Jboss (or whatever Java EE server), what you should do is run
mvn package
which will create the war of the game, and then publish that war on your Java EE server, then you can use the PlayN.net package with no problems whatsoever, running in a single server
This is how we currently handle our client / server communication. We are using a stateless JavaEE architecture and provide everything as REST services. This allows us to scale horizontally by adding more servers and simply adding them to the cluster entry in the Glassfish config.
However due to missing reflection or a working JSON lib, it forces us to implement a toJson()method in every data transfer object BY HAND (be carfull with case sensitivity). We added our server project as a module to the PlayN metaproject and added the core as a dependency to the server. So you can place every DTO on the core project (which is quite awesome). Placing them on the server results in people trying to annotate the classes as entities, which will result in failure during the html build. I am currently thinking about adding a shared project to the build, like in GWT projects.
This is how we send data to the server (for this example without any abstraction, do yourself a favor and implement one):
private void loadMapFromServer() {
SessionDto session = this.main.getSessionCtrl().getSessionMdl();
PlayN.net().post("http://localhost:8080/server/rest/map/mapMdl",
session.toJson(),
new Callback<String>() {
#Override
public void onSuccess(String result) {
mapMdl = new MapDto();
}
#Override
public void onFailure(Throwable cause) {
PlayN.log().error("fail " + cause.getMessage());
}
});
}
Notice how we bastardize the POST argument with session.toJson(). This is because of the missing MIME type feature and passing JSON strings via GWT will fail.
And this is how it looks on the server:
package com.fact.server;
//I also posted the imports, for clarity.
import com.fact.core.map.MapDto;
import com.fact.core.user.SessionDto;
import com.fact.server.game.map.MapCtrl;
import com.google.gson.Gson;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.apache.log4j.Logger;
#Stateless
#Path("/map")
public class MapSrvs {
#Inject
Logger logger;
#Inject
MapCtrl mapCtrl;
Gson gson = new Gson();
#POST
#Path("/mapMdl/")
#Produces( MediaType.APPLICATION_JSON )
public MapDto getMapMdl(String sessionDtoStr) {
//logger.info("map was requested: " + sessionDtoStr);
// Use gson to deserialize the class. Jersey would do this, if PlayN
// would allow to set a correct MIME type (and #Consumes was set).
// We could simply write: getMapMdl(SessionDto sessionDto)
SessionDto sessionDto = gson.fromJson(sessionDtoStr, SessionDto.class);
if(sessionDto == null) {
return null;
}
// [...] check for a valid session
MapDto mapMdl = new MapDto();
mapMdl.foo = "message from server";
return mapMdl;
}
}
This would be a bit nicer, if PlayN would allow you to set the MIME type, so that you won't have to cast the String using Gson. However this works quite well. We use Jersey on the server side to handle all the REST stuff. To get it running I had to put the following into the web.xml:
<servlet>
<!-- We need jersey for the REST stuff -->
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>
com.sun.jersey.spi.container.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.fact.server</param-value>
</init-param>
<init-param>
<!-- This took me hours to find :(. It is needed to automatically
map POJOs to JSON code. -->
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Also Jersey is already included into the Java-EE-Api, so it works out of the box. I hope this helps. If anyone knows how to do client side JSON parsing , please look at this question: How do I convert a POJO to JSON in PlayN?

Servlet Mapping URL pattern

webapps
|
|----helloworld
|
|----WEB-INF
|
|-----classes-HelloWorldServlet.class
|-----lib----servlet-api.jar
|-----web.xml
The above is my directory structure. Now in web.xml i don't know what to give in url-pattern for servlet mapping. What should i give there? Which is the url pattern?
The mechanism for mapping servlets is not relevant to the directory structure, as skaffman noted.
Basically, you have two things in web.xml (regarding servlets):
the <servlet> tag, which defines the alias for the servlet, and its fully-qualified name (for example com.foo.pkg.YourServlet)
the <servlet-mapping> which specifies a url-pattern for a given alias (taken from the <servlet> definitions).
As the name suggest, the url-pattern denotes what URL portion should make the servlet be called. So if you map a given servlet to the url-pattern /myfirstserlet, it will be accessible when the user opens http://localhost:8080/helloword/myfirstservlet, where the first part is the host name and the port, followed by the context name (the name of your webapp), and then the url-pattern
Note: you are currently using the default package (i.e. no package) for your servlet. This is discouraged, so give it some package name. (and put it in WEB-INF/classes/com/foo/pkg/). This is done via specifying package com.foo.pkg;

Resources