BLOG main image
정민군's Blog
miniya devlog

'Framework'에 해당되는 글 2건

  1. 2007.08.01 Struts 2 달라진 점
  2. 2007.07.27 Welcome to Struts 2

Struts 2 달라진 점

Framework/STRUTS2 2007. 8. 1. 11:21 by 정민군

Struts 2는, 이름으로, Struts 1과 구별된다.

Struts 2는 WebWork 2.2.4의 아키텍처를 전격 수용한 웹 프레임워크로 기존 Struts 프레임워크와는 내부 구조부터 다르다. 달리 말하면, WebWork 프레임워크가 Struts의 명성이라는 옷을 입은 셈이다. Struts 2.0.6 버전에서 상당히 안정되고 새로운 웹 프레임워크로 변신 가능성을 열고 있지만, Struts 2.0.1 BETA 버전에서는 둘의 생경한 만남 그 자체였다.

Struts 2 버전에서 Action 정의 방식이 Struts 1.x 버전과 다르다. 아래에 간략히 정리한다.

1. Struts 2에서 Struts 1.x 코드를 재사용하려면 플러그인(plugin)을 사용하여야 한다.

2. WebWork 프레임워크의 action 정의 방식

이 방식은 Struts 2에서 동적 메소드 호출(dynamic method invocation)이라고 이름이 붙여졌고, 이를 사용하기 위해서는 struts.properties 파일에서 다음과 같은 구성을 지정하여야 한다. 사전에 false로 지정되어 있기 때문이다.

struts.enable.DynamicMethodInvocation = true

3. Wildcard Mapping 지원

웹 애플리케이션의 규모가 커지면 action 수가 많아질 것이고, 기존 방식대로 action을 일일이 정의하는 것이 꽤 번거로울 수 밖에 없다. 이런 경우에 Wildcard Mapping 방식은 상당히 편리하다.

Struts 2 Wildcard Mappings 문서에 있는 예는 이렇다:

<!-- Generic edit* mapping -->
<action name="/edit*" class="org.apache.struts.webapp.example.Edit{1}Action">   
<result name="failure" path="/mainMenu.jsp"/>
<result path="/\{1\}.jsp"/></action>

/edit으로 시작하는 모든 페이지와 일치하는 Wildcard Mapping에 의해 action을 정의한다.

다른 예로, 3개의 action을 Wildcard Mapping으로 한 번에 정의하는 예를 아래에 보인다.

<action name="user!*" method="{1}" class="myapp.actions.UserAction">   
<result name="input">/WEB-INF/jsp/userForm.jsp</result>   
<result name="list">/WEB-INF/jsp/userList.jsp</result>   
<result name="saved" type="redirect-action">user!list.action</result>
</action>

여기서, list(), input() 메소드를 가지는 단일의 Action 클래스에 대해 Wildcard Mapping을 적용하여 user!input.action, user!list.action, user!saved.action 과 같은 action 호출이 가능하도록 한 번에 action을 정의할 수 있다.


4. 무구성(Zero configuration)

우리 식으로 번역하면 무구성(Zero configuration)이 적절한 것 같다. 말 그대로 구성이 없다는 것으로, 복잡한 구성 파일을 만들지 않아도 된다. 하지만, action 정의가 구성 파일에서 하지 않는 것뿐 action 클래스에서는 꼭 있어야 한다.

4.1. actionPackages 필터 지정

web.aml 파일에서 actionPackages 필터의 init param에 action 클래스를 포함하는 패키지를 쉼표로 구분하여 지정한다.

<filter>
  <filter-name>struts2</filter-name>
  <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
  <init-param>
    <param-name>actionPackages</param-name>
    <param-value>com.foo.bar,com.baz.quux</param-value>
  </init-param>

</filter>


4.2. 패키지와 action 명칭

하위 패키지 명칭을 네임스페이스(namespace)로, action 클래스 명칭을 action 이름으로 만든다. 클래스 명칭 뒷부분에 붙여진 "Action"은 action 이름에서 빠지게 된다. 따라서 구성된 패키지 명칭이 com.myapp.actions, action 클래스가 com.myapp.actions.member.EditAction 이면, http://server/myapp/member/edit.action을 통해 이에 접근할 수 있다.

4.3. Result 및 Results Annotation

클래스 수준에서 Result 및 Results Annotation 사용하여 결과를 정의한다.

단일한 결과에 대해 Result Annotation 사용한다.

Struts 2 Result Annotation 문서의 코드 예:

@Result(name="success", value="/home.page", type=TilesResult.class)
public class HomeAction extends ActionSupport {
    // ...
}

여러 개의 결과는 Result 및 Results Annotation 사용한다.

@Results({
    @Result(name="input", value="/WEB-INF/jsp/userForm.jsp"),
    @Result(name="list", value="/WEB-INF/jsp/userList.jsp")
})
public class UserAction extends ActionSupport  {
    :

Struts 2 무구성(Zero configuration)은 구성 파일을 더 이상 만들지 않아도 된다는 점에서는 편리해졌다고 할 수 있지만, Struts 2의 action 호출 방식 때문에 (이제까지 구성 파일에서 정의했던) 결과 정의를 클래스에서 Result 및 Results Annotation을 새로 추가하여야 한다.

Welcome to Struts 2

Framework/STRUTS2 2007. 7. 27. 18:09 by 정민군

Struts 2와 관련된 국내 문서가 너무 없는거 같아 http://struts.apache.org 의 기본문서를 토대로 기본 프로젝트를 하나 만들어 보았습니다.

지극히 초보분들을 위한 내용이니, 고수 분들은 '뒤로'를 눌러주시면 되겠습니다^^;

기본적인 HelloWorld 프로젝트를 생성합니다. 스트럿츠 관련 라이브러리를 추가합니다. (WEB-INF/lib/)

미니멈하게 필요한 라이브러리 파일은 다음과 같습니다.

  • struts2-core.jar : 스트럿츠2의 코어 라이브러리입니다.
  • xwork.jar : 스트럿츠2의 새로운 점중 가장 큰 부분입니다. Webwork(= Xwork)와 통합 되었는데요. xwork가 주가 되고 struts가 뒷받침 해주는 형식으로 작동합니다.
  • ognl.jar : Object Graph Navigation Language라고 합니다. struts2를 위한 EL(Expression Language)라고 하는군요. JSP 2.1 스펙에 포함된 EL과 거진 비슷한거 같습니다. 좀더 편한거 같긴한데 struts2의 퍼포먼스를 좀먹는 녀석이라고 하네요. 이녀석이 꼭 있어야 한다니..OTL
  • freemarker.jar : UI 태그 탬플릿을 위해 있는 녀석입니다. 벨로시티를 생각하시면 되겠습니다.
  • commons-logging.jar : log4j와 같은 로깅을 위한 라이브러리입니다.


다음의 소스들을 보시면 느끼시겠지만, 예전의 서블릿 매핑이 아닌 필터 매핑을 하고 있습니다.

눈에 띄는것부터 보자면 excute함수의 인자가 하나도 없군요. 컨트롤러에서 특정 로직을 수행후에 view로 리턴해 줄때 열심히 setAttribute하던것도 없어졌습니다. 그냥 변수에 담아두면 가져다 쓸수 있군요.

SUCCESS를 많이 써서 그럴까요? 리턴할떄 SUCCESS가 기본 상수가 되어버린 모양입니다.

열심히 mapping어쩌고를 안써도 되게 되었네요.

또한 struts.properties에 기본적인 설정을 할수 있습니다. 캐릭터셋까지 기본설정 가능하군요. 디폴트는 UTF-8입니다.

struts2의 디폴트 확장자는 do가 아닌 action입니다.

/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

 <display-name>HelloWorld</display-name>
 <filter>
  <filter-name>struts2</filter-name>
  <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
 </filter>

 <filter-mapping>
  <filter-name>struts2</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
</web-app>



/WEB-INF/classes/struts.xml

version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
 "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
 <!-- Configuration for the default package. -->
 <package name="tutorial" extends="struts-default">
        <action name="HelloWorld" class="tutorial.HelloWorld">
            <result>Helloworld.jsp</result>
        </action>
        <!-- Add your actions here -->
    </package>
</struts>



/WEB-INF/classes/struts.properties

### Struts default properties
###(can be overridden by a struts.properties file in the root of the classpath)
###

### Specifies the Configuration used to configure Struts
### one could extend org.apache.struts2.config.Configuration
### to build one's customize way of getting the configurations parameters into Struts
# struts.configuration=org.apache.struts2.config.DefaultConfiguration

### This can be used to set your default locale and encoding scheme
# struts.locale=en_US
struts.i18n.encoding=UTF-8

### if specified, the default object factory can be overridden here
### Note: short-hand notation is supported in some cases, such as "spring"
### Alternatively, you can provide a com.opensymphony.xwork2.ObjectFactory subclass name here 
# struts.objectFactory = spring

### specifies the autoWiring logic when using the SpringObjectFactory.
### valid values are: name, type, auto, and constructor (name is the default)
struts.objectFactory.spring.autoWire = name

### indicates to the struts-spring integration if Class instances should be cached
### this should, until a future Spring release makes it possible, be left as true
### unless you know exactly what you are doing!
### valid values are: true, false (true is the default)
struts.objectFactory.spring.useClassCache = true

### if specified, the default object type determiner can be overridden here
### Note: short-hand notation is supported in some cases, such as "tiger" or "notiger"
### Alternatively, you can provide a com.opensymphony.xwork2.util.ObjectTypeDeterminer
### implementation name here
### Note: if you have the xwork-tiger.jar within your classpath, GenericsObjectTypeDeterminer is
### used by default
### To disable tiger support use the "notiger" property value here.
#struts.objectTypeDeterminer = tiger
#struts.objectTypeDeterminer = notiger

### Parser to handle HTTP POST requests, encoded using the MIME-type multipart/form-data
# struts.multipart.parser=cos
# struts.multipart.parser=pell
struts.multipart.parser=jakarta
# uses javax.servlet.context.tempdir by default
struts.multipart.saveDir=
struts.multipart.maxSize=2097152

### Load custom property files (does not override struts.properties!)
# struts.custom.properties=application,org/apache/struts2/extension/custom

### How request URLs are mapped to and from actions
#struts.mapper.class=org.apache.struts2.dispatcher.mapper.DefaultActionMapper

### Used by the DefaultActionMapper
### You may provide a comma separated list, e.g. struts.action.extension=action,jnlp,do
struts.action.extension=do

### Used by FilterDispatcher
### If true then Struts serves static content from inside its jar.
### If false then the static content must be available at <context_path>/struts
struts.serve.static=true

### Used by FilterDispatcher
### This is good for development where one wants changes to the static content be
### fetch on each request.
### NOTE: This will only have effect if struts.serve.static=true
### If true -> Struts will write out header for static contents such that they will
###             be cached by web browsers (using Date, Cache-Content, Pragma, Expires)
###             headers).
### If false -> Struts will write out header for static contents such that they are
###            NOT to be cached by web browser (using Cache-Content, Pragma, Expires
###            headers)
struts.serve.static.browserCache=true

### Set this to false if you wish to disable implicit dynamic method invocation
### via the URL request. This includes URLs like foo!bar.action, as well as params
### like method:bar (but not action:foo).
### An alternative to implicit dynamic method invocation is to use wildcard
### mappings, such as <action name="*/*" method="{2}" class="actions.{1}">
struts.enable.DynamicMethodInvocation = true

### Set this to true if you wish to allow slashes in your action names.  If false,
### Actions names cannot have slashes, and will be accessible via any directory
### prefix.  This is the traditional behavior expected of WebWork applications.
### Setting to true is useful when you want to use wildcards and store values
### in the URL, to be extracted by wildcard patterns, such as
### <action name="*/*" method="{2}" class="actions.{1}"> to match "/foo/edit" or
### "/foo/save".
struts.enable.SlashesInActionNames = false

### use alternative syntax that requires %{} in most places
### to evaluate expressions for String attributes for tags
struts.tag.altSyntax=true

### when set to true, Struts will act much more friendly for developers. This
### includes:
### - struts.i18n.reload = true
### - struts.configuration.xml.reload = true
### - raising various debug or ignorable problems to errors
###   For example: normally a request to foo.action?someUnknownField=true should
###                be ignored (given that any value can come from the web and it
###                should not be trusted). However, during development, it may be
###                useful to know when these errors are happening and be told of
###                them right away.
struts.devMode = false

### when set to true, resource bundles will be reloaded on _every_ request.
### this is good during development, but should never be used in production
struts.i18n.reload=false

### Standard UI theme
### Change this to reflect which path should be used for JSP control tag templates by default
struts.ui.theme=xhtml
struts.ui.templateDir=template
#sets the default template type. Either ftl, vm, or jsp
struts.ui.templateSuffix=ftl

### Configuration reloading
### This will cause the configuration to reload struts.xml when it is changed
struts.configuration.xml.reload=false

### Location of velocity.properties file.  defaults to velocity.properties
struts.velocity.configfile = velocity.properties

### Comma separated list of VelocityContext classnames to chain to the StrutsVelocityContext
struts.velocity.contexts =

### Location of the velocity toolbox
struts.velocity.toolboxlocation=

### used to build URLs, such as the UrlTag
struts.url.http.port = 80
struts.url.https.port = 443
### possible values are: none, get or all
struts.url.includeParams = get

### Load custom default resource bundles
# struts.custom.i18n.resources=testmessages,testmessages2

### workaround for some app servers that don't handle HttpServletRequest.getParameterMap()
### often used for WebLogic, Orion, and OC4J
struts.dispatcher.parametersWorkaround = false

### configure the Freemarker Manager class to be used
### Allows user to plug-in customised Freemarker Manager if necessary
### MUST extends off org.apache.struts2.views.freemarker.FreemarkerManager
#struts.freemarker.manager.classname=org.apache.struts2.views.freemarker.FreemarkerManager

### See the StrutsBeanWrapper javadocs for more information
struts.freemarker.wrapper.altMap=true

### configure the XSLTResult class to use stylesheet caching.
### Set to true for developers and false for production.
struts.xslt.nocache=false

### A list of configuration files automatically loaded by Struts
struts.configuration.files=struts-default.xml,struts-plugin.xml,struts.xml

### Whether to always select the namespace to be everything before the last slash or not
struts.mapper.alwaysSelectFullNamespace=false



Class : tutorial.HelloWorld.java

package tutorial;

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorld extends ActionSupport {

 private static final long serialVersionUID = 1L;
 public static final String MESSAGE = "Hello World (Struts 2)";

 public String execute() throws Exception {
  setMessage(MESSAGE);
  return SUCCESS;
 }

 private String message;

 public void setMessage(String message) {
  this.message = message;
 }

 public String getMessage() {
  return message;
 }
}



/Helloworld.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>

<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
    <head>
        <title>Hello World!</title>
    </head>
    <body>
        <h2><s:property value="message" /></h2>
    </body>
</html>
1 

카테고리

분류 전체보기 (46)
Technic (5)
Language (16)
Database (8)
System (5)
Algorithm (1)
Design (1)
Tool (3)
Framework (2)
Network (1)
Utility (1)
SmartPhone (2)

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

달력

«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31

글 보관함