You should be able to delete
${catalina.home}/work/Catalina/localhost/appName/SESSION.ser where
appName is your application (or just delete the whole work directory).
In Struts 2, resource bundles can be associated with classes. The
framework will automatically discover and load class-orientated
resource bundles. You can also specify one or more global resource
bundles, which would be available to all classes in the application,
using either the standard properties file, or a custom listener.
Properties file
Global resource bundles can be specified in the struts.properties configuration file.
struts.properties
struts.custom.i18n.resources=global-messages
The framework searches the class heirarchy first, then, as a last resource, checks the global resources.
Multiple resource bundles can be specified by providing a comma-separated list.
Aside from the properties file, a Listener could also be used to load global resource bundles.
ActionGlobalMessagesListener.java
public class ActionGlobalMessagesListener implements ServletContextListener { privatestatic Logger log = Logger.getLogger(ActionGlobalMessagesListener .class); privatestaticfinalString DEFAULT_RESOURCE = "global-messages";
/** * Uses the LocalizedTextUtil to load messages from the global message bundle. * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.Servle tContextEvent) */ public void contextInitialized(ServletContextEvent arg0) { log.info("Loading global messages from " + DEFAULT_RESOURCE); LocalizedTextUtil.addDefaultResourceBundle(DEFAULT_RESOURCE); log.info("Global messages loaded."); }
/** * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent) */ public void contextDestroyed(ServletContextEvent arg0) {
1. HttpServletResponse 로 부터 OutStream 을 얻는다. 2. Header, ContentsType 등을 설정한다. 3. FileStream 을 통해 전송될 파일의 스트림을 얻는다. 4. Response 로 부터 얻은 outputStream 에 파일을 쏜다. 5. 열려진 모든 자원을 닫는다.
뭐 다른것들은 괜찮지만 2번 항목에서 환경에 따라 헤더 설정이 틀려진다. 단독 WAS 환경인지, WAS 앞에 Apache 나 IIS 가 있는지 등등..
Posted by gmurray71 on September 27, 2006 at 12:01 PM | Comments (9)
Preventing Cross Site Scripting Attacks
Cross site scripting (XSS) is basically using JavaScript to execute JavaScript from an unwanted domain in a page. Such scripts could expose any data in a page that is accessible by JavaScript including, cookies, form data, or content to a 3rd party. Here is how you can prevent your web pages from being exploited on both the client and the server. This is followed with tips on how to avoid vulnerable sites.
Escape parameters and User Input - The safest step you can take is to escape all parameters to a page where the parameters are displayed in the content.The same applies for any user input that may be displayed or re-displayed in a web page rendered by a server. The downside is that your users can not provide markup.
Remove eval(), javascript, and script from User Provided Markup - If you allow users to provide markup in any part of your application that is displayed in a page make sure to remove eval() and javascript: calls from element attributes including styles as they can be used to execute JavaScript. Also remove script blocks.
Filter User Input on the Server - You should always filter user input that is stored or processed on a server because URLs and GET/POST requests can be created manually.
Use Caution with Dynamic Script Injection - Be careful when dynamically injecting external scripts to retrieve JSON based data as you are potentially exposing everything accessible by JavaScript.
Avoid XSS Phishing Attacks - Be aware of sites that contain vulnerabilities and phishing style attacks containing external script references.
Escape Parameters and User Input
This is the classic XSS attack that can open your service or web application up to hackers. By design the site displays a user's id that is passed in as a URL parameter. The following script will take the id and display a welcome message.
<script type="text/javascript">
var start = window.location.href.indexOf("id");
var stop = window.location.href.length;
var id = "guest";
if (start < stop) {
id = decodeURIComponent(window.location.href.substring(start,stop));
}
document.write("Hi " + id);
</script>
A request to the URL index.html?id=greg (assuming the page containing the script is index.html) will result in:
Hi greg
What would happen if instead of "greg" I used the following URL:
Notice the URL above contains a link to script http://baddomain.com/badscript.js which contains malicious code from a different domain. This script will be evaluated when the page is loaded putting the page and all the data in it at risk.
To prevent from these types of attacks your client code should always escape "<" and ">" parameters that are displayed or evaluated by JavaScript code.
You can do this with a simple line of code as can be seen in the next example.
<script type="text/javascript">
var start = window.location.href.indexOf("id");
var stop = window.location.href.length;
var id = "guest";
if (start < stop) {
id = decodeURIComponent(window.location.href.substring(start,stop));
}
document.write("hi " + id);
</script>
Consider the following containing a form where a user enters a description that will be visible to other users.
Seems innocent enough right? Try including the following content in the text area.
<a onmouseover="eval('s=document.createElement(\'script\'); document.body.appendChild(s); s.src=\'badscript.js\'')">Mouse Over Me</a>
A mouseover of the link will cause a script in a badscript.js to be loaded. This script could also pass along cookies or any other information it wanted to as parameters of the "s.src" URL. Unlike the first example where the user would need to click on a bad link this type of attack requires a simple mouseover to load the badscript.js.
So the question now comes to mind: 'How do you protect your web page from being being exploited?'
The code description = description.replace(//g, ">"); filters the user input and prevents unwanted scripts from being executed.
Now that we have looked at how to prevent most attacks the next section focuses on cases where you want to allow users to provide markup that does not contain malicious code.
Remove eval(), javascript:, and script from User Provided Markup
There may be cases where you want to allow a user to add markup such as links or HTML content that is displayed for other users to see. Consider a blog that allows for HTML markup, user provided URLs, HTML comments, or any other markup. The solution would be to filter all markup before it is displayed in a page or before it is sent to a server or service. The following example shows how to allow for some HTML markup while preventing malicious code.
The example above removes all eval(), javascript and script references that may be entered in the description field. The replacement here is not a perfect as it may replace legitimate uses of the words javascript and script in the body of a document. You may consider refining the regular expressions to only look in tag attributes for example and to remove full scripts. There are other considerations you should keep in mind when filtering client code such as line breaks, charsets, case sensitivity which are commonly exploited in attacks. As some browsers will allow you to specify JavaScript calls from CSS styles you should also consider searching user provided CSS styles as well.
Filter User Input on the Server
Most of the problems related to cross site scripting are because of poorly designed clients. Servers can also unwillingly become participants in cross domain scripting attacks if they redisplay unfiltered user input. Consider the following example where a hacker manually makes a HTTP POST request to set the homepage URL with the following.
The URL would end up being stored as is on the server as is and expose any user that clicks on the URL to the JavaScript. The example above seems innocent enough but consider what would happen if in place of an alert('bad') the "javascript" contained malicious code. To prevent such attacks you should filter user input on the server. The following Java example shows how to use regular expression replacement to filter user input.
The code above removes eval() calls, javascript: calls, and script references the replacement here is not a perfect as it may replace legitimate uses of the words javascript and script in the body of a document. The code above may be applied using a servlet, servlet filter, or JSF component on all input parameters or on a per parameter basis depending on what how much markup you would like to allow users to provide. You may want refine the regular expressions that filter the content to handle more or consider a Java library built that specializes in removing malicious code.
Use Caution with Dynamic Script Injection
Dynamic script injection to retrieve JSON data (also known as JSONP) can be powerful and useful as it decouples your client from the server of origin. There is still a bit of debate over using JSONP as some consider it as a hack or security hole in JavaScript because when you dynamically include a reference to a 3rd party script you are giving that script full access to everything in your page. That script could go on to inject other scripts or do pretty much whatever it wanted.
If you choose to use JSONP make sure you trust the site for which you are interacting with. There is nothing stopping a JSONP provider from including unwanted script with JSONP data. One alternative would be to provide a proxy service which you can control the output, restrict access to, and can cache as needed.
Avoid XSS Phishing Attacks
This next recommendation focuses on protecting yourself as a user from a site that is vulnerable to cross site scripting attacks.
Phishing attacks, or attacks where what appears to be a valid URL links to a fraudulent web page who's purpose is to collect a users data, are nothing new to the web world. A related attack involves cross site scripting attacks where a URL to a legitimate site that has a cross site scripting vulnerability contains a script reference. Such a link may appear in an email message, blog posting/comment, or other user generated content that contains a URL. Clicking a link to a site containing a cross site scripting vulnerability would cause a 3rd party script to be included along with your request and could expose your password, user id, or any other data. Consider the following example:
A quick look at the URL shows it references the site http://foobar.com/index.html. An unsuspecting user may not see the script included as a parameter later in the URL.
It is also wise to always look at carefully at URLs and the URL parameters that are provided with them. URLs will always appear in the status bar of your browser as and you should always look for external script reference. Another solution would be to manually type in links into the URL bar of your browser if a link is suspect.
While JavaScript based interfaces can be very flexible you need to be very careful with all user provided input whether it be as parameters or form data. Always make sure to escape or filter input on the both the client and server. As a user you should be cautious not to become a victim of a vulnerable site. It's better to be safe than in the news!
What other things do you do to prevent XSS attacks?
jMaki is all about enabling Java developers to use JavaScript in their Java based applications as either a JSP tag library or a JSF component. jMaki uses the best parts of Java and the best parts of JavaScript to deliver a rich AJAX style widgets.
jMaki currently provides bootstrap widgets for many components from Dojo, Scriptaculus, Yahoo UI Widgets, Spry, DHTML Goodies, and Google. jMaki provides a common interfaces to these widget libraries and allows you to use these libraries together in the same page.
Download the jMaki web application which contains all the latest components (updated 06/16/2006). The web application has been tested against the latest builds of Glassfish. jMaki is written as a JSP 2.0/JSF 1.1 tag library and should run on earlier containers that support JSP 2.0 and/or JSF 1.1 specifications.
Interested in creating rapidly Web Applications using the jMaki project? Check out the NetBeans 5.5 jMaki plugin that allows Drag and Drop of jMaki components directly in your JSP pages. Watch the screencast demonstrating the plugin capabilities (audio and video).
Please choose from the screen of Eclipse with "Help" ->"Software Updates" -> "Update Manager". An 'Update Manager' opens.
In the "Feature Updates" view at the lower left of an 'Update Manager', please carry out the right click of the "Sites to Visit", and create a site bookmark by "New" -> "Site Bookmark...". - The bookmark to create should input the following "URL" and should push an "Finish" button. Name: Arbitrary input URL : http://propedit.sourceforge.jp/eclipse/updates/ Bookmark type: Eclipse update site
If a site bookmark is created, the bookmark created at the bottom of "Feature Updates" will appear. A click of "jp.gr.java_conf.ussiy.app.propedit.eclipse.feature.PropertiesEditorFeature x.x.x" displays a preview on a right window. Since the button "Install Now" is in around the lower right, please click.
Since an installation wizard starts, please click a "Next" button rapidly.
"You will need to restart the workbench for the changes to take effect. Would you like to restart now?" is displayed. Please reboot Eclipse according to a dialog.
No solutions exist for "NotifyUtil::java.net.ConnectException " Author: JavaWriterDude Posts: 17 Registered: 7/30/04
Oct 11, 2005 2:14 PM
Hi, I get the following error when I load a webpage that is on a tomcat 5.0 server.... It repeats about 3-5 times just from loading a page any ideas?
NotifyUtil::java.net.ConnectException: Connection refused: connect at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:305) at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:171) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:158) at java.net.Socket.connect(Socket.java:452) at java.net.Socket.connect(Socket.java:402) at sun.net.NetworkClient.doConnect(NetworkClient.java:139) at sun.net.www.http.HttpClient.openServer(HttpClient.java:402) at sun.net.www.http.HttpClient.openServer(HttpClient.java:618) at sun.net.www.http.HttpClient.<init>(HttpClient.java:306) at sun.net.www.http.HttpClient.<init>(HttpClient.java:267) at sun.net.www.http.HttpClient.New(HttpClient.java:339) at sun.net.www.http.HttpClient.New(HttpClient.java:320) at sun.net.www.http.HttpClient.New(HttpClient.java:315) at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:521) at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:498) at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:569) at org.netbeans.modules.web.monitor.server.NotifyUtil$RecordSender.run(NotifyUtil.java:237)
Re: No solutions exist for "NotifyUtil::java.net.ConnectException " Author: orangina Posts: 2 Registered: 10/12/05
Oct 12, 2005 4:45 AM (reply 1 of 8)
Hi, I'm fairly new to java and trying to download a web page page with th help of URL object and I get the following Exception:
java.net.ConnectException: Connection timed out: connect at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.PlainSocketImpl.doConnect(Unknown Source) at java.net.PlainSocketImpl.connectToAddress(Unknown Source) at java.net.PlainSocketImpl.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.<init>(Unknown Source) at java.net.Socket.<init>(Unknown Source) at HttpConnection.conectare(HttpConnection.java:92) at HttpConnection.incarca(HttpConnection.java:58) at HttpConnection.main(HttpConnection.java:44)
Can anybody help me? Shoud I know about a proxy or something like that? :) thankx
Re: No solutions exist for "NotifyUtil::java.net.ConnectException " Author: backupp Posts: 137 Registered: 8/25/05
Oct 12, 2005 8:50 PM (reply 2 of 8)
it means that u can't connect to the server. try to ping to the server and see the result.
Re: No solutions exist for "NotifyUtil::java.net.ConnectException " Author: orangina Posts: 2 Registered: 10/12/05
Oct 13, 2005 9:25 AM (reply 3 of 8)
i don't know if that reply refeared to me or not... but in case it did thank you... I figured out what was wrong with it :)) i have a proxy and i did a small modification to my code i simply added the following lines before I used the URLConnection object: // Modify system properties Properties sysProperties = System.getProperties();
Re: No solutions exist for "NotifyUtil::java.net.ConnectException " Author: jwolter Posts: 2 Registered: 10/14/05
Oct 14, 2005 1:47 PM (reply 4 of 8)
I had this problem from installing netbeans. I uninstalled it, but there was still some configurations in the <catilina home>/config/web.xml file. Remove the following:
If you want an IDE, perhaps you'd like to try eclipse.
edit your [$TOMCAT_HOME]/conf/web.xml file and rip out the following section from the top - where Netbeans snuck it in, and didn't remove - even if i uninstalled it
Re: No solutions exist for "NotifyUtil::java.net.ConnectException " Author: JavaWriterDude Posts: 17 Registered: 7/30/04
Oct 15, 2005 7:48 AM (reply 5 of 8)
GO POST your QUESTION in your OWN thread!
Re: No solutions exist for "NotifyUtil::java.net.ConnectException " Author: JavaWriterDude Posts: 17 Registered: 7/30/04
Oct 15, 2005 7:57 AM (reply 6 of 8)
Thanks jwolter, will try.
Re: No solutions exist for "NotifyUtil::java.net.ConnectException " Author: JavaWriterDude Posts: 17 Registered: 7/30/04
Oct 15, 2005 8:02 AM (reply 7 of 8)
This worked. I did have NetBeans installed but thought the error was originating from Eclipse. Thanks for the help jwolter.
Re: No solutions exist for "NotifyUtil::java.net.ConnectException " Author: ant21 Posts: 7 Registered: 11/26/00
Nov 7, 2005 4:58 AM (reply 8 of 8)
Yes, this works for me. I installed NetBeans but never notice that. I confused why get connetion refused even if access into 127.0.0.1. Now everything works fine. Thanks jwolter!
Cougaar has a Java-based architecture for the construction of large-scale distributed agent-based applications. It is the product of a multi-year DARPA research project into large scale agent systems and includes not only the core architecture but also a variety of demonstration, visualization and management components to simplify the development of complex, distributed applications.
fetchrss polls weblogs (rss feeds) and e-mails the updates, one message per updated entry. The effect is comparable to the weblog author e-mailing you personally. fetchrss can run in the background on your desktop or server.
A compact, powerful, extensible and performant component-oriented software framework written in java, and a collection of components developed for this framework. Jicarilla utilizes and supports inversion of control, seperation of concerns, seperation of interface from implementation, contract-based programming, aspect-oriented programming and event-based programming. To get the buzzwords out of the way :D
In readable english, Jicarilla provides a platform for developing a wide range of applications and software components. Think of Jicarilla as the glue between your classes, beans, components and/or services. Jicarilla can be used for building and glueing together a wide variety of applications. Whether you build web services, server applications, servlets, enterprise javabeans, desktop applications, or applets, Jicarilla will make it easier.
The Merlin project deals with the broad area of service and component management. The Merlin system is a container that provides comprehensive support for the management of complex component-based systems. Merlin uses a component meta-model to facilitate the automated assembly and deployment of components.
Mule is a light-weight messaging framework. It can be thought of as a highly distributable object broker that can seamlessly handle interactions with other applications using disparate technologies such as Jms, Http, Email, and Xml-Rpc.The Mule framework provides a highly scalable environment in which you can deploy your business components. Mule manages all the interactions between components transparently whether they exist in the same VM or over the internet and regardless of the underlying transport used.
Mule was designed around the Enterprise Service Bus enterprise integration pattern, which stipulates that different components or applications communicate through a common messaging bus, usually implemented using Jms or some other messaging server. Mule goes a lot further by abstracting Jms and any other transport technology away from the business objects used to receive messages from the bus.
Jestr--pronounced like "jester"--is a Java Reflection-based library that provides an extensible framework for defining the way objects are "stringified"--that is, converted into String's for display and logging purposes. It allows the application to define how objects are stringified just by editing a properties file. The style of stringification can be adjusted at runtime, either in a blanket fashion or just for individual classes, class hierarchies, and package hierarchies. Jestr is configurable using a properties file called jestr.properties, which models log4j.properties and should look reasonably familiar to those accustomed to Log4J.
SiteMesh is a web-page layout and decoration framework and web- application integration framework to aid in creating large sites consisting of many pages for which a consistent look/feel, navigation and layout scheme is required.
Flume is a component pipeline engine. It allows you to chain together multiple workers into a pipeline mechanism. The intention of Flume is that each of the workers would provide access to a different type of technology. For example, a pipeline could consist of a Jython script worker followed by a BeanShell script worker followed by an XSLT worker.
The pipeline workers can contain any custom code, however the intention behind Flume is that the workers would implement different scripting languages. This provides a means of separating distinct functionality of the work-flow. For example, if Al understands the business flow and Betty is really good at making it look good, Al could write his piece in Jelly and Betty could do her work in XSL. The pipeline could then execute Al's script, then do Betty's transformation, spewing out some nice document.
Echomine Muse is a library intended to make communication across a wide variety of protocols (including Jabber, Napster, Gnutella, and more) easy and somewhat consistent.
SwarmCache is a simple but effective distributed cache. It uses IP multicast to efficiently communicate with any number of hosts on a LAN. It is specifically designed for use by clustered, database-driven web applications. Such applications typically have many more read operations than write operations, which allows SwarmCache to deliver the greatest performance gains. SwarmCache uses JavaGroups internally to manage the membership and communications of its distributed cache.
The Element Construction Set makes it easy for you to build structured XML from a series of calls to objects. It tries to make sure you can't generate something that is not well-formed at the least, even if it is not necessarily well structured. I've used this in the past and found it easy to use but it seems to have fallen from favor. The last time I looked there wasn't much new activity and most people I work with tend to push for using JDOM for this purpose.
Library functions to find differences between XML documents and represent those differences as a series of edit operations (again in XML form). Sample code is provided to make it easy to not only find the differences but also to patch an existing file to make it look like a new one.
Jakarta Lucene is a high-performance, full-featured text search engine written entirely in Java. It is a technology suitable for nearly any application that requires full-text search, especially cross-platform.
JMX offers a simple way for you to package server components so you can make them administrable locally or remotely. JBoss and many other server packages now make their components MBeans (managable beans) just to get this functionality.
Consider it seriously for any server software you might be building.
Ekit is a free open source Java HTML editor applet and application. The Ekit standalone also allows for HTML to be loaded and saved, as well as serialized and saved as an RTF. It is approaching its first production release version.
Canvas is a template generator based on the Groovy language. It uses the familiar Velocity Java API to bind variables and allows you to use the full expressivity of Groovy inside your templates.
JAMon offers a set of functions which can be called to record performance data (both duration and number of times executed). The data can be reviewed using an admin JSP.
Jalopy is a source code formatter for the Sun Java programming language. It layouts any valid Java source code according to some widely configurable rules; to meet a certain coding style without putting a formatting burden on individual developers.
Bonita is a flexible cooperative workflow system, compliant to WfMC specifications, based on the workflow model proposed by the ECOO Team, which incorporates the anticipation of activities as a more flexible mechanism of workflow execution.
JaWE (Java Workflow Editor) is the first open source graphical Java workflow process editor fully according to WfMC specifications supporting XPDL as its native file format and LDAP connections. It can be used to edit / view every XPDL file which conforms to WfMC specifications.
The "OpenEmcee Microflow Engine for Java" is an open source framework (Released under MPL 1.1) for developing flexible, manageable, and adaptable applications. It aims to allow application developers to develop well-engineered business-logic intensive application domain software. Drafting from the "Model" and "Controller" layers of the "Model-View-Controller" pattern, it allows developers to separate the business context of their application from their core business functions.
This separation of context from core implementation encourages development of software units which are easily reusable and require no or little modification to business critical code when implementing new functionality. Also, these units of work ("tasks") can be easily reused in future projects.
The Shark project delivers a workflow server with a difference. Shark is completely based on standards from WfMC and OMG using XPDL as its native workflow definition format. Storage of processes and activities is done using Enhydra DODS.
지금은 웹 프레임워크의 전성시대라고 해도 과언이 아닐 것이다. MVC(Model -View-Controller) 형태의 모델2가 발표된 이후 수많은 웹 프레임워크가 발표됐고, 이런 웹 프레임워크의 난립(?)은 프로젝트 시작부터 어떤 것을 선택해야 할지에 대한 고민을 안겨주었다. 모든 웹 프레임워크가 나름대로 강조하는 장점들이 있지만, 왠지 ‘2%’ 부족하다는 느낌은 우리로 하여금 섣불리 그것을 선택하기를 주저하게 한다. 하지만 난세에 영웅이 난다고 했던가? JSF(Java Sever Faces)는 자바 표준 스펙(JCP-127)이라는 점에서 태생부터가 다른 웹 프레임워크와는 차별성을 보여주고 있다. 또한 스트럿츠 프로젝트의 리더인 Craig R. McClanahan 이 주도하고 스트럿츠의 커미터들이 대거 참여를 했다는 점에서 스트럿츠 이상의 그 무엇을 기대해도 좋을 것이라는 기대감을 갖게 한다.
JSF의 오픈소스 구현체, MyFaces MyFaces는 JSF의 오픈소스 구현체이다. 인큐베이터에서 스트럿츠와 같은 위치인 최상위 프로젝트로 격상된 오픈소스 프로젝트인 것을 보면 ASF에서 MyFaces에 거는 기대가 얼마나 큰 것인지를 알 수 있다. MyFaces는 JSF의 구현체임으로 MVC 모델을 기본으로 한 최신의 웹 애플리케이션 프레임워크이며, 무엇보다 UI 단의 풍부한 컴포넌트는 그 어떤 웹 프레임워크와 비교해도 뒤떨어지지 않는다. 이번 기사에서는 JSF에 대한 설명보다 MyFaces에 포함된 쓸만한 컴포넌트들을 중심으로 설명하고자 한다. <표 1>에는 MyFaces의 동작 여부를 테스트한 리스트를 보여주고 있지만, 다른 버전의 WAS 등에서도 JSP 2.0이 지원될 수 있는 환경만 갖추어진다면 적용하기에는 큰 무리가 없다.
MyFaces 설치하기 MyFaces를 동작시켜보기 위해선 다음과 같은 소프트웨어가 필요하다.
◆ JDK 1.5 설치 ◆ 톰캣 5.5.7 설치 : 기존의 톰캣을 사용할 경우 JSF 라이브러리가 있다면 삭제한다(jsf-api.jar, jsf-impl.jar). ◆ MyFaces Example 설치 - <TOMCAT_HOME>/webapps 디렉토리 밑에 war를 설치한다. - 톰캣 실행 후 <TOMCAT_HOME>/webapps/myfaces-examples/WEB-INF /lib/commones-el.jar와 jsp-2.0.jar를 삭제한다(톰캣 5.5일 경우만). - 톰캣을 재시작한다.
MyFaces의 다양한 컴포넌트 MyFaces는 다양한 컴포넌트들로 무장하고 있다. 기존 웹 기반의 자바 프레임워크가 가지지 않는 이런 여러 가지 UI단 컴포넌트들은 MyFaces가 가는 길을 좀 더 편하게 만들 것이다. 많은 개발자들이 평소 프로젝트를 진행하면서, ‘아 이런 UI 컴포넌트들이 있었으면 좋겠다!’라고 생각했던 것의 대부분을 MyFaces에서 만나볼 수 있다. 또한 MyFaces는 JSF의 구현체로써 기본적인 JSF 관련 태그 선언부의 경우 다음과 같이 JSF를 따르고 있다.
JSCook 메뉴 컴포넌트 JSCook 메뉴 컴포넌트는 <화면 2>에서 보듯이 웹 페이지의 메뉴를 만들어 낼 수 있는 컴포넌트이다. 커스텀 태그(custom tag)로 제공되고 실제 실행은 자바스크립트에 의해 동작된다. JSCook 메뉴는 Heng Yuan이라는 청년에 의해 개발된 자바스크립트로 작성된 메뉴 스크립트이다. 본래의 JSCook 메뉴의 경우 자바스크립트의 변수로 메뉴들을 정의하고, 이렇게 정의된 변수를 통해 자바스크립트가 메뉴를 표현하게 되어 있었다(변수로 메뉴를 정의하는 것은 상당히 번거로운 작업처럼 보였는데, JSCook의 홈페이지에서는 이런 메뉴 변수를 정의하는 Menu Builder를 제공하고 있다. Menu Builder는 브라우저상에서 메뉴의 이름과 아이콘 위치 등을 입력하면 자동으로 자바스크립트 소스를 만들어준다).
MyFaces에서는 커스텀 태그를 통해 정의된 메뉴의 URL과 레이블, 아이콘들을 정의한다. 실제 브라우저의 요청에 의해 커스텀 태그가 동작하게 되면(자바스크립트로써) 기존의 JSCook 메뉴가 원하는 형태의 소스로 변경된다. 즉 JSCook 메뉴의 경우 MyFaces의 커스텀 태그를 사용할 수도 있고, 자바스크립트 형태로도 사용할 수 있음으로 때에 따라 적절한 방법을 사용하면 된다. JSCook 메뉴를 구성하는 항목은 유일한 아이디와 아이템 레이블 그리고 링크 클릭시의 액션으로 구성되며, 모든 JSCook 메뉴는 <x:jscookMenu/> 태그를 부모 태그로 해야 하며, 각 메뉴 항목은 <x:navigationMenuItem/>으로 추가할 수 있다.
트리 컴포넌트 트리 컴포넌트의 경우 <화면 3>처럼 보이는 전형적인 트리의 형태를 갖추고 있으며, <리스트 2>의 예제를 보면 벌써 몇몇 개발자의 입에서는 탄성이 나올 법한 코드로 이뤄져 있다. DefultMutableTree Node 등 기존 Swing에서 사용하던 트리 컴포넌트와 거의 동일한 형태로 제공되며 사용하기도 상당히 편리하다. JSP의 Scriptlet을 통해 트리 컴포넌트를 구성하는 각 노드들에 대해 생성하고, Root 트리 노드를 기준으로 insert 메쏘드를 통하여 추가할 수 있다. 또한 구성된 트리 구조를 pageContext의 Attribute에 넣어 페이지가 다시 리로딩되거나 호출됐을 때 기존에 구성된 트리 구조를 재사용하도록 하고 있다. 트리 컴포넌트는 <x:tree/> 태그를 부모로 하여 구성되며, value 항목에 스크립트릿으로 TreeModel을 구성하여 pageContext에 셋팅된 값이 보여진다.
<% if (pageContext.getAttribute("treeModel", PageContext.SESSION_SCOPE) == null) { DefaultMutableTreeNode root = new DefaultMutableTreeNode("XY"); DefaultMutableTreeNode a = new DefaultMutableTreeNode("A"); root.insert(a); DefaultMutableTreeNode b = new DefaultMutableTreeNode("B"); root.insert(b); DefaultMutableTreeNode c = new DefaultMutableTreeNode("C"); root.insert(c);
DefaultMutableTreeNode node = new DefaultMutableTreeNode("a1"); a.insert(node); node = new DefaultMutableTreeNode("a2 "); a.insert(node); node = new DefaultMutableTreeNode("b "); b.insert(node);
a = node; node = new DefaultMutableTreeNode("x1"); a.insert(node); node = new DefaultMutableTreeNode("x2"); a.insert(node);
pageContext.setAttribute("treeModel", new DefaultTreeModel(root), PageContext.SESSION_SCOPE); } %>
정렬 가능한 테이블 컴포넌트 <x:dataTable/>은 HTML의 Table 형태로 데이터를 표현하는 수단으로 상당히 유용하게 사용할 수 있는 태그이다. 정렬 가능한 테이블은 dataTable이라는 CustomTag에 sortColumn과 sortAscending이라는 속성을 부여해 줌으로써 정렬 가능한 테이블 형태로 보여주는 것이다. <화면 4>에서 Car Type과 Car Color 부분을 클릭하면 순방향 정렬과 역방향 정렬로 토글(toggle)되며 내용이 표시된다. dataTable의 Header 영역에 sort를 할 수 있는 링크를 주기 위해 command SortHeader를 사용하고 있고 화살표의 사용여부를 arrow=”true”로 설정하고 있다. <x:dataTable/>을 부모 태그로 사용하며 각 컬럼마다 <h:column/>을 사용하여 테이블 구조를 나타나게 된다.
HTML 에디터 컴포넌트 HTML 에디터 컴포넌트의 경우 Kupu라는 이름으로 존재하던 WYSIWYG XHTML 에디터를 MyFaces의 컴포넌트로 포함시킨 것이다. HTML 에디터의 경우 상당히 많은 사이트에서 사용되고 있지만 웹 프레임워크 단에서의 UI 컴포넌트로 제공되는 것은 처음이 아닌가 싶다. HTML 에디터의 경우 글자체, Bold, Underline 등의 폰트를 꾸밀 수 있는 버튼과 색상, 정렬 등 다른 상용 HTML 에디터와 비교해도 뒤떨어지지 않는 기능성을 보여주고 있다. HTML 에디터 커스텀 태그의 경우 필수 속성은 없다.
DataScroller 컴포넌트 DataScroller 컴포넌트의 경우 리스트를 표현하는 JSP 단에서 페이지 이동을 할 때 사용하는 컴포넌트이다. 페이지 이동의 경우 몇몇 사이트에서 커스텀 태그를 만들어 사용하는 경우를 보았으나, 거의 대부분은 특별한 표준이 없이 개발되고 있는 것 중에 하나이다. 하지만 리스트의 경우 페이지 이동은 필수적인 컴포넌트인 것을 보면, My Faces에 DataScroller가 있다는 것은 참으로 다행스러운 일이다. 또한 <x:dataScroller/>를 부모 태그로 하여 현재 페이지를 나타낼 pageCountVal 속성이 존재하며, 각 페이지의 navigation의 여부를 paginator 속성의 boolean 타입을 정의하고 보여질 총 페이지 수를 paginatorMaxPages로 정의할 수 있다.
여러 Validation 컴포넌트 MyFaces의 Validation의 경우 썬 JSF RI가 세 가지 정도의 기본적인 Validation을 제공하는 것에 추가적으로 이메일, 신용카드 , ISBN, Equal 같은 상당히 유용한 Validation을 제공한다. Valication을 넣는 방법으로는 <f:validator/> 태그에 validatorId로써 사용하고자 하는 Validator 클래스를 지정하는 방법과 <x:validateXXX/>와 같은 MyFaces의 확장 태그 형태로 사용할 수 있다.
MyFaces의 장밋빛 미래 JSF가 자바 표준 스펙으로써 향후 J2EE의 웹 프레임워크의 중심이 될 것이라는 생각은 그리 어렵지 않게 할 수 있다. 또한 MyFaces가 JSF의 오픈소스 구현체로써 상당히 중요하게 대접(?)받을 것도 쉽게 알 수 있다. MyFaces는 충실한 JSF의 구현체이면서 유용한 컴포넌트들로 무장하고 있다. 다만 조금 걱정이 되는 부분은 UI가 상당히 다이나믹한 국내의 실정에서 얼마나 적용 가능성이 있을지에 대한 우려와 개발자 입장에서 커스텀 태그에 대한 사용이 얼마나 쉽게 받아들일 수 있는가가 문제가 될 수 있을 것으로 보인다. MyFaces는 이클립스와 같은 IDE와의 연계성, J2EE 진영의 주요 벤더에서 JSF를 제대로 지원하는 순간부터 MyFaces의 활용도는 그 어떤 JSF의 구현체보다 활발할 것이다. 아직 제한된 오픈소스만을 사용하는 국내 실정에서 좀 더 많은 오픈소스를 사용하게 되는 계기가 MyFaces를 통해 시작되기를 간절히 바랄뿐이다. [maso]