Dev/Struts

Struts2 - 입출력 기능 구현, Struts1과2 비교

창문닦이 2019. 3. 22. 14:48

Struts properties 파일

properties 파일 생성시

- 최대 사이즈를 지정한다.(파일 업로드,다운로드 시 필요)

struts.multipart.maxSize=2097152


- true로 설정하면 리소스 번들을 매 요청시 마다 reload 한다.

- 개발할 때는 편하지만 실제 서비스에는 절대로 사용해서는 안된다.

struts.i18n.reload=false


Struts2 실습 - 테스트 예제1

1. TestAction 클래스 생성 (Model)

Struts2 에서는 Action클래스에서는 변수와 메소드를 함께 생성할 수 있다.(DTO와 Action이 함께 작성된 예제)

package com.test;

import com.opensymphony.xwork2.ActionSupport;

public class TestAction extends ActionSupport {

private static final long serialVersionUID = 1L;

private String userId;

private String userName;

private String message;

public String getUserId() {

return userId;

}

public void setUserId(String userId) {

this.userId = userId;

}

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

public String getMessage() {

return message;

}

public void setMessage(String message) {

this.message = message;

}

@Override

public String execute() throws Exception {

message = userName + "님 반가워요!!";

return SUCCESS;

//struts1에서 mapping.findForward("created"); 를 작성했던 것처럼 반환값 설정

//SUCCESS는 내장변수.

//String com.opensymphony.xwork2.Action.SUCCESS = "success"

//xml파일 작성시 success로 처리하면 된다.

}

}

2. write.jsp (View - 데이터 입력 페이지)

<%@ page contentType="text/html; charset=UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%

request.setCharacterEncoding("UTF-8");

String cp = request.getContextPath();

%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>입력</title>

</head>

<body>

<form action="<%=cp%>/itwill/write_ok.action" method="post">

아이디 : <input type="text" name="userId"/><br>

이름 : <input type="text" name="userName"/><br>

<input type="submit" value="보내기">

</form>

</body>

</html>

3. write_ok.jsp (View - 데이터 출력 페이지)

<%@ page contentType="text/html; charset=UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%

request.setCharacterEncoding("UTF-8");

String cp = request.getContextPath();

%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>출력</title>

</head>

<body>

아이디 : ${userId }<br/>

이름 : ${userName }<br/>

메세지 : ${message }<br/>

</body>

</html>

4. struts-test.xml 생성 (환경설정 등록)

이 패키지의 name을 설정하는 것은 사용자 정의. 패키지를 사용하는 경우는 어떤 주소가 왔을 때 사용하겠다고 설정을 해둬야 한다.

(유의!! 쌍따옴표안에는 공백이 들어가 있으면 안됨)

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

<package name="test" extends="struts-default" namespace="/itwill" >

   

<action name="write" >

<result>/test/write.jsp</result>

</action>

<action name="write_ok" class="com.test.TestAction">

<result name="success">/test/write_ok.jsp</result>

</action>

</package>

</struts>

5. struts.xml에 다른 환경설정 파일을 등록(struts-test.xml)

<?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="default" extends="struts-default" namespace="" >       

      <global-results>

          <result name="error">/exception/error.jsp</result>

      </global-results>

 </package>

 <include file="struts-test.xml"/>

</struts>

6. 실행 페이지 

환경설정파일(현재 struts-test.xml)에서 등록한 namespace에 해당하는 클라이언트 브라우저에서 요청할 경우 해당하는 JSP파일로 연결되었다.


클라이언트의 요청에 write_ok가 왔을 때 action태그에 class="com.test.TestAction" 을 기재하여 해당 클래스가 함께 write_ok.action 으로 전달되는 모습을 볼 수 있다.

<action name="write_ok" class="com.test.TestAction">

<result name="success">/test/write_ok.jsp</result>

</action>



Struts2 실습 - 테스트 예제2

1. User클래스 생성(Domain Object)

도메인 오브젝트의 발전사: http://egloos.zum.com/springmvc/v/542467



package com.test1;

//Domain Object . 임시적으로 발생하는 데이터를 처리하기 전까지 담아두는 도메인 객체

public class User {

private String userId;

private String userName;

public String getUserId() {

return userId;

}

public void setUserId(String userId) {

this.userId = userId;

}

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

}

2. TestAction 클래스 

package com.test1;

import com.opensymphony.xwork2.ActionSupport;

public class TestAction extends ActionSupport{

private static final long serialVersionUID = 1L;

//Domain Object를 변수형식으로 생성 가능(struts2 덕분!)

private User user;

private String message;

public User getUser() {

return user;

}

public void setUser(User user) {

this.user = user;

}

//message는 Setter를 사용하지않고 execute 메소드를 통해 생성할 것

public String getMessage() {

return message;

}

@Override

public String execute() throws Exception {

message = user.getUserName() + "님 반가워요!";

return "ok";//반환값으로 문자열도 가능

}

}

3. created.JSP (데이터 입력 페이지)

<%@ page contentType="text/html; charset=UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%

request.setCharacterEncoding("UTF-8");

String cp = request.getContextPath();

%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>입력</title>

</head>

<body>

<form action="<%=cp%>/itwill/created_ok.action" method="post">

아이디 : <input type="text" name="user.userId"/><br>

이름 : <input type="text" name="user.userName"/><br>

<input type="submit" value="보내기">

</form>

</body>

</html>

4. result.JSP(데이터 출력 페이지)

<%@ page contentType="text/html; charset=UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%

request.setCharacterEncoding("UTF-8");

String cp = request.getContextPath();

%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>출력</title>

</head>

<body>

아이디 : ${user.userId }<br/>

이름 : ${user.userName }<br/>

메세지 : ${message }<br/>

</body>

</html>

5. struts-test.xml 에 경로 등록

▶ Struts1에 비해 Mapper가 간단한 것을 볼 수 있다

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

<package name="test" extends="struts-default" namespace="/itwill" >


<action name="created" >

<result>/test1/created.jsp</result>

</action>

<action name="created_ok" class="com.test1.TestAction">

<result name="ok">/test1/result.jsp</result>

</action>

</package>

</struts>

6. 실행 페이지 

환경설정파일(현재 struts-test.xml)에서 등록한 동일한 test package 내 JSP페이지의 위치가 달라도 연결이 가능하다.


Struts2 실습 - 테스트 예제3

1. User 클래스 생성

package com.test2;

//Domain Object . 임시적으로 발생하는 데이터를 처리하기 전까지 담아두는 도메인 객체

public class User {

private String userId;

private String userPwd;

private String userName;

private String mode; //하나의 파일을 두가지 동작으로 사용하려고 생성

public String getUserId() {

return userId;

}

public void setUserId(String userId) {

this.userId = userId;

}

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

public String getMode() {

return mode;

}

public void setMode(String mode) {

this.mode = mode;

}

public String getUserPwd() {

return userPwd;

}

public void setUserPwd(String userPwd) {

this.userPwd = userPwd;

}

}

2. TestAction 클래스 생성

package com.test2;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

import com.opensymphony.xwork2.ModelDriven;

import com.opensymphony.xwork2.Preparable;

public class TestAction extends ActionSupport

implements Preparable,ModelDriven<User>{//Model은 데이터에 해당

//서블릿에서는 if문으로 사용

//서블릿에서는 doPost, doGet메소드를 반드시 생성했어야 했음

//Struts1에서는 메소드로 분해하여 호출

//Struts2의 기본형식은 아래와 같다. getDto(), getModel(), prepare()

private static final long serialVersionUID = 1L;

private User dto;

public User getDto() {

//getParameter의 역할

return dto;

}

//ModelDriven인터페이스

@Override

public User getModel() {

return dto;

}

//Preparable인터페이스

@Override

public void prepare() throws Exception {

dto = new User();//객체 생성

//호출하는 명령어가 없어도 struts2가 알아서 진행

}

//struts1에서는 매개변수로 request와 response가 항상 존재 했었음

//struts2에서는 기본적으로 매개변수를 입력하지 않으므로 메소드의 코딩이 단순해짐

//그래서 사용할때마다 요청을 해야함

public String created() throws Exception {

//==와 .equals()의 순서가 바뀌면 오류남. 주의!

if(dto==null||dto.getMode()==null||dto.getMode().equals("")){

return INPUT; //내장변수 String com.opensymphony.xwork2.Action.INPUT = "input"

}

//세션을 만드는 것은 request. 하지만 매개변수로 입력하지 않았으므로 생성해주어야 한다

//ServletActionContext클래스에 request를 요청해서 받음(Context는 전체를 의미!)

HttpServletRequest request = ServletActionContext.getRequest();

request.setAttribute("message", "스트럿츠2..");

//request.setAttribute("dto", dto);//로 데이터를 넘겼었는데

//struts2는 자동으로 getDto 메소드를 통해 전달

return SUCCESS;

}

}

3. write.jsp(데이터 입력 페이지)

<%@ page contentType="text/html; charset=UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%

request.setCharacterEncoding("UTF-8");

String cp = request.getContextPath();

%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>입력</title>

</head>

<body>

<form action="<%=cp%>/modelDri/write.action" method="post">

아이디 : <input type="text" name="userId"/><br>

패스워드 : <input type="text" name="userPwd"/><br>

이름 : <input type="text" name="userName"/><br>

<input type="hidden" name="mode" value="save"/>

<input type="submit" value="보내기">

</form>

</body>

</html>

4. view.jsp 생성(데이터 출력 페이지)

<%@ page contentType="text/html; charset=UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%

request.setCharacterEncoding("UTF-8");

String cp = request.getContextPath();

%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>출력</title>

</head>

<body>

아이디: ${dto.userId }<br/>

패스워드:${dto.userPwd }<br/>

이름 : ${dto.userName}<br/>

메세지:${message }<br/>

</body>

</html>

5. Mapper 등록 (struts-test.xml에 package 추가)

컨트롤러 안에 분배기의 역할을 하는 패키지가 2개.

6. 실행 페이지 

환경설정파일(현재 struts-test.xml)안에 package를 여러개 등록할 수 있다.



1. 클라이언트의 요청 URL에 write.action이 올 경우 TestAction 클래스의 created 메소드를 호출하라고 컨트롤러에 설정(Struts-test.xml)


2. created 메소드의 반환값이 'input'이라면 write.jsp 페이지를 연결하고 'success'라면 view.jsp를 연결


3. struts2 프레임워크는 포워드하면서 dto를 알아서 함께 가져간다.






Struts1 와 Struts2 비교

1. 단순화된 디자인

인터페이스 대신에 추상클래스 기반으로 개발을 하는 것은 Struts 1에서 존재했던 디자인상의 문제를 Struts 2에서는 해결이 되었다. 대부분의 Struts 2 클래스들은 인터페이스들에 기반하고 있고 핵심 인터페이스의 대부분은 HTTP프로토콜에 독립적이다. Struts 2의 Action 클래스들은 프레임웍에 독립적이며 단순 POJO로 보여 질 정도로 단순화되었다. 프레임웍의 컴포넌트들이 느슨하게 결합(loosely coupled)되도록 시도되었다.


2. 단순화된 Action

Action클래스들은 단순한 POJO 이다. 어떤 Java 클래스라도 execute() 메소드만 정의하면 Action클래스로 사용될 수 있다. 또한 인터페이스를 구현하도록 선언할 필요도 없다. Action클래스를 개발할 때 Inversion of Control을 사용할 수 있도록 도입되었으며, 이것은 Action 클래스가 하위에 기반하고 있는 프레임웍으로 부터 중립적일 수 있도록 도와준다.


2-1. POJO (Plain Old Java Object)

자바 객체란 뜻으로 EJB나 Servlet과 같이 컨테이너에 의존하는 것이 아니라 자유롭게 정의할 수 있는 객체라는 의미이다. 일반적으로 POJO 마다 equals(), hashCode(), toString()


POJO 처럼 단순한 코딩을 Action에 사용할 수 있다.

jsp/sevlet 웹 프로그램 만들 수 있음. 자바 콘솔 프로그램안됨

struts1 웹 프로그램 만들 수 있음. 자바 콘솔 프로그램안됨

struts2 웹 프로그램 만들 수 있음. 자바처럼 단순한 프로그램 생성 가능

spring 자바(POJO프로그램) 와 웹 프로그램 둘다 만들 수 있음


3. ActionForm이 없다.

ActionForm과 같은 피쳐들이 Struts 2 에서는 사용되지 않는다. Action클래스에서 JavaBean을 프로퍼티를 바로 사용할 수 있다. 따라서 더 이상 모든 값들을 String 프로퍼티 형태로 사용하지 않아도

된다.


4. Annotation의 도입 < SPRING에서 자세하게 공부!!

Struts 2에서의 어플리케이션은 Java5의 어노테이션을 설정정보를 위해 XML이나 Java properties대신에 사용할 수 있다. 이러한 어노테이션은 XML의 사용량을 최소화 시켜준다.


5 쉬운 Spring 과의 연동

Struts 2의 Action은 이미 Spring에 연동될 수 있도록 되어 있다. Spring의 bean만을 추가하면 된다.


Interceptor는 기존에 사용하던 필터에 해당하는 개념