Sei sulla pagina 1di 30

***STRUTS***

Struts: Struts frame work in used to develop web based application.


Struts frame works simplify the development of web based application.
1. By using struts frame work we can develop only web based
applications. We cant use struts to develop standalone
applications.
2. We can use any of the following frame work to develop web
based applications.
a. Struts
b. Springs
c. JSF
d. Web work
e. Open symphony
3. Struts frame work is a piece of software which contains the
solutions to commonly repeatedly occurred problems across
multiple projects.
The following are the problems resolves by most of the frame work.
1. Frame work resolves the problems of identifying architectures.
Every frame work is delivered with architecture. Struts and
having frame work uses MVC2 architecture.
2. If we use servlets and JSPs we have to develop our own
controllers. If we use the frame work like struts and spring
internally they come with the controllers ActionServlet in struts,
DispatcherServlet in spring.
3. When we use any frame work we no need to use Request
dispatcher code as well as we need to hard code the path of the
resource. By using this frame work we can configure then in the
configuration files.
4. If we are JDBC, servlet and JSFs to develop the form based
applications we have to write huge amount of code and take case
of server side validations and displaying errors in the save form.

5. By using servlets and JSFs we have to provide huge amount of


code to develop I18N apps (the program which develop the o/p
based on client language).
6. The frame work like struts and spring are delivered with set of tag
libraries. If we use servlets and JSPs we have to develop our own
tag libraries.
7. When we use the frame work like struts and spring we can use
pdf/velocity/jsf as the view components. Most of the experience
people develop a view frame work.
8. Every company uses their own frame work to develop the
projects. All these frame work internally uses other frame work.
Apache company has released struts frame work to develop web
based applications based on model two Architecture. Apache guys are
released struts frame work in two versions. They are:
a. Struts 1.x
b. Struts 2.x
We can down load the struts frame work in multiple flavored. That is
we can down load only the struts jar files or we can down load only
documentation or Example applications. When we down load the struts
software majorly we set the following three files.
1. Set of struts released jar files (struts-core.jar).
2. The documentation is available in docs folder.
3. All the sample examples are available in applications folder.
Developing our First Struts based application: We can create a
struts based application by coping the jar files manually and we can
configure them web.xml files. Instead of doing the manual work we
can develop our FirstServlet based applications form sturts-blank.war.
Create a folder whose folder name is our project name (Sapps). Copy
struts-blank.war into the above created folder and extract the contents
of it. When we down load the struts will work we got the following four
components.
1. A servlet whos name is org.apache.struts.action.ActionServlet.

2. Set of predefined classes, same of them are Action,


ActionMapping, ActionForward, ActionErrors, ActionMessage,
ActionForm, .etc.
3. Set of struts tag libraries (HTML, Beam, Logic, and Tiles).
4. Get struts-config.xml and validation.xml
The following is the configuration available in web.xml.
<web-app>
<servlet>
<servlet-name>action</servlet-name>
<servletclass>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.cml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
The following steps will be carry out when we deploy struts based
project.
1. Server reads the content from web.xml file and store the
information in JVMs memory.
2. As there is load-on-startup tag for ActionServlet server has create
ActionServlet object.

action(*.do
)

ActionServl
Server
After the server has created servlet object server executed init()
method. As part of the init() method it with find the configuration file
name details and by using the parser program. It read the contents
from configuration file and stores it in JVMs memory.
action(*.do)
init()
{
}
struts-config.xml

ActionServlet
Server

The following is the sample code architecture in predefined class


ActionServlet.
public class ActionServlet extends HttpServlet{
public void init(){
ServletConfig config = getServletConfig();
String configFileName = config.getInitParameter(config);
//code to read the contents from configuration file and store in JVMs
memory.
}
public void sevice(HttpServletRequest request, HttpServletResponse
response){
----------------------------

}
public void destroy(){
//code to remove the contents from JVMs memory.
}
}
When ever any client set the request to the server whose URL pattern
and with .do ActionServlet service() method throws an Exception
saying Invalid path Exception.
A frame work defined a procedure to carry out a task/work.
We get the path of the resource from the URL.
/one.do

/one

/some/thing.do

/some/thing

/
any/thing/work.d
URL

/any/thing/work
path of the Resources

In struts if we would like to carry out any work we need to develop


action classes. With out ActionClasses we cant carry out any work.
**What is an ActionClass?
A class which is sub class of org.apache.structs.action.Action is
called as Action class.
org.apache.structs.action.Action
ActionForward execute(ActionMapping,
ActionForm, HttpServletRequest,

ActionOne

ActionTwo

The following is an example of Action class.


import org.apache.struts.action.*;
import javax.servlet.http.*;
public class ActionOne extends Action{
public ActionOne()[
System.out.println(ActionOne object is created);
}
Public ActionForward execute(ActionMapping mapping, ActionForm
form, HttpServletRequest request, HttpServletRestponse response){
System.out.println(we are in ActionOne execute);
ActionForward af = null;
return af;
}
}
To compile the above program we have to set the class path to strutscore.jar;, servlet-API.jar;.
We must configure every Action class into struts Configuration file.
Ex:
<struts-config>
<action-mappings>
<action type = ActionOne path = /a0/>
</action-mapping>
</struts-config>

// struts-config.xml

When ever we deploy a project, server reads the content from web.xml
server represents every tag in the form of object. When we deploy
struts project, servers has created the following two objects.
name =
name =
actionclass
=
ActionServl

action
url pattern =
*.do

et

Servlet tag object

ServletMapping

tag object
When ever server has encountered an action tag in
configuration file, it is mapped with an action mapping object.

struts

type =
<action type = ActionOne path = /a0/> ActionOn
e path =
/a0
ActionMapping object
The following steps will be carried out when a client has send the
request to server where URL pattern and with .do.
1. Server creates request and response objects and hand over then
to ActionServlet service() method.
2. ActionServlet service() method remove .do. Now we get the path
of the resource.
3. Service() metod is these any action mapping object is availability
whose path matches to /a0.
4. If there is no actionmapping object available server throws an
Exception invalid path Exception.
5. If the actionmapping object is available server gets the name of
the action class. If require action servlet create action class object
and call the execute() method.
6. Execute() method returns on ActionForward object with null value.
7. When ever ActinServlet service() has encoder a null value stops
the execute of request. It will display a blank screen to the user.

Service(
){

/a0
2

Request 1

.do

/a0.do
Client

req

ActionServlet
3

4
res

execute
(){
af
}
ActionOne

JEE Server

public class ActionTwo extends Action{


public ActionForward execute(ActionMapping mapping, ActionForm
form, HttpServletRequest request, HttpServletResponse response){
System.out.println(mapping.getPath());
System.out.println(mapping.getType());
System.out.println(mapping.getParameter());
System.out.println(mapping.getName());
ActionForward af = null;
return af;

}
}
When ever we change struts configuration file we must restart the
server. This is because, ActionServlet service() method reads the
contents from struts configuration file at the time of deployment only.
Parameters: We use Parameter attribute in the configuration file to
supply on extra information to that particular action.
Type: use to specify ActionClass name.
Name: Name attribute is used as a logical name to identify a
particular action this name attribute is used mainly in developing form
based applications.
ActionForward:
As part of a struts configuration file, we have added an extra
tag <forward>
<action-mapping>
<action type = ActionThree path = /ath>
<forward name = one path = one.jsp/>
<forward name = two path = two.jsp/>
</action>
</action-mapping> //struts-config.xml
When we deploy the project for the above configuration server creates
ActionMapping objects based <action>tag, and ActionForward objects
based on <forward> tag.
name = one
path = /one.jsp

type =
ActionType
path = /ath

ActionForwards
name = two

type =
ActionOne
path = /a0

path = /two.jsp

Finding ActionForward object using ActionMapping:


To check when ever an ActionMapping object contain a
specific ActionForward object, we use mapping find forward() method.
Syntax: ActionForward mapping find Forward(String forwardName);
When we call find Forward() method, if ActionForward object is
available, it returns that ActionForward object. If it is not available that
method returns null value.
Ex: ActionForward af1 = mapping.findForward(one);
ActionForward af2 = mapping.findForward(two);
ActionForward af3 = mapping.findForward(three);
For the above code is returns ActionForward object for af1, af2 and af3
it returns a null value.
*Develop an action class which forwards the result to one.jsp?
public class ActionThree extends Action{
public ActionForward execute(ActionMapping mapping, ActionForm
form, HttpServletRequest request, HttpServletResponse response){
ActionForward af = mapping.findForward(one);
return af;
}
}

The following steps are carried and when the client sends the request
to server.
1. ActionServlet service() method Action class object if requirement.

2. ActionServlet service() method call execute method [service() will


supply ActionMapping, ActionMapping req and res objects].
3. Server execute execute() method and return ActionForward object
to service() method.
4. nce if ActionForward method return service() method if checks
the path of the resource. It uses request jsp when ever code to
dispatch the request to appropriate jsp.
(*.do)
req
service()
{

Request

Client
/ath.do

res

af
}
ActionServlet

On
e.j
sp

execute(
){
af(actio
nforwar
ActionThree
d)}
JEE Server

Develop a struts based application to retrieve all the records from emp
table and display to the client. We should not create any java code in
jsps.
1. Develop a supportive class to store employee details.
public class EMP{
String eno;
String name;
String salary;

//provide setters and getter methods.


}

2. Develop an ActionClass to interact with data base server and


retrieve the records and store it in request code?
public class Search Emp Action extends Action{
public ActionForward execute( .. ){
DriverManager.registerDriver(new
oracle.jdbc.driver.OracleDriver());
Connection con = DriverManager.getConnection
(jdbc:oracle:thin:@localhost:1521:xe,syst
em,malli);
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(select * from emp);
ArrayList empList = new ArrayList();
while(rs.next()){
Emp e = new Emp();
e.setEno(rs.getString(eno));
e.setName(rs.getString(name));
e.setSalary(rs.getString(salary));
empList.add(e);
}
request.setAttribute(empList,empList);
ActionForward af = mapping.findForward(done);
return af;
}
}

3. The following is the jsp which display output to the client by using
core tag library.
<%@ page isELIgnored = false%>
<%@ Laglib uri = http://java:sun.com/jsp/jstl/core prefix =
c%>
<c:forEach var = emp items = ${empList}>
${emp.eno}
${emp.name}
${emp.salary}<br>
</c:forEach>

// search.jsp

*JSTL guys has given SQL tag library. This tag library contains set of
tags which re used to interact with Database server. Its not
recommended to use SQL tag library the jsps this is because if we use
SQL tag library we are c lab in Business logic and presentation logic.
The following data source and update queries are used to write jdbc
code and the jsps.
<%@ page isELIgnored = false%>
<%@ taglib uri = http://java.sun.com/jsp/jstl/sql prefix = sql%>
<sql:setDataSource
var = ds
driver = oracle.jdbc.driver.OracleDriver
url = jdbc:oracle:thin:@localhost:1521:xe
user = system
password = malli/>
<sql:update dataSource = ${ds}>
insert into emp values(6,esix,454)
</sql:update>

*The following query tag is used to display all the records from emp
table.
<sql:query var = rs dataSource = ${ds}>
select * from emp
</sql:query/>
<c:forEach var = row items = ${rs.rows}>
${row.eno}
${row.name}
${row.salary}
</c:forEach>
I18N application:
1. The application which display the output the client based on they
regional language.
2. We can use property files to develop I18N applications as well as
web based applications.
3. By using property files we can remove hard coding also.
4. Every property file must end with an extension called as
properties. In a project we maintain multiple property files.
5. In a property file we supply the data in the form of key and value.
Ex:

Key1 =
value1
Key2 =

// test.properties

The following example demonstrates how to read contents from


property file.
drv =
oracle.jdbc.driver.OracleDriver
url =
jdbc:oracle:thin:@localhost:1521:
xe

// db.properties
public class DBConnect{
public static void main(String args[]) throws Exception{
Properties prop = new Properties();
FileInputStream fis = new FileInputStream(db properties);
prop.load(fis);
System.out.println(prop.getProperty(drv));
System.out.println(prop.getProperty(url));
System.out.println(prop.getProperty(uname));
System.out.println(prop.getProperty(pwd));
}
}
The following java program write the contains to a property file.
public class MyApp{
public static void main(String args[])throws Exception{
Properties prop = new Properties();
prop.setProperty(one,one value);
prop.setProperty(two,two value);
FileOutputStream fos = new FileOutputStream(abc.properties);
prop.store(fos,null);
}
}
We can write the comments in a property file we can use a symbol #.
We can read the
getResourceAsStream.

contents

from

property

file

by

using

public class MyApp{


public static void main(String args[]){
Properties prop = new Properties();
prop.load(MyApp.class.getResourceAsStream(abc.properties));
System.out.println(prop.getProperties(one));
}
}
An organization ISO has assigned a two letter code for all the countries
and languages.
Generally the country letters will be written in capital letters.
Ex: IN, US .. Etc.
For the language also two letter codes are assigned. Generally the
language courses are written in small letters.
To develop I18N applications we required regional and language
information of that computer.
To find the current computer regional and language information we can
use java.util.locate object.
To find the locate information of our computer we have to get the
locate object from the locate object. We can get country code and
language code.
public class MyApp{
public static void main(String args[]){
Locate l = locate.getDefault();
System.out.println(l.getCountry());
System.out.println(l.getLanguage());
}
}

To develop I18N application we need to create multiple property files.


These property files are called as bundles.
We create this property files based on number of languages that has to
be supported by the customer.

Every property file must end with an extension is called as .properties.


In a project use maintain multiple property files. In a property file use
supply the data in the form of key and value.
Ex: key1 = value1

key2 = value2 // test.properties

The following example demonstrates how to read the context from


property file.
drv = oracle.jdbc.driver.OracleDriver
url = jdbc:oracle:thin:@localhost:1521:xe
uname = system
pwd = malli

//db.properties

public class DBConnect{


public static void main(String[] args){
Properties prop = new Properties();
FileInputStream fis = new FileInputStream(dbproperties);
prop.load(fis);
System.out.println(prop.getProperty(drv));
System.out.println(prop.getPropety(url));
System.out.println(prop.getPropety(uname));
System.out.println(prop.getPropety(pwd));
}
}

The following java program writes the properties into property file.
public class MyApp{
public static void main(String args[]){
Property p = new Property();
p.setProperty(one,onevalue);
p.setProperty(two,twovalue);
FileOutputStream fos = new FileOutputStream(abc.properties);
p.store(fos,null);
}
}
We can write the comments in a property file we can simply use #.
We can read the context
getResourceAsStream().

from

property

file

by

using

Ex: Properties p = new Properties();


p.load(MyApp.class.getResourceAsStream(abc.properties));

//it reads the properties currently working available properties class


path (same folder).
System.out.println(p.getProperty(one));
An organization ISO has assigned a two letter code for all countries
and languages.
Generally the country letters will written in capital letters.
Ex: IN,US, . . . .
For the language also two letters code are assigned. Generally the
language codes are written in small letters.
To develop I18N applications we required regional and language
information of that computer. To find the current computer regional
and language information we can use java.util.Locate Object.

To find the locate information of our computer use have to get the
locate object from the locate object. We get country code and
language code.
public class MyApp{
public static void main(String args){
Locate l = Locate.getDefault();
System.out.println(l.getCountry());
System.out.println(l.getLanguage());
}
}
To develop I18N applications we need to create multiple property files.
These property files are called as Bundle.
We create these property files based on number of languages that has
to be supported by the customer.
Procedure to use I18N applications in standalone application:
1. We need to create property files. The numbers of property files
are based on the languages are supported by our projects. Make
sure that Bundle name must be same.
2. In our project we would like to support two languages English and
French.
msg = welcome to java

// MyProject_en_US.properties

msg = welcome to java in French

// MyProject_fr_CA.Properties

To read the contents from property files based on regional language.


We take the help of java.util.ResourceBundle class. The following
example is demonstrate how to read the contents from
ResourceBoundle.
public class Welcome{
public static void main(String args[]){
Locate l = Locate.getDefault();

ResourceBoundle rb = ResourceBoundle.getBoundle(MyProject,l);

String m = rb.getString(msg);
System.out.println(m);
}
}
When we are retrieving a key from the ResourceBoundle which is not
available it thrown an Exception java.util.MissingResourceException.
When we test our application for the property files which doesnt
support
other
languages
application
throws
an
Exception
java.util.MissingResourceException.
The project supports two languages and when you run the same
project in a computer which doesnt support above two languages and
we want to display the default language. We achieve this from the
property files we have to remove country code and language code.
Developing I18N applications for web-based:
1. We have developed the following JSP to display the o/p based on
client regional language. But it always displayed o/p in English
language. This is because we have hard coded the values in JSP.
2. From the following JSP we have to remove the high located hard
code values.
<html>
<head>
<tittle>welcome to my project</tittle>
</head>
<body>
<h1><center>welcome to my project</center>m/h1>
<p>Firstline</p>
<p>Secondline</p>

<p>Thirdline</p>
</body>
</html>
When the client sends the request to Server, Server creates request
and Response Object. Server fined the client Regional language and
creates a Locate Object. The Locate Object is associated with request
object.

re
q

en
US

re
s

Accept-Language (en-US)

Client1

Accept-Language (fr-CA)
re
q

fr
CA

re
s

Client2

Server
The following JSP demonstrate how do we find the Locate Object of
client and send it back.
<%@ page import = java.util.*%>
<%
Locate l = requet.getLocate();
out.println(l);
%> //two.jsp
1. Create the property files to support multiple languages.
Ex:

msg.tittle = welcome to my propect in English


msg.header = welcome to my project in English
msg.l1 = Firstline in English
msg.l2 = Secondline in English
msg.l3 = Thirdline in English
2.

//Message_en_US.Properties

Copy all the property files into classs folder. This is because the
entire web-based application class path is set to classs folder.

3. Develop a JSP to find the client regional language and based on


that read the content of property file and display.
Ex:
<%
Locate l = Locate.getDefault();
ResourceBundle rb ResourceBundle.getBundle(message,l)
%>
<% = rb.getString(msg.tittle)%>
<% = rb.getString(msg.header)%>
<% = rb.getString(msg.l1)%>
<% = rb.getString(msg.l2)%>

//one.JSP

The disadvantage of above the JSP is we are providing lot of java code
its not recommended to write java code in JSPs. to remove that java
code we use I18N tag library.
Req: Develop one.JSP by using struts I18N application.
Procedure to use I18N application in struts.
1. Create the property files and copy them in to classes folder.
2. Configure property files into struts configuration file by using
<MessageResources parameter = />
//tag
Ex:

<struts-config>
------------------<Message-resources parameter = welcome/>
</struts-config>
3.

// struts-config.xml

Import the tag lib in JSP and use message tag of Bean tag
library (strutsTaglib = Bean, HTML, Nested, Logic)
<%@ taglib uri = http://struts.apache.org/tags-bean prefix =
bean%>
<bean:Message key = msg.tittle/><br>
<bean:Message key = msg.header/><br>
<bean:Message key = msg.l1/><br>
<bean:Message key = msg.l2/><br>
<bean:Message key = msg.l3/><br>

// One.jsp

When we use the message <bean:message> tag for a key which is not
available it will throw an Exception saying missing message key key
name for Bundle.
Generally when multiple people are working in same project and they
want to share the property files and when ever we are using a key
which is not available my application should not display any Exception
to achieve. This we have to configure null = false in the struts-configxml.
<MessageResources parameter = welcome null = false/>
By default struts uses null = false the meaning of null = true is if
the key is not available it returns null to the struts. When it return a
null value to strut it throws an Exception.
When we specify null = false, even if the key is not available it will
not thrown an Exception it throws the following Error.
???en-US.msg.l5??? // country and language of Browsers.

Req Assign:
eno name salary

//15 Records MVC2

At first Request display 1 to 5.


1
2
3
4
5
When ever we pre next display.
6
7
8
9
10
Using multiple Bundles in Struts:
1. We are trying to use multiple Bundles in struts base projects.
Ex:
One = One in English

four = One in English

Two = Two in English

five = Two in English

Three = Three in English

six = Three in English

resone_en_US.Properties
One = One in French

resone_en_US.Properties
four = One in French

Two = Two in French

five = Two in French

Three = Three in French

six = Three in French

resone_fr_CA.Properties

resone_fr_CA.Properties

Basename = resone

Basename = restwo.

2. We are configure above two Bundles into Struts configuration file


as show below.
<Message_resources parameter = resone/>
<Message_resources parameter = restwo/>
3. We have developed a JSP and trying to use key from both two
Boundles.
<%@ tag lib uri = http://struts.apache.org/tags-bean prefix =
bean%>
<bean:message key = one/>
<bean:message key = four/>
4. When we run the above JSP program it will thrown an Error
message missing key for resource one. We have observed that for
the above configuration it is able to read the contents only from
resource BundleTwo. When we read the contents from
Bundleone it is throwing an Exception. Because the Bundle2 over
ride the Bundleone [int a =10, int b = 20].
5. To resolve the above problem we have make the changes in
struts-configuration file by adding an attribute key in
<message-resources>.
Ex:
<message-resources parameter = resone key = bo/>
<message-resources parameter = restwo key = bt/>
6. While we are using the <message> tag in the JSP we have to
specify from which Bundle to have search by using an attribute
called Bundle.
<%@ tag lib uri = prefix = b>
<b:message key = one bundle = bo/>
<b:message key = two bundle = bt/>

When ever the project is deployed server creates the servlet context
object. Immediately server calls the init() method. In this method have
the code to read the data from strut-configuration file. When ever the
server found the tag it will create the objects to each tag. Now the
server fined <message_resources > tag. Now the server creates
the object to <message_resource>. Because this class is provide the
implementation to the <message_resources>.
Now server get the parameter value from the
<message-resource>. Here i.e parameter = resource. Now the server
checks into classes folder is there any bundle name like resone. If it is
available the server reads the property files and store it in pmr1
object.
Now server store that pmr1 object in ServletContext object. Here the
server checks whenever the <message-resource> tag contains any
key attribute. If it is not available it takes default key as
org.apache.struts.Action.Message. If it is available it takes key and
store in context object [see preview page].
When we configure resource bundles with out
key they try to store two bundles into application scope by using same
key org.apache.Struts.Action.Message. When ever server has
encountered <message-resource> tag server creating an object to a
class whose name is PropertyMessageResource.
<message-resources parameter = resone/>
<message-resources parameter = restwo/>
When the above configuration is Exception it will try to create two
pmr objects and trying to use the same default key.
en

fr

US

CA

MESSAGE
pmr2

pmr1
Application

resone
restwo
pmr1

pmr2

Sapp

en

fr

US

CA

Server
When we modify the property files we must restart the server.
org.apache.Struts.action.MESSAGE key available in a class called as
Gobles [MESSAGE-KEY]. The logic tag library contains set of tags which
are used to check the logic contains.
Ex: present, not present, grater than, less than and etc.
To check whether the application scope contains the following key.
org.apache.Struts.ActionMESSAGE.
<%@ tag lib uri = http://strus.apache.org/tags-logic prefix =
logic%>
<logic:Present name = org.apache.struts.action.MESSAGE Scope =
application>
Available
</logic:Present>
How to deal with Errors in Struts:
1. In struts 1.3 they are given three different classes to deal with
Errors/Messages: They are action.
1.1. ActionErrors
1.2. ActionMessage
1.3.

ActionMessages

2. If you want to deal with ActionErrors we have to create


ActionErrors object and add Error Message by using
ActionMessage object.
ActionErrors

ActionMessages

if Error

if normal message
ActionMessages

*Develop as action class which generates five Errors and displayed in


JSP.
1. Create the property file and add all Errors to property files.
error1 = Errorone
error2 = Errortwo
error3 = Errorthree
2. Develop an action class which generates an Error and added to
request scope.
public class TestErrorAction extends Action{
public ActionForward execute(.){
ActionErrors aes = new ActionErrors();
ActionMessage am1 = new ActionMessage(error1);
aes.add(e1,am1);
ActionMessage am2 = new ActionMessage(error2);
aes.add(e2,am2);
ActionMessage am3 = new ActionMessage(error3);
aes.add(e3,am3);
System.out.println(size:+aes.Size());
saveErrors(request,aes);
return mapping.FindForward(done);
}
}
3. Configure action class into struts configuration file.
<action type = TestErrorAction path = /te>
<forward name = done path = /pages/one.jsp/>
</action>

//Struts-Config.xml

4. Using <errors> tag display the Error.


<%@ tag lib = http://strut.apache.org/tags-html prefix =
html%>
<html:Errors/>

//One.jsp

Potrebbero piacerti anche