h2

townripeData Management

Jan 31, 2013 (4 years and 6 months ago)

219 views

1

Servlets:

Leftover Odds and Ends

(Most apply to JSPs as
well, duh….)

Representation and Management of
Data on the Internet, 2007

CS Department, HUJI

2

A Warning: Don’t Panic…


Many of the examples in this presentation are
using various features not discussed throughout
this course.


There is not need to understand them in a deeper
extent than the understanding of the relevant
examples.


They are there to give you a general idea of what
these feature names refer to and what can be
done with them.


Google these features if you want / ever need to...

3

Exceptions


Exceptions are caught by the server


You can find them in the log file under

$CATALINA_BASE/logs/


The result shown in the browser depends on the
buffer state


Check the example on the next slide…


Find the exceptions in the log


4

Run :

http://localhost/dbi/exception?nlines=
10

http://localhost/dbi/exception?nlines=
1000

public class
ExceptionServlet
extends

HttpServlet

{


public void
doGet(
HttpServletRequest

request,





HttpServletResponse

response)




throws

ServletException
,
IOException

{


response.setContentType(
"text/html"
);


PrintWriter

out = response.getWriter();


int

nLines =
Integer
.parseInt(request.getParameter(
"nlines"
));




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



for

(
int

i = 0; i < nLines; ++i) {



out.println(
"<p> bla bla bla "

+ i +
"</p>"
); }


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


out.println(
" "

+ 1/0 +
" "
); }}

This line causes an
exception

5

Uploading Files with
Servlets

Read more about the
FileUpload API

6

Handling Uploads with Package
Commons FileUpload


Commons FileUpload

is a package of Apache for
handling uploaded files in the Servlet side


Files are sent in the body of post requests


Using this package, uploaded files are
temporarily written into the memory or the disk
(depending on the file size)


You can set the size threshold beyond which files
are written to disk

This is not a configuration parameter in
web.xml

but a part of the API as we’ll
see in the next slides

7

Handling Uploads with Package
Commons FileUpload


Servlets read the file from the disk or memory


In Tomcat, the default temporary directory is
$CATALINA_BASE/temp/


However, you can specify a temporary directory
of your own (e.g.,
/tmp
)


What if a very big file is uploaded?

-
You can define the maximal size of uploaded files

-
Exception is thrown for larger files

8

Example 1

<
html
>


<
head
>


<
title
>
Upload Files and Parameters
</
title
>


</
head
>


<
body
>


<
form

action=
"upload
1
"

method=
"post"



enctype=
"multipart/form
-
data"
>






<
h
2
>
File:
<
input

type=
"file"

name=
"file
1
"
/></
h
2
>

<
h
2
><
input

type=
"submit"

value=
"send"

/></
h
2
>




</
form
>


</
body
>

</
html
>

upload
1
.html

Sends the client the
uploaded file

This is the right encoding type for
files uploading

9

import

org.apache.commons.fileupload.disk.*;

import

org.apache.commons.fileupload.servlet.*;

import

org.apache.commons.fileupload.*;

public

class

Upload
1
extends

HttpServlet {


public

void

doPost(HttpServletRequest request,


HttpServletResponse response)


throws

ServletException,
IOException

{



DiskFileItemFactory factory =
new

DiskFileItemFactory();


//factory.setRepository(
new

File("/tmp"));


factory.setSizeThreshold(
1000
);




ServletFileUpload upload =
new

ServletFileUpload(factory);


upload.setSizeMax(
60000
);



Upload
1
.java

Sets the repository
directory

Sets the memory vs.
disk threshold (bytes)

Sets the maximum file size (bytes).
Bigger files generate exceptions

10

try

{


List

items = upload.parseRequest(request);


Iterator it = items.iterator();


FileItem item = (FileItem) it.next();


response.setContentType(item.getContentType());


response.setContentLength((
int
)item.getSize());


InputStream

is = item.getInputStream();


OutputStream

os = response.getOutputStream();


byte
[] buffer =
new

byte
[
4096
];

int

read =
-
1
;


while
((read=is.read(buffer))>=
0
) os.write(buffer,
0
,read);


}


catch

(FileUploadException exp) {


response.setContentType(
"text/html"
);


PrintWriter

out = response.getWriter();


out.println(
"<html><body><b>Error</b>: <i>"

+


exp.getMessage() +
"</i></body></html>"
);


}}}

Upload
1
.java

In our example, we
expect a single
parameter

We use an
Output
stream
and
not the
out

PrintWriter

(why?)

Makes life
much easier

11

Example
2

<
html
>


<
head
>


<
title
>
Upload Files and Parameters
</
title
>


</
head
>


<
body
>


<
form

action=
"upload
2
"

method=
"post"



enctype=
"multipart/form
-
data"
>



<
h
2
>
Parameter x:
<
input

type=
"text"

name=
"x"

/></
h
2
>


<
h
2
>
File:
<
input

type=
"file"

name=
"file
1
"

/></
h
2
>


<
h
2
>
Parameter y:
<
input

type=
"text"

name=
"y"

/></
h
2
>


<
h
2
><
input

type=
"submit"

value=
"send"

/></
h
2
>


</
form
>


</
body
>

</
html
>

upload
2
.html

Mixed parameter types

12


List

items = upload.parseRequest(request);


Iterator it = items.iterator();


out.println(
"<ol>"
);


while

(it.hasNext()) {


FileItem item = (FileItem) it.next();


if

(item.isFormField())


out.println(
"<li><b>Field</b>: "

+ item.getFieldName()


+
" = "

+ item.getString() +
"</li>"
);


else



out.println(
"<li><b>File</b>"



+
": parameter name: "

+ item.getFieldName()


+
", file name: "

+ item.getName()


+
", file size: "

+ item.getSize()


+
" bytes, file type: "
+ item.getContentType()


+
"</li>"
);


}


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

Upload
2
.java

This time we use a loop
since there are several
parameters

13

Example
3


The latter example reflected a common design problem:
combining complex HTML code and Java code in a
Servlet or a JSP

-
Java code for processing parameters and uploaded files

-
HTML code for generating the (dynamic) response


An accepted solution is to process the parameters in a
Servlet
, and forward the request to a JSP for generating
the response

-
Attributes can be sent to the JSP via the request object.


The next example also uses
JSTL

14

JSTL


JSTL stands for JSP Standard Tag Library


This is a regular tag library that can be imported
to your page, like the ones we created in the past


This library includes some standard actions that
are common in JSP, like iteration and conditions
over EL expressions, parsing/manipulation of
XML and database access


More details can be found in
Sun's J
2
EE Tut
.

15

Example
3

<
html
>


<
head
>


<
title
>
Upload Files and Parameters
</
title
>


</
head
>


<
body
>


<
form

action=
"upload
3
"

method=
"post"



enctype=
"multipart/form
-
data"
>



<
h
2
>
Parameter x:
<
input

type=
"text"

name=
"x"

/></
h
2
>


<
h
2
>
File:
<
input

type=
"file"

name=
"file
1
"

/></
h
2
>


<
h
2
>
Parameter y:
<
input

type=
"text"

name=
"y"

/></
h
2
>


<
h
2
><
input

type=
"submit"

value=
"send"

/></
h
2
>


</
form
>


</
body
>

</
html
>

upload
3
.html

16

List

formParams =
new

LinkedList();

List

files =
new

LinkedList();


List

items = upload.parseRequest(request);

Iterator it = items.iterator();



while

(it.hasNext()) {


FileItem item = (FileItem) it.next();


if

(item.isFormField())formParams.add(item);


else

files.add(item);


}


request.setAttribute(
"formParams"
,formParams);

request.setAttribute(
"files"
,files);


this
.getServletContext().getRequestDispatcher


(
"/WEB
-
INF/jsp/upload
3
.jsp"
).forward(request,response);

Upload
3
.java

We’ll store
parameter
s and
fileitem
s
in those lists

Attach the lists to the request

17

<%@

taglib uri=
"
http://java.sun.com/jsp/jstl/core
"

prefix=
"c"

%>

<%@

page isELIgnored=
"false"

%>

<
html
><
head
><
title
>
Submitted Parameters
</
title
></
head
>


<
body
><
h
1
>
Submitted Parameters:
</
h
1
><
ol
>



<c:forEach

var=
"item"

items=
"${formParams}"
>


<
li
><
b
>
Parameter
</
b
>
:


name:
<
i
>
${item.fieldName}
</
i
>
,


value:
<
i
>
${item.string}
</
i
></
li
>


</c:forEach>



<c:forEach

var=
"item"

items=
"${files}"
>


<
li
><
b
>
File
</
b
>
:


name:
<
i
>
${item.name}
</
i
>
,


length:
<
i
>
${item.size}
</
i
>
,


size:
<
i
>
type:${item.contentType}
</
i
></
li
>


</c:forEach>


</
ol
></
body
></
html
>

/WEB
-
INF/jsp/upload
3
.jsp

18

A Question


What is the advantage of redirecting to JSP
pages that are under WEB
-
INF?

-
Pages under the WEB
-
INF are not accessible

-
You can make sure no one invokes the JSP directly

-
You can hide the implementation

19

Programmatic Security
with Servlets

20

Programmatic
-
Security Methods


The Servlet API contains several accessories for
handling programmatic security:

-
getRemoteUser()

-
isUserInRole(
String

role
)

-
getAuthType()


These are all methods of
HttpServletRequest


To enable user authentication (even for public URLs),
provide a link to some protected page

Returns the
authenticated

user or
null if none exists

21

An Example: Security Constraints
in web.xml


<security
-
constraint>


<web
-
resource
-
collection>


<web
-
resource
-
name>Firm People</web
-
resource
-
name>


<url
-
pattern>
/login.html
</url
-
pattern>


</web
-
resource
-
collection>


<auth
-
constraint>


<role
-
name>
employees
</role
-
name>


<role
-
name>
managers
</role
-
name>


</auth
-
constraint>


</security
-
constraint>

web.xml

Roles, some users and their roles are defined in
/conf/tomcat
-
users.xml

Some secured
resources

Roles that can view those
resources

22


<login
-
config>


<auth
-
method>FORM</auth
-
method>


<form
-
login
-
config>



<form
-
login
-
page>
/login
</form
-
login
-
page>



<form
-
error
-
page>
/login?
fail=fail
</form
-
error
-
page>


</form
-
login
-
config>


</login
-
config>


<security
-
role>


<role
-
name>
managers
</role
-
name>


</security
-
role>


<security
-
role>


<role
-
name>
employees
</role
-
name>


</security
-
role>

web.xml

An Example: Security Constraints
in web.xml

Roles used in this
application

(not required)

23

public

class

FirmServlet
extends

HttpServlet {


public

void

doGet(HttpServletRequest req, HttpServletResponse
res)
throws

ServletException,
IOException

{


res.setContentType(
"text/html"
);


PrintWriter

out = res.getWriter();


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


out.println(
"<h
1
>Hello.</h
1
>"
);



String

username = req.getRemoteUser();



if
(username==
null
) {


out.println(
"<p><img src=
\
"images/visitor.gif
\
"/></p>"
);


out.println(
"<h
3
><a href=
\
"login.html
\
">Login</a></h
3
>"
);


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


return
; }

FirmServlet

Returns the
authenticated

user or
null if none exists

24






if
(req.isUserInRole(
"employees"
)) {


out.println(
"<p><img src=
\
"images/employee.gif
\
"/></p>"
);


out.print(
"<h
2
>Welcome Employee "

+ username +
"!</h
2
>"
);


}


if
(req.isUserInRole(
"managers"
)) {


out.println(
"<p><img src=
\
"images/manager.gif
\
"/></p>"
);


out.print(
"<h
2
>Executive average salary:
42764
NIS!</h
2
>"
);


}


out.print(
"<h
3
><a href=
\
"endsession
\
">Log Out</a></h
3
>"
);


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


}

}

FirmServlet

This is ugly. This is why attributes in HTML can be single
-

or
double
-
quoted. Same goes for strings in many scripting
languages (watch out for escaping differences, though!)

25

public

class

LoginServlet
extends

HttpServlet {


public

void

doGet(HttpServletRequest req, HttpServletResponse res)
throws

ServletException,
IOException

{


res.setContentType("
text/html
");


PrintWriter

out = res.getWriter();


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


if
(req.getParameter(
"fail"
)!=
null
)


out.print(
"<h
2
>Login Failed. Try Again.</h
2
>"
);





out.println(
"<form action=
\
"j_security_check
\
" method=
\
"post
\
">"

+


"<p>Login: <input type=
\
"text
\
" name=
\
"j_username
\
"/></p>"

+


"<p>Password: <input type=
\
"password
\
" name=
\
"j_password
\
"/></p>"

+


"<p><input type=
\
"submit
\
" value=
\
"Log In
\
"/></p>"

+


"</form></body></html>"
);


}

LoginServlet.java

Notice that though this code contains no
getSession()
calls, the server
tries to put
session
-
cookie
as a part of the
FORM authorization

26


public void doPost(HttpServletRequest req, HttpServletResponse res)


throws ServletException, IOException {


this.doGet(req,res);


}


}

LoginServlet.java



<servlet>



<servlet
-
name>
Login
</servlet
-
name>



<servlet
-
class>
LoginServlet
</servlet
-
class>



</servlet>





<servlet
-
mapping>




<servlet
-
name>
Login
</servlet
-
name>




<url
-
pattern>
/login
</url
-
pattern>



</servlet
-
mapping>

web.xml

27

public

class

EndSession
extends

HttpServlet {


public

void

doGet(HttpServletRequest req, HttpServletResponse res)


throws

ServletException,
IOException

{


HttpSession session = req.getSession(
false
);


if
(session!=
null
) {


session.invalidate();


}


res.sendRedirect(
"firm"
);

}

EndSession.java



<servlet>



<servlet
-
name>EndSession</servlet
-
name>



<servlet
-
class>
EndSession
</servlet
-
class>



</servlet>


<servlet
-
mapping>




<servlet
-
name>EndSession</servlet
-
name>




<url
-
pattern>
/endsession
</url
-
pattern>



</servlet
-
mapping>

web.xml

Tomcat’s
session
implementation
saves the user
details in the
session but not as
attributes.

Recovering this data is
done by calling the
mentioned request
methods, but of
course invalidating
the session leads to
logout

28

<html>


<head>


<title>
Logged On
</title>


</head>



<body>


<h
1
>
You are logged on!
</h
1
>



<p><a href="
firm
">
Back to the firm page.
</a></p>


</body>

</html>

login.html

29

Managing User
Authentication with
Tomcat

30

A Reminder

create

table

users

(


username

varchar
(
30
)
not

null

primary

key
,


pass

varchar
(
30
)
not null

);


create

table

users_roles

(


username

varchar
(
30
)
not null
,


role

varchar
(
30
)
not null
,


primary

key

(
username
,
role
),


foreign

key

(
username
)
references

users(
username
)

);

31

In tomcat
-
base/conf/server.xml

<Realm


className=
"org.apache.catalina.realm.JDBCRealm"


driverName=
"org.postgresql.Driver"


connectionURL=
"jdbc:postgresql://dbserver/public?user=
snoopy
"


userTable=
"users"


userNameCol=
"username"


userCredCol=
"pass"


userRoleTable=
"users_roles"


roleNameCol=
"role"
/>

32

User Tables


What if we do not have one table that stores
usernames and passwords?


What if we only have one role for the all users?


What if we wanted the above information to be
stored in several tables (e.g., users and
administrators)?


The idea is to use
views

rather than real tables

33

Creating Views

create

view

up
as



(
select

username
u
, pass
p

from

users


union



select

u
,
p

from

admin
);


create

view

ur

as




(
select

username

u
,
'myRole'

r

from

users



union



select

u,
'admin'

r

from

admin);


Unifies the user/password data
from
2
tables

Default role for “simple” users

Default role for “admin” users

34

Fixing server.xml

<Realm


className=
"org.apache.catalina.realm.JDBCRealm"


driverName=
"org.postgresql.Driver"


connectionURL=
"jdbc:postgresql://dbserver/public?user=
snoopy
"


userTable=
"up"


userNameCol=
"u"


userCredCol=
"p"


userRoleTable=
"ur"


roleNameCol=
"r"
/>

35

Filters

36

Filters 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




37

Filter 1
Request
Response
Filter 2
Filter 3
Servlet/JSP/HTML
Client
Container
38

public

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”

39



<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 Filter

web.xml

You can also add an
<init
-
param>
element like we
saw in
servlets

and
JSPs
.

40

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/image
1
.gif

in
the server’s logs

41

Notes 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

42

public 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("
<h
2
>Image filename =
" + URI + "
</h
2
>
\
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>

43

else

{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>
/images
2
/*
</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
.txt

Open
/images
2
/image
1
.gif

Open
/images
2
/joke
1
.txt

A url
-
pattern of
/images
2
/*.gif

doesn’t work.

That’s why we check the suffix in
the Java code