Proper scope for App Engine services - java

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.

Related

Web applications: servlet thread safety using singleton pattern

I'm looking to hopefully get into web application programming using Java, coming from a PHP/Laravel background (I have some Java experience having studied it around about 8 years ago at university).
I've been playing around for a while and feel fairly comfortable with most of the foundational concepts such as Servlets and Servlet containers as well as some popular web server/servlet container technologies used such as Jetty, Tomcat etc. I've also tried to do quite a bit of research into Java EE.
Now since I want to build up my knowledge on the subject, I don't want to use any frameworks, in fact I would like to look to build my own as a learning exercise. However, I've also looked quite a bit into some of the frameworks around, such as Spring MVC, Struts, Play and Vaadin etc.
So I've got a Maven project set up, I have a web.xml file set up pointing at a servlet that I have created and I am looking to build an entry point into my "framework".
src/main/webapp/WEB-INF/web.xml
<servlet>
<servlet-name>Application</servlet-name>
<servlet-class>com.mypackage.Application</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Application</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
src/main/java/com/mypackage/Application.java
package com.mypackage;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class Application extends HttpServlet {
#Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//
}
}
So now I want to make my own IoC container that uses the singleton pattern (I know this is usually discouraged and is considered an anti-pattern), so it is easy to access it from other parts of my application:
src/main/java/com/mypackage/Container.java
package com.mypackage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Container {
private static Container instance;
public static Container make(HttpServletRequest request, HttpServletResponse response) {
return instance = new Container();
}
public static Container getInstance() {
if (instance == null) {
// Throw an exception
}
return instance;
}
private Container(HttpServletRequest request, HttpServletResponse response) {
// ...
}
}
I want to create a Container object for every request/response cycle (or every servlet) as the entry point to my application. So I would look to do something like this:
#Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Container container = Container.make(request, response);
// Do stuff with container and eventually respond to the client
}
Now I know that thread safety is a concern when it comes to servlets, and properties on the servlet instance are shared among threads, but my question relates specifically to the Container object I'm creating using the singleton pattern and thread safety.
Is my current approach considered to be thread safe? If not, why, and how can I make it thread safe? Bear in mind that don't actually want my Container instance to be shared among each thread and would like a separate container for each incoming request/response.
Would it be thread safe (or a recommended approach) to create a new object inside the service method of the servlet class and then have that new object create an instance of the Container? e.g.
public class Something {
public Something(HttpServletRequest request, HttpServletResponse response) {
Container.make(request, response);
}
}
#Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Something something = new Something(request, response);
// Do stuff with container and eventually respond to the client
}
Finally, would I be correct in assuming that the issue of thread safety arises due to the servlet container re-using servlet instances? As per the Java EE documentation:
The life cycle of a servlet is controlled by the container in which the servlet has been deployed. When a request is mapped to a servlet, the container performs the following steps.
If an instance of the servlet does not exist, the web container
Loads the servlet class.
Creates an instance of the servlet class.
Initializes the servlet instance by calling the init method. Initialization is covered in Initializing a Servlet.
Creating an instance in the servlet means that it is not thread-safe as a servlet instance is reused.
A Singleton or ApplicationScoped object will only have one copy across your entire application. If you want to make sure that there is only one instance of the object then annotate the class with #ApplicationScoped:
#ApplicationScoped
public class Something {
//do stuff
}
Then in the servlet inject it:
public class SomeServlet extends HttpServlet {
#Inject
Something obj;
#Override
public void service(HttpServletRequest request, HttpServletResponse response) {
//do stuff
}
}
If instead you want the class to you are using to be unique per request then make your class RequestScoped instead. Like so:
#RequestScoped
public class Something {
//do stuff
}
For more information see the CDI tutorial at https://docs.oracle.com/javaee/6/tutorial/doc/giwhl.html. Note that this will require using an application server that has CDI i.e. Payara and not just a servlet container.

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.

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

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.

Execute method before Business Logic

I know about Servlet Filters and Event Listeners but I'm not sure if that's what I need to use.
Let's say I have a method:
Integer count = 0;
public void increment() {
count++;
}
and then a doGet:
public void doGet(HttpServletRequest request, HttpServletResponse response) {
System.out.println(count);
}
When performing a Get request for the first time, I'd expect count=1 and not count=0 because I want the method increment() to be executed first, before any other business logic in the web application.
Also, the count should be different for each user. It should be based on the number of requests a particular user has made.
What can I use to solve this problem?
I would prefer to not use Spring or any other 3rd party library
This all depends on where the count should be available, but you can create an abstract HttpServlet sub class that calls some abstract method to perform logic before handling the request
public abstract class BaseServlet extends HttpServlet {
#Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// wrap it in try-catch if you need to
prePerformLogic(req, resp);
// call super implementation for delegation to appropriate handler
super.service(req, resp);
}
protected abstract void prePerformLogic(HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException;
}
Now your own Servlet implementation will extend from this class. You'll implement it as you see fit. But, as Luiggi has stated in the comments, the example you've posted brings up many possible concurrency issues. A Servlet shouldn't normally have any mutable state.
If you just want to add an counter attribute to the HttpSession, synchronize on the HttpSession, check if an attribute exists. If it doesn't, add one starting at 0. If it does, increment it and add it back as an attribute. You might get better performance with a AtomicInteger, but you need to synchronized the check for the existence of the attribute.
A Filter would probably be more appropriate in that sense, since the Servlet wouldn't have any state anyway.

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);
}
}
}

Categories