Servlets and Cookies - cs.huji.ac.il

10
Servlets Servlets Part 2 Part 2 Representation and Management of Data on the Web Servlets and Cookies Servlets and Cookies Cookies Cookies Cookies are a general mechanism that server-side applications can use to both store and retrieve long-term information on the client side Servers send cookies in the HTTP response and browsers are expected to save and to send the cookie back to the Server, whenever they make additional requests to the Server Java Servlet API provides comfortable mechanisms to handle cookies The class javax.servlet.http.Cookie represents a cookie - Getter methods: • getName(), getValue(), getPath(), getDomain(), getMaxAge(), getSecure()- Setter methods: • setValue(), setPath(), setDomain(), setMaxAge()The domain to which the cookie is attached Servlets and Cookies API Servlets and Cookies API Kind of expiration date The path (prefix) to which the cookie is attached Send cookies on secure connections only or on any connection Read more about the Cookie Class Servlets and Cookies API (cont) Servlets and Cookies API (cont) Get the cookies from the servlet request: Cookie[] HttpServletRequest.getCookies() Add a cookie to the servlet response: HttpServletResponse.addCookie(Cookie cookie) An Example An Example <html> <head><title>Insert your Name</title></head> <body> <h1>What is your name?</h1> <form action="welcomeback" method="get"> <p> <input type="text" name="username" /> <input type="submit" /> </p> </form> </body> </html> getname.html

Transcript of Servlets and Cookies - cs.huji.ac.il

1

1ServletsServletsPart 2Part 2

Representation and Management of Data on the Web 2Servlets and CookiesServlets and Cookies

3CookiesCookies

• Cookies are a general mechanism that server-side applications can use to both store and retrieve long-term information on the client side

• Servers send cookies in the HTTP response and browsers are expected to save and to send the cookie back to the Server, whenever they make additional requests to the Server 4• Java Servlet API provides comfortable mechanisms to handle

cookies

• The class javax.servlet.http.Cookie represents a cookie

- Getter methods:

• getName(), getValue(), getPath(),getDomain(), getMaxAge(), getSecure()…

- Setter methods:

• setValue(), setPath(), setDomain(), setMaxAge()…

The domain to which the cookie

is attached

Servlets and Cookies APIServlets and Cookies API

Kind of expiration

date

The path (prefix) to which

the cookie is attached

Send cookies on secure

connections only or

on any connection

Read more about the Cookie Class

5Servlets and Cookies API (cont)Servlets and Cookies API (cont)

• Get the cookies from the servlet request:

Cookie[] HttpServletRequest.getCookies()

• Add a cookie to the servlet response:

HttpServletResponse.addCookie(Cookie cookie) 6An ExampleAn Example

<html><head><title> Insert your Name</title></head>

<body> <h1> What is your name?</h1>

<form action= "welcomeback" method= "get"><p>

<input type= "text" name= "username" />

<input type= "submit" />

</p></form>

</body>

</html>

getname.html

2

7An Example (cont)An Example (cont)

public class WelcomeBack extends HttpServlet {

public void doGet(HttpServletRequest req, HttpServletResponse res)throws ServletException, IOException {

String user = req.getParameter("username");if (user == null ) { // Find the "username" cookie

Cookie[] cookies = req.getCookies();for (int i = 0; cookies != null && i < cookies.length; ++i) {

if (cookies[i].getName().equals("username"))user = cookies[i].getValue();

}} else res.addCookie(new Cookie("username", user));

WelcomeBack.java

Look for “username”

cookie

If “user” parameter was sent, create a

“username” cookie

Look for

“username”

parameter in the

query 8An Example (cont)An Example (cont)

if (user == null ) // No parameter and no cookieres.sendRedirect("getname.html");

res.setContentType("text/html");PrintWriter out = res.getWriter();out.println("<html><body><h1>Welcome Back " + user

+ "</h1></body></html>");

}} WelcomeBack.javaRun /dbi/welcomeback twice or more.Check the sent headers Delay setting the

ContentType until it’s

clear that a content

should be sent at all

9Session Management with Session Management with ServletsServlets 10

Sessions Sessions –– A ReminderA Reminder

• HTTP is stateless

• But some web applications need states (e.g. online stores)

• A session captures the notion of a continuous interaction between a server and a client

• Session management should be efficient - The client should not send the whole shopping cart every time

a single product is added

• We’ll discuss 2 mechanisms- Session Cookies

- URL rewriting

11Session CookiesSession Cookies

Web browser 1

Web server

request request

Servlet

id1

response

put cookie id1

response

Create Session

id1 12Session CookiesSession Cookies

Web browser 2

Web server

request request

Servlet

id1

response

put cookie id2

response

Create Session

id2id2

3

13Session CookiesSession Cookies

Web server

request

Servlet

id1

response response

request

Cookie: id1

id2

Session read/write

Web browser 1

id1 14Session CookiesSession Cookies

Web server

request

Servlet

id1

response response

request

Cookie: id2

id2

Session read/write

Web browser 2

id2

15sessionId list

The lists are kept on

the server side

The cookies are kept

on the client side 16Here’s an example that demonstrates the session is attached to a specific application:1. Two new applications are available – test1, test22. Read the code of /test1/test1.jsp3. Read the code of /test2/test2.jsp4. Run /test1/test1.jsp, and use the links to go to the other application’s JSP and back several time.Notice that 2 session-cookies are set by the server, one for every application.5. Invalidate any of the application’s session and notice that the other application is still validA Session is attached to an ApplicationA Session is attached to an Application

17Accessing the Session DataAccessing the Session Data

• The session object is represented by the class HttpSession

• Use the methods HttpServletRequest.getSesssion() or HttpServletRequest.getSesssion(true) within doXXXto get the currentHttpSession object, or to create one if it doesn’t exist- Only when a new session is created, the server automatically

add a session cookie to the response (set-cookie header)

- As a result you must call this method before the response is committed

• Use HttpServletRequest.getSesssion(false) if you do not want to create a new session when no session exists 18

HttpSession MethodsHttpSession Methods• Session data is accessed in a hash-table fashion:

- setAttribute(String name,Object value)- Where is this value stored (server-side or client-side)?

- Object getAttribute(String name)

• More methods:

- removeAttribute()

- isNew()

- getId()

- Enumeration getAttributeName()

- getCreationTime(), getLastAccessedTime()

True iff there’s an active session

which the client hasn’t joined

yet.

That is:

• The server created a session

and sent session-cookie

• This session timeout was not

reached,

• No response from the client

containing this session-cookie

was received

A unique session ID assigned by

the servlet container

Read more about the HttpSession Interface

4

19Session Expiration Session Expiration –– Client sideClient side

• Session may expire because of client-side reasons

- The client agent runs on another process

- Session cookie has expired (exceeded max-age)

- Client used external links (writing the URL explicitly in the address-bar) instead of the server’s rewritten ones

Unless the session-cookie has max-age and you manage to open another

browser before max-age expired.

For example open

http://localhost/dbi/session?timeout=100&reload=50&maxage=20

Close your browser and open a new one with this URL again…

We’ll discuss the code in few more slides

Applies to URL-Rewriting . If the client is using cookies, external links

should raise no problem. (The session-cookie will be sent, though

only to URLs under the path like always…)20

Session Expiration Session Expiration –– Server sideServer side• Server calls session.invalidate()

- User asked to logout

• Session idle time has passed

- You can also set/get the timeout of a specific session

and override the server default values using session.getMaxInactiveInterval(), session.setMaxInactiveInterval()

<web-app > <session-config >

<session-timeout >10</session-timeout ></session-config >

</web-app >

web.xml

Timeout is given in

minutes .

A zero or negative value

means infinite timeout

webapps/myApp/WEB-INF/web.xml

21Session Expiration ExampleSession Expiration Example

public class SessionTester extends HttpServlet {

private int nReloads = 1;

public void doGet(HttpServletRequest req, HttpServletResponse res)

throws ServletException, IOException {

int timeout = Integer.parseInt(request.getParameter("timeout"));

int refresh = Integer.parseInt(request.getParameter("reload"));

int maxage = Integer.parseInt(request.getParameter("maxage"));

HttpSession session = request.getSession();

SessionTester.java

#Reloads (#GET request) with the

same session

Either find an existing session which the client already accepted its

session-cookie and sent it back in a request,

OR create a new session and send a session cookie

Read request

paramters 22if (session.isNew()) {

session.setMaxInactiveInterval(timeout);

nReloads = 1;

Cookie newCookie = new Cookie("JSESSIONID", session.getId());

newCookie.setMaxAge(maxage);

newCookie.setPath(request.getContextPath());

response.reset();

response.addCookie(newCookie);

} else { ++nReloads; }

response.setContentType("text/html");

PrintWriter out = response.getWriter();

Date found = (Date)session.getAttribute("lastdate");

Date now = new Date();

Reset counter

Create a new cookie

identical to the old one

and set client-side

limits on the session

using the max-age

Search for “lastdate ” in the session . This

attribute value is the session’s creation date

Only if a new session was created

Delete the headers

containing the old

cookie and add the

new cookie

Advance the counter

Set server-side limits on

session

23out.println("<html><head><title>Session Tester</title>");

out.println("<meta http-equiv=\"refresh\" content=\""

+ refresh + "\"/></head>\n");

out.println("<body>");

Cookie[] cookies = request.getCookies();

for (int i = 0; cookies != null && i < cookies.length; ++i) {

out.println("<h2>Client sent cookie : " + cookies[i].getName()

+ " = " + cookies[i].getValue() + "</h2>\n");

}

if ((cookies == null ) || (cookies.length) == 0) {

out.println("<h2>Client sent no cookies</h2>\n");}

Set the refresh rate

Print the request cookies

Or print there no cookies… 24if (session.isNew()) {

out.println("<h2>(New) Session ID = " + session.getId() + "</h2>\n");}

else { out.println("<h2>Session ID = " + session.getId() + "</h2>\n");}

out.println("<h2>Session max inactive interval = " + session.getMaxInactiveInterval() + "</h2>\n");

out.println("<h2>Current date = " + now + "</h2>\n");

if (found == null) {session.setAttribute("lastdate", now); out.println("<h2>No lastdate found in session<h2>\n");}

else {out.println("<h2>Found in session lastdate = " + found + "<h2>\n");}

out.println("<h2>#Responses with this session = " + nReloads + "</h2>\n");

out.println("</body></html>"); }

Print the session ID and declare if it’s a new one

Set the new

session’s

creation date

5

25Running the exampleRunning the example1. Run http://localhost/dbi/session.htmlwith timeout=10, reload=5, max-age=20.notice that the set-cookie isn’t sent in the response unless a new session is created2. Rerun with timeout=20, reload=5, max-age=103. Now deny to the servlet cookies modification request.Check the sent request headers, notice that in the next reload the server will ask again to set the session-cookie with a new session ID4. Run http://localhost/dbi/session?timeout=100&reload=50&maxage=100Run http://127.0.0.1/dbi/session?timeout=100&reload=50&maxage=100notice that a new session is created since the HOST string is different even tough 127.0.0.1 is the IP of localhost5. Run http://localhost/dbi/session2?timeout=100&reload=5This is a similar code without the explicit new cookie creation and max-age feature.Deny to save the session-cookie and notice that you’ll be asked to save a session-cookie after every reloadConclude that the call getSession() itself creates a new set-cookie header if no session was accepted by the user, and not the header manipulation code in which purpose is to set the max-age cookie property

If the client denies, it will not

send this cookie on the

following requests 26Example: A Basic Shopping CartExample: A Basic Shopping Cart

• In the following example a basic shopping cart for an online store is implemented

• The application consists of two Servlets:- Store.java: the main store site

- ShoppingCart.java: handles cart manipulation

27OnlineOnline--Store ExampleStore Example

public class Store extends HttpServlet {public void doGet(HttpServletRequest req, HttpServletResponse

res) throws ServletException, IOException {

res.setContentType("text/html");PrintWriter out = res.getWriter();out.println("<html><head>"

+ "<link rel=\"stylesheet\" type=\"text/css\""+ " href=\"cartstyle.css\"/></head><body>");

HttpSession session = req.getSession();if (session.getAttribute("item-list") == null ) {

out.println("<h1>Hello new visitor!</h1>");session.setAttribute("item-list", new LinkedList());

}List itemList = (List ) session.getAttribute("item-list");

Store.java

28OnlineOnline--Store Example (cont)Store Example (cont)

out.println("<h2>Your Shopping Cart:</h2><ol>");for (Iterator it = itemList.iterator(); it.hasNext();)

out.println("<li>" + it.next() + "</li>");

out.println("</ol>");

out.println("<form method=\"post\" action=\"cart\">");out.println("<p>Add item:<input name=\"item\" type=\"text\"/>"

+ "<input type=\"submit\" value=\"send\"/></p>"+ "<p><input type=\"submit\" value=\"empty cart\" "+ "name=\"clear\"/></p></form>");

out.println("</body></html>");}

} Store.java

2 buttons of type submit

and therefore they are

named (the 2nd one) , so

the servlet can identify

which one was pressed

on

29OnlineOnline--Store Example (cont)Store Example (cont)

public class ShoppingCart extends HttpServlet {public void doPost(HttpServletRequest req, HttpServletResponseres) throws ServletException, IOException {

res.setContentType("text/html");PrintWriter out = res.getWriter();

List items = (List ) req.getSession().getAttribute("item-list");

out.println("<html><head><link rel=\"stylesheet\""+ " type=\"text/css\" href=\"cartstyle.css\"/>"+ "</head><body>");

ShoppingCart.java

30OnlineOnline--Store Example (cont)Store Example (cont)

if (req.getParameter("clear") != null ) {items.clear();

out.println("<h2>Your Shopping Cart is Empty!</h2>");} else {

String item = req.getParameter("item");

items.add(item);out.println("<h2>The item <i>" + item +

"</i> was added to your cart.</h2>");}

out.println("<h2><a href=\"store\">Return to the store</a></h2>");out.println("</body></html>");

}} ShoppingCart.java

6

31URL RewritingURL Rewriting

• Cookies might cause some security risk- Would you really like any server to put files claimed to be

“cookies” on you computer ?- A computer is being used by multiple users

• User A buys some products• User B comes right after user A finished working• Cookies are kept as local files• User B can read the private content of A’s cookies

• Solution 1- Use session cookies instead of other cookies so that B can

only read the session ID- But B can still read the domain and the path

• Solution 2- Use URL-rewriting 32

URL RewritingURL Rewriting

Web browser

Web server

request request

Servlet

id1

response response

Create Session

<HTML>…

<A HREF=“servletURL;sessID=id1”>

…</HTML>

The domain and path are not sent

with the rewritten URLs, since the

sesion-ID is attached to the URL

only as long as the user follows

inner links. If the user writes a

complete URL in the address-bar

he/she will probably won’t copy

the session-ID part

33URL RewritingURL Rewriting

Web server

request

Servlet

id1

response response

request

(no cookie)

id2

Session read/write

Web browser 1

GET servletURL;sessID=id1 HTTP/1.0

<HTML>…

<A HREF=“servletURL2;sessID=id1”>

…</HTML> 34Servlet URL RewritingServlet URL Rewriting

• Use the following methods of the doXXX response object to rewrite URLs:

- String HttpServletResponse.encodeURL(String url) • Use for HTML hyperlinks

- String HttpServletResponse.encodeRedirectURL(String url)• Use for HTTP redirections

• These methods contain the logic to determine whether the session ID needs to be encoded in the URL

• For example, if the request has a cookie, thenurl is returned unchanged

• Some servers implement the two methods identically

35Back to our StoreBack to our Store

• The Store example assumes that the client supports cookies

• To fix the program, we should encode the links we supply:• Store.java:

"<form method=\"post\" action=\"" + res.encodeURL("cart") + "\">"

• ShoppingCart.java: “<a href=\"" + res.encodeURL("store") + "\">"Clear the cookies, run again http://localhost/dbi/store, and this time deny saving cookies.How does the server knows before the client denies/accepts what to put in the href? Check the first item’s URL sent to /cart and compare to the other items. You could also check compare the source of /store at the 1stitem and on other items 36

The Session ListenerThe Session Listener

• The session listener reacts to the following events:- A new session has been created

- A session is being destroyed

• To obtain a session listener, implement the interfacejavax.servlet.http.HttpSessionListener

Read more about the HttpSessionListener Interface

We’ve already met ContextListeners

that react to the events of context

creation / destruction…

7

37SessionSession--Listener Example (cont)Listener Example (cont)

public class CartInitializer implements HttpSessionListener {public void sessionCreated(HttpSessionEvent se) {

List itemList = new LinkedList();

se.getSession().setAttribute("item-list",itemList);itemList.add("A Free Apple");

}public void sessionDestroyed(HttpSessionEvent se) {}

} CartInitializer.java

<listener><listener-class>CartInitializer</listener-class>

</listener> web.xmlRun again http://localhost/dbi/store, only this time uncomment the listener 38The Servlet ContextThe Servlet Context

39Uses of ServletContextUses of ServletContext

• For communicating with the Servlet container (e.g., Tomcat server), we use theServletContext object

• Obtain a reference to the ServletContext by calling getServletContext() from any doXXX()

• One context is shared among all Web-application Servlets

• Can store Web application initialization parameters

• Can store and manipulate application-shared attributes

• Can be used to access the logger

• Can be used to dispatch requests to other resources 40We came across this method in JSP

class

(application.getInitParameter() )

ServletContext MethodsServletContext Methods• Access initialization parameters:

getInitParameter(String name), getInitParameterNames()

• Read Web-application scoped attributes:getAttribute(String name), getAttributeNames()

• Manipulate Web-application scoped attributes:setAttribute(String, Object), removeAttribute(String)

• Transform context-relative paths to absolute paths and vice versa:getRealPath(String path), URL getResource(String path)

e.g. get the servlet’s class filename

from its mappingRun http://localhost/dbi/context.htmlJNDI = Java Naming and Directory Interface e.g. get the URL from a static resource

(doesn’t work well with

servlet-mappings )

41More More ServletContextServletContextMethodsMethods

• Write to the application log:

log(String msg), log(String message, Throwable exception)

• Get a request dispatcher (discussed later):RequestDispatcher getRequestDispatcher(String path)

• Name and version of the Servlet container:

String getServerInfo()

Writes also the stack trace

$CATALINA_BASE/logs/… 42Note about ServletContextNote about ServletContext

• There is a single ServletContext per Web application

• Different Sevlets will get the same ServletContext

object, when calling session,getServletContext()

during different sessions

• You can lock the context (using synchronize) to protect a critical section from all Web-application accesses

Read more about the ServletContext Interface

8

43The Request DispatcherThe Request Dispatcher 44The Request DispatcherThe Request Dispatcher

• The RequestDispatcher object is used to send a a client request to any resource on the server

• Such a resource may be dynamic (e.g. a Servlet or a JSP file) or static (e.g. a HTML document)

• To send a request to a resource x, use:getServletContext().getRequestDispatcher("x")

Path must begin with a “/” and is interpreted as

relative to the current context root

45Request Dispatcher MethodsRequest Dispatcher Methods

• void forward(ServletRequest request, ServletResponse response)

- Forwards a request from a Servlet to another resource

• void include(ServletRequest request, ServletResponse response)

- Includes the content of a resource in the response of the

current servlet

Read more about the RequestDispatcher Interface 46Passing on DataPassing on Data

• 3 different ways to pass parameters for the forwarded Servlet or JSP

- Data that will be used only for this request:

request.setAttribute("key", value);

- Data will be used for this client (also for future requests):

session.setAttribute("key", value);

- Data that will be used in the future for every client

context.setAttribute("key", value);

47An ExampleAn Example

• The Servlet JokesAndImages enables a user to choose a random joke or a random image

• The server has 5 images in the directory images/ and 5 jokes (txt files) in the directory jokes/

• Empty requests are forwarded to a HTML file that enables the user to choose a joke or an image

• Requests to a joke are forwarded to the servlet Jokes

• Requests to an image are forwarded to a random image from the directory images/ 48

Jokes and ImagesJokes and Images

<html>

<head><title>Images and Jokes</title></head>

<body>

<h1>Please Select:</h1>

<form method="post" action="JokesAndImages">

<h2>

<input type="submit" name="joke"

value="A Joke" />

<input type="submit" name="image"

value="An Image" />

</h2>

</form>

</body></html> imagesJokesOptions.html

9

49Jokes and Images (cont)Jokes and Images (cont)

public class JokesAndImages extends HttpServlet {public void doPost(HttpServletRequest req, HttpServletResponse res)

throws ServletException, IOException {

int randomNum = 1 + Math .abs((new Random ()).nextInt() % 5);if (req.getParameter("joke") != null ) {req.setAttribute("jokeNumber", new Integer (randomNum));

getServletContext().getRequestDispatcher("/Jokes").forward(req,res);} else if (req.getParameter("image") != null ) {getServletContext().getRequestDispatcher("/images/image" +

randomNum + ".gif").forward(req, res);

} else getServletContext().getRequestDispatcher("/imagesJokesOptions.html"). forward(req,res);

}public void doGet ... }} JokesAndImages.java 50

Jokes and Images (cont)Jokes and Images (cont)public class Jokes extends HttpServlet {

public void doPost(HttpServletRequest req, HttpServletResponse res)throws ServletException, IOException {res.setContentType("text/html"); PrintWriter out = res.getWriter();out.println("<html><body><h1>A Joke</h1><pre>");

int jokeNum = ((Integer ) req.getAttribute("jokeNumber")).intValue();getServletContext().getRequestDispatcher

("/jokes/joke" + jokeNum + ".txt").include(req, res);out.println("\n</pre>");

out.println("<a href=\"" + req.getRequestURL() + "\">Back</a>");out.println("</body></html>");

}}

Jokes.javaActually since this request was forwarded using a RequestDispatcher the

URL reflects the path used to obtain the RD and not the path specified

by the client as usual. You can use Javascript to fix this problem.

Check http://localhost/dbi/forward1 to understand the problem

51Forwarding versus RedirectionForwarding versus Redirection

• HttpServletResponse.SendRedirect() requires extra communication on part of the client: Why?

• SendRedirect does not pass the request therefore request’s parameters cannot be obtained easily

• You can’t reach external resources with RequestDispatcher but you can useSendRedirect

• SendRedirect ends up with a different URL on the client

• Which image will be loaded in the following scenario? Servlet/forwardjoke forwards to /jokes/joke1.html and joke1.htmlcontains <img src="image1.gif".../>

You can use either the session or the context to pass those parametersOpen /dbi/image1.gif, /dbi/jokes/image1.gif, /dbi/jokes/joke1.hmtl, /dbi/forwardjoke and check… 52FiltersFilters

53Filters in Servlet APIFilters in Servlet API

• Filters are used to dynamically intercept requests and responses

• A filter that applies to a URL u typically acts as follows given a request for u- performs some actions before the processing of u

- passes the request handling to the next filter

- The last filter passes the request to u itself

- performs some actions after the processing of u 54

10

55public class FilterExample implements Filter {

public void init(FilterConfig filterConfig) throws ServletException {

...

}

public void destroy() {

...

}

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException , ServletException {

...

chain.doFilter(request, response);

...

}} FilterExample.java

Before other elements in

way “down”

After other elements in way

“up” 56<filter><filter-name>Example Filter</filter-name><filter-class>FilterExample</filter-class>

</filter>

<filter-mapping><filter-name>Example Filter</filter-name><url-pattern>/images/*</url-pattern>

</filter-mapping>

Registering a FilterRegistering a Filter

web.xml

You can also add

<init-param>

element like we

saw in servlets

and JSPs .

57What Can we Do with Filters?What Can we Do with Filters?

• Examine and log requests

• Modify request headers and properties

• Modify the response headers and response data

• Block requests

• And more...Open FilterExample.java.Check the result of calling http://localhost/dbi/images/image1.gif in the server’s logs 58Notes About FiltersNotes About Filters

• The order of the filters in the chain is the same as the order that filter mappings appear web.xml

• The life cycle of filters is similar to that of Servlets

• Filters typically do not themselves create responses, although they can

• The request and response arguments of doFilter are actually of type HttpServletRequest and HttpServletResponse

• The FilterConfig interface is used to read initialization parameters- Those are set in web.xml

59public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException {

HttpServletResponse res = (HttpServletResponse)response;

HttpServletRequest req = (HttpServletRequest)request;

String URI = req.getRequestURI();

if (URI.endsWith(filterConfig.getInitParameter("type")) &&

(req.getParameter("nofilter") == null)) {

res.setContentType("text/html");

PrintWriter out = res.getWriter();

out.println("<html><head><title>ImageFilter</title></head><body>");

out.println("<h2>Image filename = " + URI + "</h2>\n");

out.println("<img src=\"" + URI.substring(1 + URI.lastIndexOf("/")) +

"?nofilter\" />");

out.println("</body></html>"); } ImageFilter.java

URI is the part of the URL

following the http://host:port

Only for filetypes <type> with no

“nofilter” parameter in the

query

We have to add the “nofilter” query so that

the filter won’t work again on the <img> 60else {chain.doFilter(request, response); }}

<filter>

<filter-name>fImageFilter</filter-name>

<filter-class>ImageFilter</filter-class>

<init-param>

<param-name>type</param-name>

<param-value>.gif</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>fImageFilter</filter-name>

<url-pattern>/images2/*</url-pattern>

</filter-mapping>

Default filter chaining .

This time next element in the

chain is not a filter but the

original URL

web.xml

The Filter applies only to .gif

files in /dbi/images/ but not

for other files on the same

directory such as .txtOpen /images2/image1.gifOpen /images2/joke1.txturl-pattern of /images2/*.gif

doesn’t work.

That’s why we check the suffix in

the Java code