All java web application based on servlet, knowledge about servlet it is basic for start develop web apps on the Java. Inside all java web frameworks use servlets.
First you need to add to your pom.xml dependency on Servlet API. Scope value is provided - this means that this library which be provided by servlet container such as Tomcat or Jetty. Java web app should be packaged in war. Servlet Container provide for environment, sockets, manage resources and class loading for servlets. All java application which use maven should have three dirs at the src/main, it is java - hold source code, resources - hold config files and webapp - contains file which describe that this is web app. Third directory interesting for us. At this should be WEB-INF directory which must contain web.xml - deployment descriptor which needs for servlet container.
When I try make my first servlet app, I get stuck - xml configuration does not works and I am start using annotations. XML configuration must be placed at the web.xml, otherwise annotations based configuration should be placed at the class file.
XML Configuration:
<web-app>
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>me.vrnsky.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
Annotations configuration
@WebServlet("/hello")
public class HelloServlet {
Let’s create a first servlet - create a package at the java directory and create on it Index class. It must extends HttpServletClass which contains method for handle HTTP requests. And another three interesting method is init, service and destroy. What does this method ?
First of it is create servlet object, second run at the endless loop and serve HTTP requests and last it call when servlet container shut down. Note that servlet container do not instant servlet object until receive request for servlet. It may change by set load-on-startup parameter. Another important thing that on all servlet container exist ONLY ONE object of servlet.
Override one of servlet method
By default servlet call doGet method, try to override it. We want to get some response from server in utf-8. For this we should write this code. Notice that servlet have a PrintWriter and OutputStreamWriter do not use it together, if you try to use this together you get an exception.
@WebServlet("/hello")
public class HelloServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws Exception {
resp.setContentType("text/utf-8");
PrintWriter writer = resp.getWriter();
writer.append("hello, I am a servlet!");
writer.flush();
}
}
At this time most used method is doGet and doPost, other uses but less at the real web app.
doTrace - check trace of request
doPut - update data on the server
doDelete - delete data from server
doGet - get data from server
doPost - send data to server(not idempotent method, because produce different data)
doHead - ask about header without message
doOptions - return server options
doPatch - frequency update data on server
When servlet container receive an request it create two object HttpServletRequest and HttpServletRespone and give it to the thread of Servlet by this way servlet may serve a few user at one time, this thing allow improve speed of responding to the user.
A small task to the servlet and it’s solution
How to count how many users ask about some servlets? For solution I have two idea - thread local - which allow contains variable for current thread and atomic constant. First is not suitable for this and second is very suitable for it.
@WebServlet("/counter")
public class Counter {
private static final AtomicInteger COUNTER = new AtomicInteger(0);
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws Exception {
resp.setContentType("text/utf-8");
PrintWriter writer = resp.getWriter();
writer.append(String.format("%s user visit this page", COUNTER.incrementAndGet()));
writer.flush();
}
}