- Servlet - provides dynamic, user-oriented content in web apps using request-response programming model
- Servlet - Java class
- It is used to extend capabilities of servers that host applications accessed by means of request-response programming model
- They are commonly used to extend apps hosted by web servers (but can respond to any type of request)
- HTTP Specific servlet classes are defined for HTTP requests
javax.servletandjavax.servlet.http- Packages have interfaces & classes for writing servlets
- All servlets must implement
ServletinterfaceServletinterface defines lifecycle methods
- If generic service needs to be implemented, use or extend
GenericServletclass (provided with Java Servlet API) HTTPServletclass provides methods for handling HTTP-specific servicesdoGetdoPost
- Lifecycle of servlet is controlled by container (in which servlet is deployed)
- When request is mapped to servlet, container performs following steps
- If an instance of the servlet does not exist, the web container
- Loads the servlet class
- Constructs an instance of the servlet class
- Initializes servlet instance by calling
initmethod (initialization is covered in Constructing and Initializing a Servlet
- Container invokes
servicemethod- Request and response objects are passed
- Writing Service Methods
- If container needs to remove servlet, it finalizes servlet by calling servlet's
destroymethod.
- If an instance of the servlet does not exist, the web container
- One can monitor and react to events in servlet's lifecycle by defining listener objects whose methods get invoked when lifecycle events occur.
- To use listener objects,
- Define and specify listener class
- To use listener objects,
-
Defined by implementing a listener interface
- Events that can be monitored for:
- Web context object - Initialization and destruction -
javax.servlet.ServletContextListenerandServletContextEvent - Web context object - Attribute added, removed, or replaced -
javax.servlet.ServletContextAttributeListenerandServletContextAttributeEvent - Session object - Creation, invalidation, activation, passivation, and timeout -
javax.servlet.http.HttpSessionListener,javax.servlet.http.HttpSessionActivationListener,HttpSessionEvent - Session object - Atribute added, removed, or replaced -
javax.servlet.http.HttpSessionAttributeListenerandHttpSessionBindingEvent - Request object - A servlet request has started being processed by web components -
javax.servlet.ServletRequestListenerandServletRequestEvent - Request object - Attribute added, removed, or replaced -
javax.servlet.ServletRequestAttributeListenerandServletRequestAttributeEvent
- Web context object - Initialization and destruction -
- Events that can be monitored for:
-
@WebListener- used to define listener to get events for operations on particuler web application context-
Classes annotated with
@WebListener(M)javax.servlet.ServletContextListener javax.servlet.ServletContextAttributeListener javax.servlet.ServletRequestListener javax.servlet.ServletRequestAttributeListener javax.servlet.http.HttpSessionListener javax.servlet.http.HttpSessionAttributeListener
-
-
Example: Following code implements two of the listeners
import javax.servlet.ServletContextAttributeListener; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; @WebListener() public class SimpleServletListener implements ServletContextListener, ServletContextAttributeListener { // ... }
-
Exceptions can occur when servlet executes
-
The following page gets shown when exception occurs
A Servlet Exception Has Occurred- This can be overridden by specifying error page for given exception
- Web components (like other objects) work with other objects (usually) to accomplish their tasks
- Web components can do so by doing the following:
- Using private helper objects (example: JavaBeans components)
- Sharing objects that are attributes of public scope
- Using database
- Invoking other web resources
- Collaborating web components share info by means of objects maintained as attributes of four scope objects
- Using
getAttribute&setAttributemethods of the class representing scope- Web context scope object -
javax.servlet.ServletContext- Accessible from web components within a web context. Accessing the Web Context - Session scope object -
javax.servlet.http.HttpSession- Accessed by web components handling request that belongs to session. Maintaining Client State - Request scope object - Subtype of
javax.servlet.ServletRequest- Accessed by web components handling the request - Page scope object -
javax.servlet.jsp.JspContext- JSP page that constructs the object
- Web context scope object -
- Using
- In multithreaded server, shared resources can be accessed concurrently
- (In addition to scope object attributes) shared resources include
- in-memory data
- Instance or class variables
- External objects (files, database connections, network connections)
- in-memory data
- Concurrent access can arise in many situations
- Multiple web components accessing objects stored in web context
- Multiple web components accessing objects stored in a session
- Multiple threads within a web component accessing instance variables.
- Web container typically constructs a thread to handle each request
- To ensure servlet instance handles only one request at a time?
- Servlet can implement
SingleThreadModel(M) interface- No two threads can execute concurrently in servlet's service method
- Implementation: Web container synchronizes access to single instance of servlet or by maintaining a pool of web component instances and dispatching each new request to free instance
- Caveat: The interface does not prevent synchronization problems that result from web components accessing shared resources
- Static class variables
- External objects
- Servlet can implement
- To ensure servlet instance handles only one request at a time?
- Web container typically constructs a thread to handle each request
- If resources are accessed concurrently, they can be used in inconsistent fashion
- Solution: Synchronization using threads
@WebServlet(M) is used to define servlet component in web application- The annotation is specified on a class
- It contains metadata about servlet declared
- Must declare at least one URL pattern
- Two ways to do it:
urlPatternsattribute (when other attributes are also used)valueattribute (when it is the only attribute)
- Two ways to do it:
- Must declare at least one URL pattern
- Classes annotated with
@WebServletmust extend:javax.servlet.http.HttpServlet-
Example:
import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; @WebServlet("/report") public class MoodServlet extends HttpServlet { ... }- Web container initializes servlet after loading and instantiating servlet class and before delivering requests from clients
- Customization of the process:
- To allow servlet to read persistent config data, initialize resources, perform any other one-time activities:
- Override
initmethod ofServletinterface or - Specify
initParamsattribute of@WebServletannotation- It contains
@WebInitParamsannotation
- It contains
- Override
- To allow servlet to read persistent config data, initialize resources, perform any other one-time activities:
- If servlet cannot complete initialization process, it throws
UnavailableException
-
- Use init parameter to provide data needed to a particular serlvet
- A context parameter provides data available to all components of web application
- Service provided by servlet is
- In
servicemethod ofGenericServlet - In
doMethod methods (Method can beGet,Delete,Options,Post,Put, orTrace) ofHttpServletobject (or any other protocol-specific methods defined by class that implementsServletinterface)
- In
- service method is used for any method in servlet class that provides service to client
- General pattern of service method:
- Extract info from request
- Access external resources
- Populate response (based on info)
- HTTP Servlets - procedure to populate response
- Retrieve an output stream from response
- Fill in response headers
- Write body content to output stream
- Response headers must be set before the response is committed
- Web container will ignore attempt to set or add headers after response has been committed
- Next: How to get info from requests and generate responses
- Request contains data passed between client and servlet
- All requests implement -
ServletRequestinterfaceServletRequest- has methods for accessing following info- Parameters - typically used to convey info between clients and servlets
- Object-valued attributes - typically used to pass info between web container and servlet or between collaborating servlets
- Info about protocol used to communicate request & about client and server involved in request (?)
- Info relevant to localization
- An input stream can be retrieved and data be manually parsed
BufferedReader- for character data- Returned by request's
getReadermethod
- Returned by request's
ServletInputStream(M) - to read binary data- Returned by
getInputStream
- Returned by
- All requests implement -
- HTTP servlets are passed HTTP request object -
HttpServletRequest-
It contains
- Request URL
- HTTP headers
- Query string
- ...
-
HTTP request URL has following parts
http://[host]:[port][request-path]?[query-string]- Request path is composed of:
- Context path - concatenation of
/with context root of servlet's web application - Servlet path - Path section that corresponds to component alias that activated this request (?)
- Path starts with
/
- Path starts with
- Path info - Part of request path that is not part of context path or servlet path
- Context path - concatenation of
getContextPath- to access context pathgetServletPath- to access servlet pathgetPathInfo- to get other parts
- Request path is composed of:
-
- URI always has the three parts
- Irrespective of encoding differences between request URI and path parts
- Query strings
- Composed of set of params and values
- Individual params are retrieved using
getParametermethod
- Individual params are retrieved using
- Two ways to generate query strings
- query string can explicitly appear in web page
- query string is appended to URL when form with
GETHTTP method is submitted
- Composed of set of params and values
- Response contains data passed between server and client
- All responses implement
ServletResponseinterface. The interface defines methods to do:- Retrieve output stream to use to send data to client
PrintWriter- to send character data- Returned by
getWritermethod
- Returned by
ServletOutputStream- to send binary data in Multipurpose Internet Mail Extensions (MIME) body response- Returned by
getOutputStream
- Returned by
- To mix binary and text data (as multipart response)
- Use
ServletOutputStream- Need to manage character sections manually
- Use
- Indicate content type (example:
text/html) being returned by response withsetContentType(String)- Method must be called before response is committed
- Registry of content type names: Internet Assigned Numbers Authority (IANA)
- Indicate whether to buffer output with
setBufferSize(int)- Default behaviour:
- Any content written to output stream is immediately sent to client
- Buffering:
- Content is written first before sending anything back to client
- Use case: gives servlet more time to set appropriate status codes and headers or forward to another web resource
- Partially written content?
- Use case: gives servlet more time to set appropriate status codes and headers or forward to another web resource
- Content is written first before sending anything back to client
- Method must be called before any content is written or before response is committed
- Default behaviour:
- Set localization information:
- Locale
- Character encoding
- Retrieve output stream to use to send data to client
- All responses implement
javax.servlet.http.HttpServletResponse- has fields representing HTTP headers- Status codes
- Used to indicate reason a request is not satisfied or that request has been redirected
- Cookies
- Used to store application-specific information at client
- User session: Cookies can be used to track id information of a user session
- Status codes
- filter - It is an object that can transform header and content (or both) of request or response
- Difference as compared to web components:
- usually do not themselves construct response
- It has functionality that can be attached to any kind of web resource
- It should not have any dependency on a web resource (for which it is a filter)
- It can be composed with more than one type of web resource
- It should not have any dependency on a web resource (for which it is a filter)
- Difference as compared to web components:
- Tasks performed by a filter:
- Query request and act accordingly
- Block request-and-response pair from passing any further
- Modify request headers and data
- Done by providing customized version of request
- Modify response headers and data
- Done by providing customized version of response
- Applications of filters:
- Authentication
- Logging
- Image conversion
- Data compression
- Encryption
- Tokenizing streams
- XML transformations
- ...
- A web resource can be configured to be filtered by a chain of - zero, one, or more filters in specific order
- Chain is specified when web application containing component is deployed and instantiated when web container loads component
-
API is defined by:
Filter,FilterChain,FilterConfiginterfaces injavax.servletpackageFilter- used to implement filter@WebFilterannotation is used to define a filter in web application- It is specified on a class & contains metadata about filter being declared
- It must specify atleast one URL pattern
urlPatterns- used to define url patterns (used if other attributes are also used)value- used to define single url pattern (used if it is the only attribute)
- Other attributes are optional (they have default settings)
-
Classes annotated with
@WebFiltermust implementFilterinterface -
initParamsis used to add config data to filter in@WebFilter-
Contains
@WebInitParamannotation (M) -
Example: Specifying initialization parameter
import javax.servlet.Filter; import javax.servlet.annotation.WebFilter; import javax.servlet.annotation.WebInitParam; @WebFilter(filterName = "TimeOfDayFilter", urlPatterns = {"/*"}, initParams = { @WebInitParam(name = "mood", value ="awake") }) public class TimeOfDayFilter implements Filter { ...
-
-
Most important method in
Filterinterface isdoFilter- The method is passed request, response, filter chain objects
- The method can perform the following:
- Examine request headers
- Customize request object if fiter wishes to modify request headers or data
- Customize response object if filter wishes to modify response headers or data
- Invoke next entity in filter chain
- If current filter is last filter in chain that ends with target web component or static resource
- Next entity is resource at the end of chain (forwarded to web component or static resource)
- Else
- It is next filter that was configured in WAR
- Filter invokes next entity by calling
doFilteron chain object- Request and response are passed that the original filter was called with (or wrapped versions that it might have instantiated)
- Alternatively:
- Filter can choose to block request by not making call to invoke next entity
- In this case:
- Filter is responsible for filling up the response
- In this case:
- Filter can choose to block request by not making call to invoke next entity
- If current filter is last filter in chain that ends with target web component or static resource
- Examine response headers after invoking next filter in chain
- Throw exception to indicate error in processing
-
initanddestroymust be imlemented in addition todoFilterinit- called by container when filter is instantiated- If initialization parameters need to be passed to filter:
- Retrieve them from
FilterConfigobject passed toinit
- Retrieve them from
- If initialization parameters need to be passed to filter:
- There are many ways for filter to modify request or response
- Example: Filter can add attribute to request or can insert data in response
- Filter that needs to modify response must capture response before it is returned to client
- Procedure to do that:
- Pass stand-in stream to serlvet (that generates response)
- stand-in stream prevents servlet from closing original response stream when it completes
- This allows filter to modify servlet's response
- stand-in stream prevents servlet from closing original response stream when it completes
- Pass stand-in stream to serlvet (that generates response)
- Procedure to do that:
- Filter that needs to modify response must capture response before it is returned to client
- Example: Filter can add attribute to request or can insert data in response
- How to pass stand-in stream to servlet?
- Filter constructs a response wrapper that overrides
getWriterorgetOutputStreamto return the stand-in stream- Wrapper is passed to
doFiltermethod of filter chain - Wrapper methods default to calling through to wrapped request or response object
- To override request methods
- Wrap request in object that extends either
ServletRequestWrapper(M) orHttpServletRequestWrapper
- Wrap request in object that extends either
- To override response methods
- Wrap response in object that extends either
ServletResponseWrapperorHttpServletResponseWrapper
- Wrap response in object that extends either
- To override request methods
- Wrapper is passed to
- Filter constructs a response wrapper that overrides
-
Web container uses filter mappings to decide how to apply filters to web resources
- Filter mapping
- Matches filter to web component by name or to web resource by URL pattern
- Filters are invoked in order in which filter mappings appear in filter mapping list or WAR
- Filter mapping list:
- Specified in deployment descriptor
- Using NetBeans IDE
- Coding list in XML
- Specified in deployment descriptor
- Filter mapping list:
- Filter mapping
-
Example: To log every request to a web application
- Map hit counter filter to URL pattern
/*
- Map hit counter filter to URL pattern
-
A filter can be mapped to one or more web resources
-
More than one filter can be mapped to a web resource (Many-to-Many)
- F1 is mapped to S1, S2, S3
- F2 is mapped to S2
- F3 is mapped to S1, S2
-
Filter chain:
- It is one of the objects passed to
doFiltermethod of filter - Chain is formed indirectly by means of filter mappings
- Order of filters in chain is same as order in which filter mappings appear in web app deployment descriptor
- It is one of the objects passed to
-
Invocation:
- When filter is mapped to servlet S1, web container invokes
doFilterof F1 doFiltermethod of each filter in S1's filter chain is invoked by preceding filter in chain by means ofchain.doFiltermethod- F1's call to
chain.doFilterinvokdesdoFilterof F3 (F3 follows F1) - When F3's
doFiltercompletes, control returns to F1'sdoFilter
- When filter is mapped to servlet S1, web container invokes
- Steps:
- Expand application's project node in Project tab
- Expand Web Pages and WEB-INF nodes under project node
- Double click web.xml
- Click Filters at the top of editor window
- Expand Servlet Filters node in editor window
- Click Add Filter Element to map filter to web resource by name or by URL pattern
- In Add Servlet Filter dialog box, enter name of filter in Filter Name field
- Click Browse to locate servlet class to which filter applies
- We can include wildcard characters so that you can apply filter to more than one servlet
- Click OK
- To constrain how filter is applied to requests follow the steps below:
- Expand Filter Mappings node
- Select filter from list of filters
- Click Add
- In Add Filter Mapping dialog box, select one of following dispatcher types
- REQUEST - Only when request comes directly from client
- ASYNC - Only when asynchronous request comes from client
- FORWARD - Only when request has been forwarded to a component (Transferring Control to Another Web Component)
- INCLUDE - Only when request is being processed by a component that has been included (Including Control to Another Web Component)
- ERROR - Only when request is being processed with error page mechanism (Handling Servlet Errors)
- We can direct filter to be applied to any combinations of preceding situations by selecting multiple dispatcher types
- Defautl is REQUEST if no types are specified
- Web components can invoke other web resources directly and indirectly
- Indirect method:
- Web compoenent indirectly invokes another web resource by embedding URL that points to another web component in content returned to client
- Direct method:
- While a web component is executing, it directly invokes another resource by either including content of another resource or forwarding a request to another resource
- To invoke resource available on server that is running web component:
- First obtain
RequestDispatcherobject by usinggetRequestDispatcher("URL")method- It can be obtained either from:
- Request or
- Web context
- The two methods have slightly different behaviour
- Method takes path to requested resource as an argument
- Request can take relative path
- That does not begin with
/- But Web context - requires absolute path
- That does not begin with
- Request can take relative path
- It can be obtained either from:
- If resource is not available, or if server has not implemented
RequestDispatcherobject for the type of resource,getRequestDispatcherwill returnnull- Serlvet should deal with this condition
- First obtain
-
It is often useful to include another web resource (such as banner content or copyright info) in response returned from web component
- How to do that?
-
Invoke the following method of
RequestDispatcherinclude(request, response);
-
- How to do that?
-
If resource is static:
includemethod enables programmatic server-side includes -
If resource is web component: effect of the method is to
- Send request to included web component
- Execute web component
- Include result of execution in response from containing servlet
-
Included web component has access to request object but is limited in what it can do with response object
- It can write to body of response and commit a response
- It cannot set headers or call any method that affects headers of response
setCookiesay
- In certain applications, we might want to have
- One web component do preliminary processing of request
- Another component generate response
- Example: We want to partially process a request and then transfer to another component (depending on nature of request)
- To transfer control to another web component, invoke
forwardofRequestDispatcher-
Request URL is set to the path of forwarded page
-
Original URI and it's parts are saved as following request attributes:
javax.servlet.forward.request_uri javax.servlet.forward.context_path javax.servlet.forward.servlet_path javax.servlet.forward.path_info javax.servlet.forward.query_stringforwardmethod should be used to given another resource responsibility for replying to user- If
ServletOutputStreamorPrintWriterhave already been accessed in servlet, we cannot use this methodIllegalStateExceptionwill get thrown
- If
-
- Context in which web components execute is an object that implements
ServletContextinterface- Web context is retrieved using
getServletContextmethod - Web context:
- Provides methods for accessing
- Initialization parameters
- Resources associated with the web context (?)
- Object-valued attributes
- Logging capabilities
- Provides methods for accessing
- Web context is retrieved using
- Counter's access methods are synchronized to prevent incompatible operations by servlets running concurrently
- Filter retrieves counter object by using context's
getAttributemethod - Incremented value of counter is recorded in log
- Filter retrieves counter object by using context's
- Applications may require series of requests from client be associated with one another
- Example: Web application can save state of user's shopping cart across requests
- Application is responsible for maintaining such state called sesion (Since HTTP is stateless)
- To support apps that need to maintain state, Java Servlet technology provides API for managing sessions & allows mechanisms for implementing sessions
- Application is responsible for maintaining such state called sesion (Since HTTP is stateless)
- Example: Web application can save state of user's shopping cart across requests
- Sessions are represented by
HttpSessionobject- A session is accessed by calling
getSessionmethod of request object- Method returns current session associated with the request
- or
- If request does not have a session, a session is created
- A session is accessed by calling
- If attribute values are objects, they can be associated with a session by name
- The attributes are accessible by any web component that belongs to same web context and is handling request that is part of same session
- Application can notify web context and session listener objects of servlet lifecycle events
- Objects can also be notified of certain events which is related to their association with session
- When object is added or removed from session:
- The object must implement
javax.servlet.http.httpSessionBindingListenerinterface
- The object must implement
- When session to which object is attached is passivated or activated:
- Passivation or activation occurs when object is moved between virtual machines
- Passivation or activation occurs when object is saved to or restored from persistent storage
- Object must implement
javax.servlet.http.HttpSessionActivationListenerinterface to receive notifications
- When object is added or removed from session:
- HTTP client has no way to signal that it no longer needs a session,
- Each session has an associated timeout (to reclaim the resources)
- Timeout period can be accessed using session's
getMaxInactiveIntervalsetMaxInactiveInterval
- Notes:
- To ensure an active session is not timed out, periodically access the session by using service methods
- This resets session's time-to-live counter
- When particular client interaction is finished, use session's
invalidatemethod to invalidate a session on server side and remove session data
- To ensure an active session is not timed out, periodically access the session by using service methods
- In deployment descriptor:
- Open project if not already opened
- Expand node of your project in Projects tab
- Expand Web Pages and WEB-INF nodes under project node
- Double click
web.xml - Click General at top of editor
- In Session Timeout field, enter an integer value
- It represents number of minutes of inacitivity that must pass before session times out
- Several methods can a web container use to associate a session with user
- All methods involve passing an identifier between client and server
- Identifier can be:
- Maintained by client as a cookie
- includes by web component in every URL that is returend to client
- Identifier can be:
- All methods involve passing an identifier between client and server
- If application uses session objects
- We must ensure that session tracking is enabled by having application rewrite URLs whenever client turns off cookies
- Done by calling response's
encodeURL(url)method on all URLs returned by servletencodeURL(url)- includes session ID in URL if cookies are disabled or else, returns URL unchanged
- Done by calling response's
- We must ensure that session tracking is enabled by having application rewrite URLs whenever client turns off cookies
- Web container may determine that servlet should be removed from service
- Example:
- When container wants to reclaim memory resources
- When container is being shut down
- Example:
- Container calls
destroymethod ofServletinterface- In this method, we release resources servlet is using and save persistent state
- Releases database object constructed in
initmethod
- Releases database object constructed in
- In this method, we release resources servlet is using and save persistent state
- Servlet's service methods should be complete when servlet is removed
- Server tries to ensure this by calling
destroyonly after all service requests have returned or after server-specific grace period (whichever comes first)- If servlet has operations that may run longer than server's grace period, operations could still be running when
destroyis called- Ensure threads still handling client requests complete
- If servlet has operations that may run longer than server's grace period, operations could still be running when
- Server tries to ensure this by calling
- Next: How to do the following:
- Keep track of how many threads are currently running
servicemethod - Provide clean shutdown by having
destroymethod notify long-running threads of shutdown and wait for them to complete - Have long-running methods poll periodically to check for shutdown and, if necessary, stop working, clean up, and return
- Keep track of how many threads are currently running
-
To track service requests:
- Include in servlet class a field that counts number of service methods running
- The field should have synchronized access methods to increment, decrement and return its value
- Include in servlet class a field that counts number of service methods running
-
Implementation
public class ShutdownExample extends HttpServlet { private int serviceCounter = 0; ... // Access methods for serviceCounter protected synchronized void enteringServiceMethod() { serviceCounter++; } protected synchronized void leavingServiceMethod() { serviceCounter--; } protected synchronized int numServices() { return serviceCounter; } } -
servicemethod should increment service counter each time method is entered and should decrement counter each time method returns- This is one time
HttpServletsubclass should overrideservicemethod - New method should call
super.serviceto preserve functionality of originalservicemethod
- This is one time
-
Implementation:
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { enteringServiceMethod(); try { super.service(req, resp); } finally { leavingServiceMethod(); } }
-
To ensure clean shutdown,
destroymethod should not release shared resources until all service requests have completed- A part of doing this is to check service counter
- Another part is to notify long-running methods that it is time to shutdown
- For this another field is required
- The field should have the usual access methods
- For this another field is required
-
Example:
public class ShutdownExample extends HttpServlet { private boolean shuttingDown; ... // Access methods for shuttingDown protected synchronized void setShuttingDown(boolean flag) { shuttingDown = flag; } protected synchronized boolean isShuttingDown() { return shuttingDown; } } -
Exmaple:
destroypublic void destroy() { /* Check to see whether there are still service methods */ /* running, and if there are, tell them to stop. */ if (numServices() > 0) { setShuttingDown(true); } /* Wait for the service methods to stop. */ while (numServices() > 0) { try { Thread.sleep(interval); } catch (InterruptedException e) { } } }
-
Last step in providing clean shutdown:
- Make long-running methods behave politely
- Methods should check value of the field that notifies them of shutdowns and should interrupt their work, if necessary
- Make long-running methods behave politely
-
Example:
public void doPost(...) { ... for (i = 0; ((i < lotsOfStuffToDo) && !isShuttingDown()); i++) { try { partOfLongRunningOperation(i); } catch (InterruptedException e) { ... } } }
- In prior versions of Servlet spec, implementing file uploads required use of external libraries or complex input processing
- Java Servlet spec now has viable solution to problem in generic and portable way
- It supports file uploads out of the box
- Any web container that implements the spec can parse multipart requests and make mime attachments available through
HttpServletRequestobject
- Any web container that implements the spec can parse multipart requests and make mime attachments available through
- It supports file uploads out of the box
- New annotation:
javax.servlet.annotation.MultipartConfig- used to indicate that servlet on which it is declared expects requests to be ade usingmultipart/form-dataMIME type
- Web containers in app servers usually use a server thread per client request
- If there is heavy load, containers need large amount of threads to serve all client requests
