How to create a RESTful Web Service using Servlet (without Jersey, etc)? - java

How to use Servlet in creating a RESTful web service without using any JAX-RS implementation (Jersey, etc)?

Basically you absolutely right, you don't need a framework in order to implement REST API.
For instance, you could do basic crud operations in simple servlet class, like this:
#WebServlet(urlPatterns = "/book/*")
public class BookServlet extends HttpServlet {
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) {
// fetch from db
}
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response) {
//update
}
#Override
public void doDelete(HttpServletRequest request, HttpServletResponse responce) {
//delete
}
}
It's a little bit inconvenient since you need to manually parse url params, do serialization, but under the hood, JAXRS and Spring MVC is just a servlets!
So, if you don't want dependencies in your code, I could suggest to just implement some convenient wrappers over servlet api.
Tip: you could parse path params from request like this:
String info = request.getPathInfo();
String[] parts = pathInfo.split("/");
String param1 = pathInfo[0];
So, for instance, if you have request like this:
HTTP GET /book/{id}
You'll get {id} in param1 which can be later used in database lookup.

Related

Spring REST service using variable URL

I am trying to develop a RESTful app with Spring. The REST service must be parametrized in a database, I mean, a generic Service that can change the whole URL from a database info doing the same work but pointing to differents URL directions.
I was searching for info related for ages. Does anyone know about useful tutorial?
is it possible to do?
Thanks everyone!
You're better off creating a simple Servlet that will listen to a static root url and respond dynamically according to the database value.
public class Config {
public static String restPath = "valueReadFromDB";
}
#WebServlet("/appName")
public class AppServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
if (req.getURI().contains(Config.restPath) {
// add your logic
}
}
}
You can call this like so: http://your.host.name/appName/dynamicUrlReadFromDB
Don't blindly attempt to use Spring just because it is cool or fashionable. Sticking to the basics can always yield excellent results and allows for fine-grained control of your application something that Spring cannot always do.

Extract URL from HttpServletRequest

I am maintaining a Java servlet application and now have to extract the URL from the web service request to determine what action to take depending on what URL called the web service. I have found that it is something to do with HttpServletRequest which I have imported to the class. I have tried setting up the following inside the web service end point but it keeps telling me that the urlrequest is not initialised. What am I doing wrong?
HttpServletRequest urlrequest;
StringBuffer url = urlrequest.getRequestURL();
The HttpServletRequest you are using should be the input parameter HttpServletRequest of either doGet,doPut,doPost or doDelete.
Then Surely HttpServletRequest.getRequestURL will reconstruct the URL used by the client,excluding the query string parameters.
Your code is correct but it has to be accessed within the doPost(request, response), doGet(request, response) etc. methods of a class extending HttpServlet.
The reason for this is the when the service() method of HttpServlet is called, it populates the request and response objects for you given the client who prompted the request to your servlet.
You cannot define a variable in java and call a method on it without initializing it beforehand.
In the first line: HttpServletRequest urlrequest; you are just defining a variable. Since it is not initialized it is null and you cannot use it.
Remove this line and use the argument passed to the doGet (or doPost) method in your Servlet.
For example if your servlet is like this:
public class MyServlet extends HttpServlet {
...
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws Exception {
...
}
Instead of your code just add below line in the body of the doGet method:
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws Exception {
...
StringBuffer url = request.getRequestURL();
...
}
After this line you should be able to use the url variable.

Handle Jersey/JAX-RS REST manually

I'm building an application where I'd like to intercept HTTP requests and decide whether or not to pass them to a JAX-RS implementation for processing.
I basically have a single filter-and-front-controller-servlet combination and would like the servlet to delegate routing either to Jersey or to my "standard" router.
I can see lots of examples of using Jersey as a servlet, or of starting up an HTTP server, but there doesn't seem to be a handy way to take an HttpServletRequest/HttpServletResponse pair and say "here you go Jersey, route this for me".
Am I missing something obvious?
In this case, I think a RequestDispatcher might helps
A RequestDispatcher object can be used to forward a request to another resource, so you can try something like the following:
public class FrontServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext sc = this.getServletContext();
if (someCondition) {
sc.getRequestDispatcher("/jersey/servlet").forward(req, resp);
}else{
sc.getRequestDispatcher("/standard/router").forward(req, resp);
}
}
}

Java servlet annotations

Is there any way to use pure Java servlets not spring mvc request mapping to map a URL to a method?
something like:
#GET(/path/of/{id})
It's also possible with "plain vanilla" servlets (heck, Spring MVC and JAX-RS are also built on top of servlet API), it only requires a little bit more boilerplate.
#WebServlet("/path/of/*")
public class PathOfServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String id = request.getPathInfo().substring(1);
// ...
}
}
That's all. Thanks to the new Servlet 3.0 #WebServlet annotation, you don't need any web.xml entry.
See also:
Our Servlets wiki page

Proper scope for App Engine services

What is the proper scope for App Engine services when creating a servlet: static, instance, or local? And what are the implications of each? It seems like you should want to use them in as wide a scope as possible, to avoid the overhead of re-creating (or re-retrieving) them, but I wonder as to whether this will cause improper reuse of data, especially if <threadsafe>true</threadsafe>.
Examples of each scope are provided below. MemcacheService will be used in the examples below, but my question applies to any and all services (though I'm not sure if the answer depends on the service being used). I commonly use MemcacheService, DatastoreService, PersistenceManager, ChannelService, and UserService.
Static scope:
public class MyServlet extends HttpServlet {
private static MemcacheService memcacheService = MemcacheServiceFactory.getMemcacheService();
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
memcacheService.get("x");
}
}
Instance member:
public class MyServlet extends HttpServlet {
private MemcacheService memcacheService = MemcacheServiceFactory.getMemcacheService();
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
memcacheService.get("x");
}
}
Local scope:
public class MyServlet extends HttpServlet {
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
MemcacheService memcacheService = MemcacheServiceFactory.getMemcacheService();
memcacheService.get("x");
}
}
GAE is a distributed system where all of it's services run on separate servers. So when you invoke a service it internally serializes the request (afaik with protocol buffers) sends it to the server running the service, retrieves the result and deserializes it.
So all of *Service classes are basically pretty thin wrappers around serialization/deserialization code. See for example source of MemcacheService.
About scope: there is no need to optimize on *Service classes as they are pretty thin wrappers and creating them should take negligible time compared to whole service roundtrip.

Categories