Menu
Is free
registration
home  /  ON/ Writing a servlet to spy on social media users. Java

Writing a servlet to spy on social media users. Java

Servlets are java programs that run on the server side of a Web application. Just as applets dynamically extend the functionality of a Web browser, servlets dynamically extend the functionality of a Web server. While servlets can serve any request, they are commonly used to extend web servers. For such applications, Java Servlet technology defines HTTP-specific servlet classes. The javax.servlet and javax.servlet.http packages provide interfaces and classes for creating servlets.

  • What is the structure of a web project?

  • What is a Servlet Container? Servlet life cycle.

A servlet container is a program that manages the life cycle of servlets.
Servlet lifecycle: It is managed by the servlet container, the first time the servlet is accessed, it is loaded into memory and the init () method is called. Throughout the application, the service () method is called to handle client requests. When the application terminates, the destroy () method is called and the servlet is unloaded from memory.

  • What are the tasks, functionality of the servlet container?

A servlet container can act as a complete stand-alone web server, serve as a page provider for another web server such as Apache, or integrate into a Java EE application server. Provides data exchange between the servlet and clients, takes care of such functions as creating a software environment for a functioning servlet, identifying and authorizing clients, organizing a session for each of them.

  • How is sendRedirect () different from forward ()?

The forward () method is used to call a JSP using a relative path, and the sendRedirect () method is used to refer to a JSP using an absolute path. The difference between these methods is that an existing request object is passed with the forward () method, and a new request is generated when the sendRedirect () method is called. In the latter case, information should be transferred with other objects. Plus, the forward () method is faster.

  • What do you know about servlet filters?

The implementation of the Filter interface allows you to create an object that intercepts the request, can transform the header and content of the client's request. Filters do not create a request or response, they only modify them. The filter preprocesses the request before it reaches the servlet, and then (if necessary) processes the response coming from the servlet. The filter can interact with different types of resources, in particular, and with servlets and JSP pages. Servlet filters can:

  • intercept the initiation of the servlet before the servlet is initiated.
  • determine the content of the request before the servlet is initiated.
  • modify the request headers and data into which the incoming request is packed.
  • modify the response headers and data into which the received response is packed.
  • intercept the initiation of a servlet after a call to the servlet.

A servlet filter can be configured to work with a single servlet or group of servlets. The basis for generating filters is the javax.servlet.Filter interface, which implements three methods:

  • void init (FilterConfig config) throws ServletException;
  • void destroy ();
  • void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;

The init () method is called before the filter starts running and sets up the filter's configuration object. The doFilter method does the actual work of the filter. Thus, the server calls init () once to start the filter, and then calls doFilter () as many times as requests will be made directly to this filter. After the filter finishes its work, the destroy () method is called.

  • Why do you need listeners in servlets?

Context and session listeners are classes that can keep track of when a context or session was initialized, or keep track of when they should be destroyed and when attributes were added or removed from the context or session. Servlet 2.4 extends the request listener model by allowing you to track how a request is created and destroyed, and how attributes are added and removed from the servlet. The following classes have been added in Servlet 2.4:

  • ServletRequestListener
  • ServletRequestEvent
  • ServletRequestAttributeListener
  • ServletRequestAttributeEvent

  • How do I handle exceptions thrown by another servlet in the application?

Since the browser only understands HTML, when the application throws an exception, the servlet container will handle the exception and generate an HTML response. This is similar to what happens with error codes like 404, 403, etc. The Servlet API provides support for our own servlets for handling exceptions and errors, which we can specify in the deployment descriptor. The main task of such servlets is to handle the error or exception and send a clear HTML response to the user. For example, you can provide a link to the main page, as well as a description of some details about the error.

  • What is a deployment descriptor?

The deployment descriptor is an artifact configuration file that will be deployed in the servlet container. In the Java Platform, Enterprise Edition specification, a deployment descriptor describes how a component, module, or application (such as a web or enterprise application) should be deployed.

This config file specifies the deployment options for a module or application with specific settings, security options, and describes the specific configuration requirements. The syntax for the deployment descriptor files is XML.

  • How do I implement a servlet launch with an application launch?

The servlet container usually loads the servlet on the first client request, but sometimes it is necessary to load the servlet right at the start of the application (for example, if the servlet is bulky and will take a long time to load). To do this, you need to use the load-on-startup element in the descriptor (or the loadOnStartup annotation), which will indicate whether the servlet should be loaded at startup.

The value must be int. If the value is negative, then the servlet will be loaded at the client's request, and if 0 and further, then it will be loaded at the start of the application. The lower the number, the earlier the servlet will be in the download queue.

  • What is the ServletConfig object?

The javax.servlet.ServletConfig interface is used to pass configuration information to a servlet. Each servlet has its own ServletConfig object, which the servlet container is responsible for instantiating. The init parameters in web.xml (or WebInitParam annotations) are used to set configuration parameters. The getServletConfig () method is used to get the ServletConfig object for this servlet.

  • What is the ServletContext object?

The javax.servlet.ServletContext interface defines a number of methods that a servlet uses to communicate with its servlet container, such as getting the MIME type of a file, dispatching requests, or writing to a log file. The ServletContext object is unique and available to all servlets in a web application. We can use the ServletContext object when we need to provide access to one or more servlets to the initialized parameters of the web application. To do this, use the element in web.xml. The ServletContext object can be obtained using the getServletContext () method of the ServletConfig interface.

Servlet containers can also provide context objects that are unique to a group of servlets. Each of the groups will be associated with a different set of host path URLs.

ServletContext has been extended in the Servlet 3 specification and provides programmatically adding listeners and filters to your application. This interface also has many useful methods like getMimeType (), getResourceAsStream (), etc.

  • What is the difference between ServletContext and ServletConfig?

Below are some of the differences:

  • ServletConfig is a unique object for each servlet, while ServletContext is unique for the entire application.
  • ServletConfig is used to provide initialization parameters to the servlet and ServletContext is used to provide application initialization parameters for all servlets.
  • We don't have the ability to set attributes on the ServletConfig object, while we can set attributes on the ServletContext object that will be available to other servlets.

  • ServletResponse interface.

The ServletResponse interface is a tool for sending data to the client. All methods of this tool serve exactly this purpose.

  • ServletRequest interface.

The ServletRequest interface is a tool for getting HTTP request parameters. This interface has several methods that are identical in name and purpose to ServletContext.

  • What is Request Dispatcher?

The RequestDispatcher interface is used to pass a request to another resource (this could be HTML, JSP, or another servlet in the same application). We can use this to add content from another resource to the response. This interface is used for internal communication between servlets in the same context. There are two methods implemented in the interface:

  • void forward (ServletRequest var1, ServletResponse var2) - Forwards a request from the servlet to another resource (servlet, JSP or HTML file) on the server.
  • void include (ServletRequest var1, ServletResponse var2) - Includes resource content (Servlet, JSP or HTML page) in response.

The interface can be accessed using the ServletContext getRequestDispatcher (String s) method. The path must start with a /, which will be interpreted as being relative to the context's current root path.

  • How can you create a deadlock in a servlet?

A deadlock can be obtained by implementing a looped method call, for example, by calling the doPost () method in the doGet () method and calling doGet () in the doPost () method.

  • How do I get the address of the servlet on the server?

To get the actual path of the servlet on the server, you can use this construction: getServletContext (). GetRealPath (request.getServletPath ()).

  • How do I get server information from a servlet?

Server information can be obtained using the ServletContext object using the getServerInfo () method. Those. getServletContext (). getServerInfo ().

  • How to get the client's ip address on the server?

Use request.getRemoteAddr () to get the client ip in the servlet.

  • What do you know about servlet wrapper classes?

The Servlet HTTP API provides two wrapper classes, HttpServletRequestWrapper and HttpServletResponseWrapper. They help developers implement their own implementations of the request and response servlet types. We can extend these classes and override only the necessary methods to implement our own response and request object types. These classes are not used in standard servlet programming.

Almost twenty years have passed since the advent of the Java programming language. During this time, Java prophesied death and oblivion, programmers on the ground laughed at its inhibition and greed for resources. But there were also those who believed in Java, they developed all kinds of libraries, developed a community, persistently proved that there are no limits for Java: realtime, embedded, AI - anything is possible. We decided not to stand aside and make a small series of articles on Java in this section. Go!

Your kettle chooses Java

According to Oracle itself, the Java virtual machine is currently installed on more than three billion devices. And these are not only computers and smartphones, but also cameras, TVs, Blu-ray players, printers, SIM cards, automatic teller machines and even cars. The list will grow steadily, and with it offers from employers for Java programmers. Even now, the number of vacancies for Java programmers exceeds the rest. And companies are willing to pay more and more, poaching employees and organizing better working conditions.

And what is it good for?

Java programmers are attracted by the minimalism of the syntax. No unnecessary modifiers and service words. Even the absence of multiple inheritance, which at first somewhat confused C ++ programmers, turns out to be reasonable and justified in the end. Simple logic, automatic memory management, detailed documentation, forums with answers to all sorts of questions, open source - all this allows you to quickly delve into the development process and significantly reduces the number of potential errors. Even Indian peasants learn Java in a couple of months, at least that's what their diplomas say :). Moreover, Java is an interpreted language. The compiler translates the source code into so-called bytecode, which is easy to convert back, which makes Java especially attractive for reverse engineering.

Well, let's get started

Java is an object-oriented language, which means that all variables, methods, constants are declared within a class. In addition to classes, there are also interfaces - a special abstract construction that allows you to describe the behavior of an object without specifying a specific implementation. And if there is no multiple inheritance of classes in Java, then a class can implement any number of interfaces, which allows one object to have many functions, but provide only a part of them.

Data types can be divided into two groups: simple (int, long, char, and so on) and object: classes, interfaces, arrays. Simple types are always and everywhere of fixed dimension. For example, on any architecture and any device, an int takes up four bytes of memory. This is pretty handy for calculations. The data array contains a special attribute length, which stores the size of the array, for which special thanks to the developers. Different types of data are passed to methods in different ways. Simple types are always passed by value. Object - always by reference to save memory. This means that if we pass int a = 10 and change its value to 5 in the called method, then in the original method a will still be 10. But if we change the property of the object, then it will change in the original method as well.

Remember the memory

Although a Java programmer is freed from the need to allocate and free memory, ignorance of some of the features of the virtual machine and the garbage collector can easily turn your program into an insatiable monster devouring CPU time and all available memory.

When creating a new array, always remember that it is much easier to create many small chunks of memory than one huge one. Otherwise, you run the risk of running into an Out of memory error, which roughly means that you had memory, but everything came out.

Many programmers, when they switch to Java and learn about automatic memory cleaning, start creating objects in huge quantities, hoping that all this will clear up on its own. Meanwhile, a garbage collector is like a machine that can pick up garbage only thrown into a trash can near a house. If you no longer need some data, you shouldn't store it just in case, like a bunch of old postcards - assign the pointer to the data null, help the cleaner clean up :). It's also a good practice to make the list clear if you don't need it already. Remember, the object will be kept in memory as long as there are references to it in the code. Even if your program runs on 16 gigabytes of memory and does not threaten to crash with Out of memory, it will become more and more clumsy and slow from an excess of used memory. 99% of user complaints about slow Java programs are due to inefficiently written source code. If you need to constantly create objects that are used quickly and are no longer needed, for example, a lot of small messages, consider creating a pool that will store a number of instances for repeated use. Remember, creating and deleting an object is costly.

For the cause, gentlemen

One example is better than a thousand words. You can flip through the manual and look at the standard Hellowords without us, so we will assume that you have already done this and are ready to implement a more interesting example.

You and I will take care of the server application of Java and write a small program to "spy" the users of social networks. To do this, you do not even have to find a job at the NSA - the users spread everything to themselves, and we will only have to get this information, organize it and display it beautifully. Let's take one of the popular social services, for example, foursquare, and draw the movement of our friends on a map.

First, let's see what we can pull out of foursquare. After going through the developer pages, we turn our attention to two methods:

  • https://developer.foursquare.com/docs/users/checkins - Places visited by the user. Unfortunately, so far it is only supported for the user registered in the program, and there are rumors that due to implementation restrictions, it will remain so;
  • https://developer.foursquare.com/docs/checkins/recent - places visited by friends of the registered user. If you play a little with this function, then a sad fact becomes clear: for each friend exactly one place is returned - the last one where he checked in.

To use the foursquare API, you need to register our future application, go to this address: https://en.foursquare.com/developers/register and fill in the fields (yes, you will have to register in foursquare itself, but you can do it just fine without me).

Of the important fields, you can mark only "Application name", "Download / welcome page url" (enter an arbitrary web address here) and "Redirect URI (s)" - this is the address to which the server will send us after registration. We will write the desired value here later, but for now you can just enter any web address. Click "Save" and our tracker app has been registered successfully.

Climbing into the clouds

Captain Obvious conveys that any server application requires a server to run. Raise the server yourself hemorrhoids, so we will use the now popular cloud solutions. The cloud will be sponsored by Google Corporation, because their Google App Engine is free, quite easy to set up and use. First, go here and download the Google App Engine SDK for Java.

Now you can start creating your project. For Java development, I use IntelliJ IDEA, but you can use the free and equally well-known Eclipse environment.

Let's select a new Java project. Let's call it nsa_tracker.


On the next tab, mark the Web Application and Google App Engine on the left and indicate the path to the previously downloaded and unpacked App Engine SDK.


Now sit back and let the IDE do its thing. If you chose IDEA and did everything correctly, then as a result you will see a finished project, which, when launched, opens a browser window with empty content. You can start coding.

We start looking

So, we have a folder with a project, which contains the src folder. We will put the sources there. Java sources are grouped by package. A package is a folder on disk. Packages are needed in order not to heap all the sources into a heap, but to separate them, guided by the principles of logic. For example, it would be logical to put the code related to the user interface in the ui package, and network interactions in the network package. This greatly facilitates the development and support of the project later. Historically, it has been the practice to start the package structure with the company name followed by the program name. This will help to easily identify our sources among the heap of the same in the future. For our program, we will create the org.nsa.tracker package. In it we will create classes.

Servlets are used on the server to process user requests. A servlet is a class that typically inherits from HttpServlet and operates on a request-response basis. All you need is to override the doGet method. Upon request from the user, we need to log into foursquare, download the list of friends' check-ins and redirect the request to the page with the map.

To work with the foursquare API, we will use the free foursquare-api-java library, which can be taken from here. The Java Library is a ZIP archive with a jar extension containing compiled Java classes that implement specific functionality. For authorization, we need the ClientId and ClientSecret obtained at the stage of registration of the application in foursquare. Since these parameters do not change during program execution, we will declare them as constants.

Private static final String CLIENT_ID = "FAKE_CLIENT_ID"; private static final String CLIENT_SECRET = "FAKE_CLIENT_SECRET";

Final means that this variable has been assigned a final value that cannot be changed. Static makes the variable available to all instances of the given class. Using the authorization example from the foursquare-api-java library, we get the following code:

Protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException (FoursquareApi foursquareApi = new FoursquareApi (CLIENT_ID, CLIENT_SECRET, CALLBACK_URL); String code = req.getParameter = req.getParameter) We go to the registration page resp.sendRedirect (foursquareApi.getAuthenticationUrl ());) else (try (foursquareApi.authenticateCode (code); // Registration successful, load data Result result = foursquareApi.checkinsRecent ("0.0,0.0", 100, 0l); ) catch (FoursquareApiException e) (e.printStackTrace ();)))

Notice the "throws ServletException, IOException" in the method declaration. This line means that the method can potentially throw one of these exceptions. An exception in Java is an object that signals when an exception has been thrown. They are verifiable and unverifiable. Checked exceptions should be handled by surrounding some of the code with a try-catch block, or passed above. Unchecked exceptions are usually not handled because they are thrown in cases where the program is unable to recover its state. In this method, we only handle the FoursquareApiException.

When the web server receives a request for an application, it uses a deployment descriptor to match the request URL to the code that needs to process the request. The deployment descriptor is an XML file named web.xml. Let's add a description of the tracking servlet.

track org.nsa.tracker.TrackerServlet track / track

Now requests to / track will be handled by our TrackerServlet. You can set the Callback Url parameter to the correct value http: // localhost: 8080 / track.

To display the results, you can use the Static Maps API, kindly provided by the same Google corporation (https://developers.google.com/maps/documentation/staticmaps/). Our servlet will generate a simple HTML page and return it in response to a user request.

StringBuilder sb = new StringBuilder (" NSA Tracker"); sb.append (" "); sb.append ("

    "); index = 1; for (Checkin checkin: result.getResult ()) (sb.append (" ") .append (index ++). append (" - ") .append (checkin.getUser (). getFirstName ()) .append (" ") .append (checkin.getUser (). getLastName ()). append ("");) sb.append ("
"); sb.append (" ");

To generate the page, the StringBuilder class is used, this is due to the fact that strings in Java are immutable objects. When concatenating strings using the + operator. a new line is created in memory. StringBuilder saves memory by using a char array to store concatenated strings. We send the answer to the user:

Byte resultBytes = sb.toString (). GetBytes ("utf-8"); resp.setContentLength (resultBytes.length); resp.getOutputStream (). write (resultBytes);

… And everything is ready. We launch it and see something similar to a picture with the saying “The result of the program's work”.


What's next?

The application can be improved, for example, to separate data collection and display. Move the collection of data into a separate service that will work constantly and remember all user movements in the database. Then it will be possible to display not individual points, but a connected route. By digging a little into the foursquare API, you can extract even more information about user activity.

But I hope I succeeded in the main thing: to convince you that Java is simple and cool. See you in a month!

Books for Java Programmer

We recommend starting to learn the language with the book “Java. A Beginner's Guide by Herbert Schildt. The next level is “Java. The Complete Guide "from him, and you can learn more about servlets in the book" Java Servlet and JSP Cookbook "by Bruce W. Perry.

Servlet is a java program that runs on the server side of a Web application. Just as applets dynamically extend the functionality of a Web browser, servlets dynamically extend the functionality of a Web server.

Work servlet"but can be described as follows: when a request comes from a client, the Web server can use a special configuration file to determine which servlet to execute. After that, the Web server starts the JVM, which in turn executes the servlet. The Servlet processes the request and transfers the content to the Web -server (possibly in the form of an HTML page) The web server sends a response (a servlet-generated HTML page) to the client.

A WEB server is essentially a kind of container that loads servlet"s, executes them, and, having received the result from them, sends it to the client.

Servlet in Web Application Architecture

Because of its power and flexibility, servlet"You can play a significant role in the architecture of the system. They can perform application tasks intended for the middle tier, act as a proxy server for the client, and even improve the functionality of the middle tier by adding support for new protocols and other functions. The middle tier acts as an application server in the so-called three-tier client-server system and is located between a "lightweight" client, such as a Web browser, and the data source.

Servlet as a proxy server

To support applets, servlets can act as their proxy servers. This can be important because Java security only allows applets to connect to the server from which they were downloaded. If the applet needs to connect to a database server located on a different machine, servlet can create this connection for the applet.

Temporary and permanent servlet"NS

Servlets can start and stop for every client request. They can also start when the Web server starts and exist until it stops. Temporary servlet"s are loaded on demand and offer a good way to conserve server resources for infrequently used functions. Persistent servlets are loaded when the Web server starts and exist until the Web server is shut down. Servlets are installed as persistent extensions to the server if the startup cost is very high ( such as establishing a database connection) if they offer persistent server-side functionality (such as an RMI service), or in cases where they need to respond to client requests as quickly as possible. servlet"but permanent or temporary; this is a function of configuring the web server.

Servlet lifecycle, javax.servlet.Servlet

Servlets run on the web server platform as part of the same process as the web server itself. The web server is responsible for initializing, invoking, and destroying each instance of the servlet. The web server communicates with the servlet through a simple interface: javax.servlet.Servlet.

The javax.servlet.Servlet interface includes three main methods:

  • init ()
  • service ()
  • destroy ()

and two helper methods:

  • getServletConfig ()
  • getServletInfo ()

Similarities between interfaces servlet"and the Java applet is obvious. This is exactly what it was designed! Java servlets are to Web servers what applets are to Web browsers. An applet runs in a Web browser, executing actions on request through a special interface. A servlet does the same when working on a web server.

Servlet initialization, init () method

The first time the servlet is loaded, the init () method is called. This allows the servlet to do any installation work, such as opening files or establishing connections to their servers. If the servlet is permanently installed on the server, it is loaded when the server starts. Otherwise, the server invokes the servlet when it receives the first request from a client to perform a service provided by that servlet.

It is guaranteed that the method init () will end before any other call to the servlet - such as, for example, a method call service ()... note that init () will be called only once; it will not be called until the servlet is unloaded and then loaded by the server again.

Method init () takes one argument - an object reference ServletConfig which contains arguments to initialize the servlet. This object has a method getServletContext () returning an object ServletContext which contains information about the servlet's environment.

Servlet core, service () method

Method service () is the heart of the servlet. Each request from the client results in one method call service ()... This method reads the request and constructs a response message using its two arguments ServletRequest and ServletResponse:

Thus, there are two ways to transfer information from the client to the servlet. The first is through passing values ​​in request parameters. Parameter values ​​can be inserted into the URL. The second way to transfer information from the client to the servlet is through an InputStream (or Reader).

Method work service () essentially simple - it creates a response to every client request sent to it from the server. Keep in mind, however, that there can be multiple parallel requests being processed at the same time. If the method service () requires any external resources, such as files, databases, it is necessary to ensure that access to the resources is thread-safe.

Unloading a servlet, destroy () method

Method destroy () called to free all resources (such as open files and database connections) before unloading the servlet. This method can be empty if there is no need to perform any finishing operations. Before calling the method destroy () the server waits either for all servicing operations to complete or for a specified time to expire. This means that the method destroy () can be called while some long running method is running service ().

It is important to formalize the method destroy () in such a way as to avoid closing the required resources until all calls service () will not end.

Servlet configuration, getServletConfig () method

Method getServletConfig () returns a reference to an object that implements the interface ServletConfig... This object provides access to servlet configuration information, i.e. access to servlet initialization parameters and servlet context object ServletContext which gives access to the servlet and its environment.

Servlet information, getServletInfo () method

Method getServletInfo () is defined by the programmer creating the servlet to return a string containing information about the servlet, such as the author and version of the servlet.

ServletRequest interface

ServletRequest provides client information about the HTTP request parameters to the servlet, i.e. provides data including parameter name and values, attributes, and an input stream. This information is passed to the method service ().

Next servlet example shows how to get information from a parameter request method service ():

BufferedReader reader; String param1; String param2; public void service (ServletRequest request, ServletResponse response) (reader = request.getReader (); param1 = request.getParameter ("First"); param2 = request.getParameter ("Second");)

Additional information about the request is available to the servlet through methods, the main of which are shown in the following table:

getAttribute () Returns the value of the specified attribute of this request.
getContentLength () Request size, if known.
getContentType () Returns the MIME type of the request body.
getInputStream () Returns an InputStream for reading binary data from the request body.
GetParameterNames () Returns an array of strings with the names of all parameters.
getParameterValues ​​() Returns an array of values ​​for the specified parameter.
getProtocol () Returns the protocol and version for the request as a string of the form /..
getReader () Returns a BufferedReader to get the text from the request body.
getRealPath () Returns the real path for the specified virtual path.
getRemoteAddr () The IP address of the client making this request.
getRemoteHost () The hostname of the client machine that made this request.
getScheme () Returns the scheme used in the URL for this request (for example, https, http, ftp, etc.).
getServerName () The hostname of the server that accepted the request.
getServerPort () Returns the port number used to receive this request.

ServletResponse interface

Interface ServletResponse is a tool for sending data to a client. All methods of this tool serve precisely to solve this problem:

Public java.lang.String getCharacterEncoding () public void setLocale (java.util.Locale loc) public java.util.Locale getLocale ()

The first method returns the MIME type of encoding (for example, UTF8), in which the information will be displayed. The second two methods also work with charset. They indicate the language used in the document (for example - Russian).

Public ServletOutputStream getOutputStream () throws java.io.IOException

The getOutputStream method returns an output stream for the servlet. This stream is used, for example, to output binaries. Text data can be output using java.io.Writer:

Public java.io.PrintWriter getWriter () throws java.io.IOException

The getWriter () method automatically converts strings to the charset specified in the getCharacterEncoding () and getLocale () methods.

Public void setContentLength (int len)

The setContentLength method sets the value of the HTTP header "Content-Length"

Public void setContentType (String type)

The setContentType method is used to send the MIME content type of the document. The "Content-Type" HTTP header field.

The output stream is buffered. This means that a chunk of data will be returned to the client only after the buffer is full.

Public void setBufferSize (int size) public int getBufferSize () public void flushBuffer () throws java.io.IOException public void resetBuffer ()

The above 4 methods allow, respectively, to set the size of the send buffer, get its size, initialize sending the contents of the buffer to the client without waiting for it to fill, and also clear this buffer of data.

Public boolean isCommitted ()

Using the isCommitted method, you can get a flag whether the sending of data to the client has already started. The flag will be positive if the HTTP response header has already been sent.

Public void reset ()

If the HTTP header has not been sent yet, the reset method "resets" the HTTP header to its "default" values.

JFreeChart charts in servlets

The JFreeChart graphics library can be used in servlets to create charts and display them on site pages as images. Details and examples of using JFreeChart in servlets are provided.

Servlet with the Chart.js graphics library

JNI in servlet

In some cases, you may need to use JNI in a WEB application. An example of using JNI in servlets is provided.

JMS messages in a servlet

Servlet can be used to exchange JMS messages between applications. An example of using a servlet to send and read JMS messages in a JBoss container is provided.

What are servlets? Servlets are actually HTTP and FTP processing modules used to build web gates.

The basis of these portals is the WEB server itself - a program that holds the server socket, receives and transmits data. Most often, to speed up the work, the server is written not in Java, but in some other programming language (for example, in C ++).

A basic servlet works in conjunction with the server. It is to him that the server sends data and from him receives the response sent to the client. In fact, the underlying servlet is the "brain" of the server. The main function of this servlet is to read the client's request, decrypt it and, in accordance with the decryption, transfer the work to the servlet responsible for this type of requested information. Often the server itself acts as the underlying servlet to achieve speed. This is exactly how Jacarta Tomcat works.

The figure shows a diagram of the transfer of calls (requests) and responses (responses) between the server and servlets. This diagram depicts the operation of an HTTP server that has several JSP pages and two resources "/ sample1" and "/ sample2", which are processed by two servlets - "Sample1 Servlet" and "Sample2 Servlet", respectively.

Let's analyze step by step what is shown in the figure:

  1. client connects to server
  2. the server passes the request to the "Basic Servlet"
  3. the underlying servlet extracts the resource URI from the request
    • if the URI points to "/ sample1" then the request wholly(unchanged) passed to the "Sample1 Servlet" servlet, which further processes this request
    • if the URI points to "/ sample2", the server passes the request to the "Sample2 Servlet"
    • in all other cases, the request is passed to the "JSP Servlet" module
  4. the servlet that was given control processes the data, creates a response, and then the response is sent back to the underlying servlet.
  5. the basic servlet, without processing the received data, immediately sends it back to the server
  6. the server issues data to the client

Thus, the task of processing a request is divided into logical parts, for each of which a separate module, its own "software brick", is responsible. In fact, there can be many more steps in processing a request. For example, different modules can be responsible for the "GET" and "POST" methods.

Servlet interface

What all these modules have in common is that they are end-to-end interconnected using the javax.servlet.Servlet interface

Let's take a look at this interface. It lists only 5 methods:

Public void init (ServletConfig config) throws ServletException This method is called to inform the servlet that it is included as a module to serve client requests. The config parameter separates the javax.servlet.ServletConfig interface, which carries information about the server environment, servlet name, initial parameters, and other goodies. The javax.servlet.ServletConfig interface will be discussed a bit later. It is assumed that after calling this function, the servlet will neatly save this config in its variable and will issue it using another method: public ServletConfig getServletConfig () After receiving system information using "getServletConfig ()", the server may want to find out the author's name, date creation, other information about the servlet, which is achieved by calling public String getServletInfo ()

To process the request and get the result of its processing, use the function

Public void service (ServletRequest request, ServletResponse response) throws ServletException, java.io.IOException In this function, two tools are passed to the code that will process the data: one to receive data from the server, and the other to send the result of the servlet. Accordingly, these are the request and response parameters that separate the javax.servlet.ServletRequest and javax.servlet.ServletResponse interfaces. All work with data is carried out precisely through these interfaces, so we'll talk about them in more detail below.

After the server no longer needs this module, the method is called

Public void destroy () which completes all operations with the servlet object.

ServletConfig interface

The 4 self-explanatory methods make up the javax.servlet.ServletConfig interface:

Public String getServletName () public ServletContext getServletContext () public String getInitParameter (String name) public java.util.Enumeration getInitParameterNames ()

I think the purpose of all functions is clear, except

Public ServletContext getServletContext () This method returns a link to a very useful server tool:

ServletContext interface

ServletContext is an interface that defines access to the following very useful functions:

Public Object getAttribute (String name) public java.util.Enumeration getAttributeNames () public void setAttribute (String name, Object object) public void removeAttribute (String name) Four methods for working with attributes. The role of attributes is performed by any object of any class. The purpose of these functions is to transfer different objects between unrelated servlets. public String getInitParameter (String name) public java.util.Enumeration getInitParameterNames () Access to the parameters with which the server was started. There may also be a hostname, port, and other useful things. public int getMajorVersion () public int getMinorVersion () Returns the Servlet API versions. public String getMimeType (String file) Returns the MIME type associated with the file specified in the file variable. Remember how you had to define MIME in SimpleWEBServer and appreciate the convenience! public java.util.Set getResourcePaths () public java.net.URL getResource (String path) throws java.net.MalformedURLException public InputStream getResourceAsStream (String path) Returns paths to resources available to the server and the resources themselves as URLs and streams data. public RequestDispatcher getRequestDispatcher (path) public RequestDispatcher getNamedDispatcher (name) RequestDispatcher is a tool for forwarding a request to another resource. These functions are needed to get the object of this tool for the specified resources. That is, say, in order to forward a request to the servlet "sample1" from the servlet body, you can do this: getServletConfig (). GetServletContext (). GetNamedDispatcher ("sample1"). Forward (request, response);

The RequestDispatcher class itself includes only two methods:

Public void forward (ServletRequest request, ServletResponse response) throws ServletException, java.io.IOException public void include (ServletRequest request, ServletResponse response) throws ServletException, java.io.IOException The first is to redirect the request, and the second is to include the result of the called servlet to the result of the current one. For example, servlet 1 prints the word "test 1", then calls include for servlet two, and then prints the word "test 2". Servlet 2 just prints the word "and". Servlet 1 will output the string "test 1 and test 2". public void log (String msg) Write something to the server log. public void log (String message, Throwable throwable) Define an exception and a phrase that will be logged when this exception is received. public String getRealPath (String path) Translates a path like "/index.html" to "http: //host/contextPath/index.html" public String getServerInfo () Returns the server name. public ServletContext getContext (String uripath) This method allows you to exchange ServletContext between different resources of the same server. public String getServletContextName () Returns the name of the servlet to which this ServletContect interface object belongs.

ServletRequest interface

The ServletRequest interface is a tool for getting HTTP request parameters. This interface has several methods that are identical in name and purpose to the ServletContext:

Public Object getAttribute (String name) public java.util.Enumeration getAttributeNames () public void setAttribute (String name, Object o) public void removeAttribute (java.lang.String name) public String getServerName () public RequestDispatcher getRequestDispatcher (String path)

The remaining methods allow you to conveniently work with the HTTP request header:

Public String getCharacterEncoding () public void setCharacterEncoding (String env) throws java.io.UnsupportedEncodingException Working with character encoding in HTTP header fields. The functions set the method for decrypting CGI requests from the% NN form into ordinary characters. For example, which standard - KOI8-R, windows-1251 or UTF-8 - should be used to decrypt Cyrillic characters. public int getContentLength () public String getContentType () Reads the "Content-Length", "Content-Type" fields from the HTTP request. public jString getParameter (String name) public java.util.Enumeration getParameterNames () public String getParameterValues ​​(String name) public java.util.Map getParameterMap () Functions for getting a field from the HTTP header and its value. public ServletInputStream getInputStream () throws java.io.IOException public java.io.BufferedReader getReader () throws java.io.IOException Get the incoming data stream or its "reader". Reader is used to read text information - it will automatically decrypt strings according to the specified charset. Attention! There is a significant bug in J2EE 1.3: when decrypting the% 25 character (the% character in Post and Get requests), Reader gives an error (the bug is seen on Tomcat 4 and Resign servers). It is possible that a similar bug exists with other symbols. public String getProtocol () Get the HTTP version of the request protocol (for example, "HTTP / 1.1"). public String getScheme () Returns the name of the request schema. For example "http", "https", or "ftp". public int getServerPort () public String getRemoteAddr () public String getRemoteHost () public boolean isSecure () Server port, client IP, client hostname and whether the connection is private (HTTPS) public java.util.Locale getLocale () public java.util.Enumeration getLocales () The client's preferred document language (the result of processing the "Accept-Language" field)

ServletResponse interface

The ServletResponse interface is a tool for sending data to the client. All methods of this tool serve exactly this purpose:

Public java.lang.String getCharacterEncoding () public void setLocale (java.util.Locale loc) public java.util.Locale getLocale () The first method returns the MIME type of encoding (for example, UTF8), in which information will be displayed. The second two methods also work with charset. They indicate the language used in the document (for example - Russian). public ServletOutputStream getOutputStream () throws java.io.IOException Returns the output stream for the servlet. This stream is used, for example, to output binaries. Text data can be output using java.io.Writer: public java.io.PrintWriter getWriter () throws java.io.IOException This method automatically converts strings to the charset specified in the getCharacterEncoding () and getLocale () methods. public void setContentLength (int len) This method sets the value of the HTTP header field "Content-Length" public void setContentType (String type) Method for sending the MIME content type of the document. The "Content-Type" HTTP header field. public void setBufferSize (int size) public int getBufferSize () public void flushBuffer () throws java.io.IOException public void resetBuffer () The point is that the output stream is buffered. This means that the next chunk of data will be issued to the client only after the buffer is full. These methods allow, respectively, to set the size of the send buffer, get its size, initialize sending the contents of the buffer to the client, without waiting for it to fill, as well as clear this buffer of data. public boolean isCommitted () With this method, you can get a flag whether data has already been sent to the client. The flag will be positive if the HTTP response header has already been sent. public void reset () If the HTTP header has not been sent yet, this method "resets" the HTTP header to its "default" values.

Predefined Servlet Types

The Java Servlet API, in addition to the actual interfaces, also contains several servlet classes that can serve as the basis for your programs.

The base for all these classes is the abstract class javax.servlet.GenericServlet:

Public abstract class GenericServlet implements Servlet, ServletConfig, java.io.Serializable

As you can see from the definition of this class, it has all the methods of the Servlet and ServletConfig interfaces. The only unimplemented method is

Public abstract void service (ServletRequest req, ServletResponse res) throws ServletException, java.io.IOException which was declared abstract.

On the basis of this class, another abstract class was created - javax.servlet.http.HttpServlet:

Public abstract class HttpServlet extends GenericServlet implements java.io.Serializable

This class was created in accordance with the concept of "even more convenience for the programmer" and has many useful methods:

Protected void doDelete (HttpServletRequest req, HttpServletResponse resp) throws ServletException, java.io.IOException protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws Servlet. throwException, java.io.io exception .io.IOException protected void doOptions (HttpServletRequest req, HttpServletResponse resp) throws ServletException, java.io.IOException protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws Servlet.Exception throws ServletException, java.io.IOException protected void doTrace (HttpServletRequest req, HttpServletResponse resp) throws ServletException, java.io.IOException protected void service (HttpServletRequest req, HttpServ throws, java. resp. , ServletR esponse res) throws ServletException, java.io.IOException Different service options (ServletRequest req, ServletResponse res) for different HTTP methods from DELETE and GET to PUT and TRACE. And in order to conveniently receive data via the CGI interface without decrypting the header, the HttpServletRequest and HttpServletResponse classes were created, which are included with the HttpServlet in the javax.servlet package.http protected long getLastModified (HttpServletRequest req) This method returns the time of the last modification of the HttpServlet object req It takes the time value from the "Date" field of the HTTP request header. If the field is not found, it returns -1.

Accordingly, we will analyze the HttpServletRequest and HttpServletResponse interfaces. They inherit from ServletRequest and ServletResponse, respectively.

HttpServletRequest, in addition to the methods inherited from ServletRequest, also has the following very useful methods:

Cookie getCookies () Returns the set of cookies sent by the client to the server.

The Cookie class, which is part of the same javax.servlet.http package, contains all the possible information about a cookie. The most important methods of this class are

Int getMaxAge () String getName () String getValue () giving, respectively, how much time this cookie has left to live, the name of the cookie and its value. Also Cookie (String name, String value) void setValue (String newValue) void setMaxAge (int expiry) to create a cookie, set its value and maximum age. long getDateHeader (String name) Returns the date from the HTTP header, if any. int getIntHeader (java.lang.String name) Returns the numeric value of the field named name from the HTTP request header String getMethod () Returns the HTTP request method. String getQueryString () String getRequestURI () StringBuffer getRequestURL () Returns the string contained in the document URL after the "?" Character, the document URI, and the full URL. HttpSession getSession () HttpSession getSession (boolean create) boolean isRequestedSessionIdFromCookie () boolean isRequestedSessionIdFromURL () boolean isRequestedSessionIdValid () Functions. allowing you to work with such an important data transfer mechanism as sessions.

Sessions are needed in order to drag data from page to page after the user. For example, a user visits page (1), where some data is sent to him for page (2), and that one saves some other things for page (3).

In principle, on page (1) you can send data to the user, then get it on page (2), add something, send it to the user ... In this way, you will have to constantly send the entire data set from the client to the server and back, and many times. In addition to the fact that such forwarding is not always convenient, it also eats up traffic.

You can do the same differently - use the session mechanism. This mechanism works as follows: the server saves the data sent by the user in a separate file - the session file. All work on changing the data will be done with the contents of this file. The client is given a "session key" (aka Session key, aka Sesseion ID) - a unique pointer to a file containing data specifically for this user. Now, in order to receive all data concerning this client, the server only needs to know the session key. The advantage of this method is the convenience and speed of its use.

These are all the main methods of the HttpServletRequest interface. For a complete list of methods, see the Java Servlet API documentation.

Now about the HttpServletRequest interface. The main difference between the classes that share this interface is that the data is not output immediately. First, all data is bundled into an HTTP response. The response is only sent after HttpServlet.service () has finished running.

And so, about the methods:

Void addHeader (String name, String value) void addIntHeader (String name, int value) void addDateHeader (String name, long date) Methods add parameters to the HTTP header. The last method sets the "Date" parameter. void addCookie (Cookie cookie) The method adds a cookie to the header boolean containsHeader (String name) Allows you to find out if the header already contains the specified parameter. String encodeURL (String url) String encodeRedirectURL (String url) The first method encodes characters using the% NN replacement. The second method does the same and calls void sendRedirect (String location) void setStatus (int sc) void sendError (int sc) void sendError (int sc, String msg) The first sets the return code, the second two send an error message. The interface has the following possible errors for the sc parameter, corresponding to the HTTP protocol return codes: SC_CONTINUE - Status code (100) SC_SWITCHING_PROTOCOLS - Status code (101) SC_OK - Status code (200) SC_CREATED - Status code (201) SC_ACCEPTED - Status code (202 ) SC_NON_AUTHORITATIVE_INFORMATION - Status code (203) SC_NO_CONTENT - Status code (204) SC_RESET_CONTENT - Status code (205) SC_PARTIAL_CONTENT - Status code (206) SC_MULTIPLE_CHOICES (Status_MULTIPLE_CHOICES - Status code (300) SCAN_MOVED code2) SC_SEE_OTHER - Status code (303) SC_NOT_MODIFIED - Status code (304) SC_USE_PROXY - Status code (305) SC_BAD_REQUEST - Status code (400) SC_UNAUTHORIZED - Status code (401) SC_PAYMENT_REQUIRED - Status code (402) SC_FORBID (Status code) - Status code (404) SC_METHOD_NOT_ALLOWED - Status code (405) SC_NOT_ACCEPTABLE - Status code (406) SC_PROXY_AUTHENTICATION_REQUIRED - Status code (407) SC_REQUEST_TIMEOUT - Statu s code (408) SC_CONFLICT - Status code (409) SC_GONE - Status code (410) SC_LENGTH_REQUIRED - Status code (411) SC_PRECONDITION_FAILED - Status code (412) SC_REQUEST_ENTITY_TOO_LARGE - Status (413) SC_REQUEST code (415) SC_REQUESTED_RANGE_NOT_SATISFIABLE - Status code (416) SC_EXPECTATION_FAILED - Status code (417) SC_INTERNAL_SERVER_ERROR - Status code (500) SC_NOT_IMPLEMENTED - Status code SC_BAD_CodeAEW2) (504) SC_HTTP_VERSION_NOT_SUPPORTED - Status code (505)

That's all there is to say about HttpServletResponse

Using Servlets in WEB Applications

Now let's talk about using servlets in WEB applications. To do this, I will give two useful examples that can be useful in practice.

The first example shows methods for working with an HttpServlet and outputting compressed HTML page content. In theory, the HTML page in the browser response is displayed in plain text, but to reduce the amount of data sent, you can use GZIP compression. Modern browsers (at least 4th generation browsers and above) support this method of sending textual information and will render the page as if it had not been compressed.

import java. io. *; import javax. servlet. *; import javax. servlet. http. *; import java. util. zip. *; // servlet inherits from HttpServlet public class ZipServlet extends HttpServlet ( // function for handling the GET method public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException ( // set the page to be an HTML document response. setContentType ("text / html"); // take the "Accept-Encoding" parameter from the HTTP header String encodings = request. getHeader ("Accept-Encoding"); // take the "encoding" parameter - the previously specified encoding of the document String encodeFlag = request. getParameter ("encoding"); // Where will we output PrintWriter out; // if the "Accept-Encoding" field is present in the request if (encodings! = null) ( // and if this field contains the value "gzip" and the encoding has not been set yet, if ((encodings. indexOf ("gzip")! = - 1) &&! encodeFlag. equals ("none")) ( // then the output will be followed by one and compress the text using GZIP out = new PrintWriter (new GZIPOutputStream (response. getOutputStream ()), false); // and set a flag for the browser that the document will be compressed response. setHeader ("Content-Encoding", "gzip"); ) else out = response. getWriter (); ) else // otherwise we will output without compression out = response. getWriter (); out. println ("This a test !!!"); // write the body of the document out. close (); // and close the output. // Everything, upon completion of this function, the document will be sent } }

The second example shows how a servlet can render a page continuously. This type of page display can be used, for example, in chats: to read new messages, you will not need to refresh the page every time, new messages will simply be downloaded over time. It should be noted that some proxy servers do not support this type of data transfer, but with this - alas - nothing can be done.

import java. io. *; import javax. servlet. *; // the program implements the Servlet interface class DoloadServlet implements Servlet (ServletConfig config; // ServletConfig object public DoloadServlet () () // doing nothing // save config during initialization public void init (ServletConfig config) throws ServletException (this. config = config;) // gives out saved config public ServletConfig getServletConfig () (return config;) // servlet info public String getServletInfo () (return "DoloadServlet";) public void destroy () () // doing nothing // Processing request public void service (ServletRequest request, ServletResponse response) throws ServletException, java. io. IOException ( // we won't parse the request, it's just mess // create an HTTP header: String head = "HTTP / 1.0 200 OK \ n" + + "Server: DoloadServlet \ n" + "Content-Type: text / html; charset = UTF-8 \ n"+ "Connection: Keep-Alive \ n" + "Content-Encoding: multipart / mixed \ n"+ "Transfer-Encoding: chunked" + "Pragma: no-cache \ n \ n"; // now add the initial data // for this example - 20 tags "
"with line break
for (int i = 0; i< 20 ; i++ ) head = head + "
\ n "; // take the output stream ServletOutputStream os = response. getOutputStream (); // write the title and initial data there os. print (head); // send everything written to the buffer to the client response. flushBuffer (); // start adding new lines: // these lines will look like this: line number, then "
\ n "
// each new line will appear every 3 seconds int i = 0; while (true) ( // increment counter i ++; // write the line os. print ("" + i + "
\ n "); // flush the buffer response.flushBuffer (); // freeze the stream for 3 seconds try (sleep (3000);) catch (Exception e) ())))

It remains to say that the servlet mechanism is very flexible and allows you to do things that might require writing a separate WEB server (as, for example, in the case of a resume servlet). The disadvantages of servlets are the low speed of the first launch (the servlet is simply compiled by the JIT machine), high memory consumption and the lack of all Java programs - the low speed of working with strings. The latter circumstance becomes noticeable when servlets work that accept text data in POST requests. A 50 KB POST request to an HttpServlet when parsing with HttpServletRequest.getReader () can paralyze the server for a couple of minutes. The same applies to other java programs.

Here are two small examples:

// given a string String text // example 1 // working with a string using the "+" operation for String String test1 = ""; for (int i = 0; i< text. length(); i++ ) test1 += text. charAt(i); // example 2 // working with a string using a buffer char buf = new char [text. length ()]; for (int i = 0; i< text. length(); i++ ) buf[ i] = text. charAt(i); String sample2 = new String(buf);

If we take small strings - up to 2-3 kb, then the differences in the work of the examples are insignificant, but if we take a string text with a size of at least 10 kb, then in the first case the program will work with the string much slower. This is by design in java and is a problem in the implementation of the functions of the String class. So if you want to write a fast servlet, avoid working with long strings through the String class, for example use the StringBuffer class. This warning applies primarily to receiving large texts from the network and processing local files (for example, in the case of a text database for a guestbook with a large number of messages).

Another problem concerns the multitasking of the WEB system. Keep in mind that multiple users can request your servlet at the same time. There are often problems with data synchronization, the exchange of information between different computational threads of the same servlet, and the most common problem is the problem of synchronous access to files and other named system resources. For example, one program has opened a file for reading, while the other is trying to write something there. As a result, the second program either gets an exception or waits for the file to be freed for writing. In this regard, I would like to draw your attention: do not leave unclosed streams behind you and close streams as soon as there is no longer a need for them. The stream, of course, will close automatically later, but this will only happen when the "scavenger" gets to it, and meanwhile the second program will still not have write access to the file.

In addition to multitasking, I would like to note that using the "Object getAttribute (String name)" and "void setAttribute (String name, Object object)" methods of the ServletContext interface, you can exchange data between servlets, including synchronizing data.

One of the nicest features of Java is its multifaceted nature. Of course, building traditional desktop and even mobile apps is great. But what if you want to get off the beaten path and enter the territory of developing web applications in Java? The good news for you is that the language comes with a full Servlet API that allows you to build robust web applications without much hassle.

Writing Java Applications with Servlets

So, we have already created the configuration files for the application. However, in its current state, it literally does nothing. We want customers to be able to register using an HTML form, so the next thing we need to do is create JSP files that will display the above form and customer details after the registration is successful. This is what we are going to do now.

We are working on the appearance

The appearance of the application will be determined by two JSP files - in the context of MVC, these are called views. The first will be responsible for displaying the registration form and possible errors caused after checking the entered data. The second will be a regular welcome page, which will show the data entered by the customer upon successful completion of the registration process.

Here's the first JSP file:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> registration

registration

$ (violation).