Поддержка аннотаций в Struts 2 - PullRequest
2 голосов
/ 24 апреля 2009

Я сейчас оцениваю Struts 2. Официальная документация содержит пример HelloWorld со следующим кодом Java и JSP:

Java

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorld extends ActionSupport {

    public static final String MESSAGE = "Struts is up and running ...";

    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;
    }
}

JSP

<%@ taglib prefix="s" uri="/struts-tags" %>

<html>
    <head>
        <title>Hello World!</title>
    </head>
    <body>
        <h2><s:property value="message" /></h2>
    </body>
</html>

В этом примере используется следующий XML-файл для указания URL-адреса для этого действия, а также для связывания действия и просмотра вместе

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <package name="tutorial" extends="struts-default">
        <action name="HelloWorld" class="tutorial.HelloWorld">
            <result>/HelloWorld.jsp</result>
        </action>
    </package>
</struts>

Мой вопрос (наконец-то) таков: действительно ли это новейшее состояние для Struts2? Я был убежден, что необходимость в конфигурации XML и создании подклассов определенного базового класса (ActionSupport) устарела. Я думал, что аннотации можно использовать для конфигурации.

Пара более конкретных вопросов:

  • Необходимо ли иметь один класс Action для каждого типа запроса или можно определить несколько методов в действии, каждый из которых может обрабатывать разные запросы?
  • Необходимо ли определять общедоступный метод получения и установки для элементов данных, которые вы хотите сделать доступными для представления («сообщение» в примере выше)?

Если это состояние уровня Struts2, то это не похоже на улучшение по сравнению с Struts1, но я подозреваю, что это просто плохой пример.

Спасибо, Дон

Ответы [ 3 ]

1 голос
/ 24 апреля 2009

Пример - стойки в старом стиле2. Вы можете использовать аннотации практически для всего, как говорит @pgb.

Существует также 2 различных стиля конфигурации; один называется «условное обозначение», а другой - «аннотация». На соглашение влияют рельсы, и он создает привязки по умолчанию между действиями и результатами по пути / имени. Используя аннотации, вы объявляете все, как вы делали с xml, но только внутри класса контроллера. Я считаю, что оба являются большими упрощениями, и в настоящее время я использую только крошечный XML-файл для большого сайта.

1 голос
/ 26 апреля 2009

Извините за отсутствующие ресурсы, но я не могу скопировать и вставить их сюда.

Но это должно дать вам представление о возможностях 2.1.x.

struts.xml:

<!DOCTYPE struts PUBLIC 
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <!-- Include webwork default (from the Struts JAR). -->
    <include file="struts-default.xml"/>
    <!-- Configuration for the default package. -->
    <package name="default" extends="struts-default">
        <interceptors>
            <interceptor name="appLogin" class="us.pdinc.client.com.usgoldnetwork.support.struts.LoginInterceptor" />   
            <interceptor-stack name="loginStack">
                <interceptor-ref name="appLogin"/>
                <interceptor-ref name="paramsPrepareParamsStack"/>
            </interceptor-stack>
        </interceptors>     
        <!-- Default interceptor stack. -->
        <default-interceptor-ref name="loginStack"/>        
        <global-results>
            <result name="login">/WEB-INF/jsp/login-input.jsp</result>
        </global-results>
    </package>
</struts>
<!--  http://struts.apache.org/2.1.6/docs/convention-plugin.html  -->

struts.properties:

struts.custom.i18n.resources=guest
struts.convention.result.path=/WEB-INF/jsp
struts.ognl.allowStaticMethodAccess=true

AddrAction.java

    package us.pdinc.client.com.usgoldnetwork.action;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.hibernate.Session;
import org.hibernate.Transaction;

import us.pdinc.client.com.usgoldnetwork.beans.model.hibernate.Addr;
import us.pdinc.client.com.usgoldnetwork.beans.model.hibernate.AddrType;
import us.pdinc.client.com.usgoldnetwork.beans.model.hibernate.Tx;
import us.pdinc.client.com.usgoldnetwork.servlet.support.RequestScopeHibernateSession;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;

@Results({
      @Result(name="list", type="redirect", location="/addr", params={"transaction.id","${transaction.id}"})
    })
public class AddrAction extends ActionSupport implements Preparable , ServletRequestAware 
{
    private static final long serialVersionUID = 1L;

    private List<Addr> addrs;
    private List<AddrType> addrTypes;
    private List<Tx> txs;
    private Addr addr;
    private AddrType addrtype;
    private HttpServletRequest httpServletRequest;
    private Tx transaction;
    long txId = 0;

    @Override
    public void prepare() throws Exception
    {
        if (addr!=null && addr.getId()!=null) 
            {
                Session session = RequestScopeHibernateSession.getSession(httpServletRequest);
                addr=(Addr) session.get(Addr.class, addr.getId());
            }
    }

    public String index()
    {
        return list();
    }

    public String list()
    {
        System.out.println("LIST");
        if (transaction==null)throw new RuntimeException();
        if (transaction.getId()==null) throw new RuntimeException();
        if (transaction.getId()<=0) throw new RuntimeException();
        Session session = RequestScopeHibernateSession.getSession(httpServletRequest);
        transaction=(Tx)session.get(Tx.class, transaction.getId());
        addrs=transaction.getAddrs();

        return SUCCESS;
    }

    public String input() 
    {
        Session session = RequestScopeHibernateSession.getSession(httpServletRequest);
        addrTypes=session.createCriteria(AddrType.class).list();
        //txs = session.createCriteria(Tx.class).list();
        return INPUT;
    }

    public String save() 
    {
        System.out.println("SAVE");

        if(transaction != null && transaction.getId() != null){
            txId = transaction.getId();
        }
        if(addr != null && addr.getTx() != null && addr.getTx().getId() != null){
            txId = addr.getTx().getId();
        }
        /*if (transaction==null || addr == null)throw new RuntimeException();
        System.out.println("******************************************************************");
        System.out.println("Transaction value ==" + transaction);
        System.out.println("Addr value ==" + addr);
        if (addr.getTx() == null) throw new RuntimeException();
        System.out.println("Transaction ID value ==" + transaction.getId());
        System.out.println("Addr Transaction value ==" + addr.getTx());
        if ( addr.getTx().getId() == null ) throw new RuntimeException();
        System.out.println("********************************************************************");
        System.out.println("Addr Transaction ID value ==" + addr.getTx().getId());*/

        Session session = RequestScopeHibernateSession.getSession(httpServletRequest);
        transaction=(Tx)session.get(Tx.class, txId);
        //String addrTypeId = httpServletRequest.getParameter("addr.addrType.id");
        //Long Id = Long.valueOf(addrTypeId);
        addrtype=(AddrType) session.get(AddrType.class, addr.getAddrType().getId());
        if (addr.getId()==null)
        {   
            System.out.println("Addr is null");
            addr.setTx(transaction);
            addr.setAddrType(addrtype);
            Transaction tx = session.getTransaction();
            tx.begin();
            session.save(transaction);
            session.persist(addr);
            tx.commit();
        }
        else
        {
            System.out.println("Addr is not null");
            Transaction tx = session.getTransaction();
            tx.begin();
            session.update(addr);
            tx.commit();        
        }
        return "list";
    }



    public String delete() 
    {
        Session session = RequestScopeHibernateSession.getSession(httpServletRequest);
        Transaction tx = session.getTransaction();
        tx.begin();
        session.delete(session.get(Addr.class, addr.getId()));
        tx.commit();        
        return "list";
    }


    @Override
    public void setServletRequest(HttpServletRequest arg0)
    {
        httpServletRequest=arg0; 
    }

    public Addr getAddr()
    {
        return addr;
    }

    public void setAddr(Addr addr)
    {
        this.addr = addr;
    }

    public List<Addr> getAddrs()
    {
        return addrs;
    }

    public List<AddrType> getAddrTypes()
    {
        return addrTypes;
    }

    public List<Tx> getTxs()
    {
        return txs;
    }

    public Tx getTransaction() {
        return transaction;
    }

    public void setTransaction(Tx transaction) {
        this.transaction = transaction;
    }

}

addr.jsp:

<%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <link href="<s:url value='/css/main.css'/>" rel="stylesheet" type="text/css"/>
    <title>Addresses Screen</title>
       <jsp:include page = "barcodeextractor.jsp" />
</head>
<body>
<div class="titleDiv">USGN Core Process</div>
<h1>Addresses</h1>
<s:url id="url" action="addr!input" >
<s:param name="transaction.id" value="transaction.id" />
</s:url>
<a href="<s:property value="#url"/>">Add New Address</a>
<br/><br/>
<table class="borderAll">
    <tr>
        <th>Customer</th>
        <th>Name</th>
        <th>Type</th>
        <th>Street 1</th>
        <th>Street 2</th>
        <th>Street 3</th>
        <th>Street 4</th>
        <th>Street 5</th>
        <th>Street 6</th>
        <th>City</th>
        <th>State</th>
        <th>Postal</th>
        <th>Country</th>
        <th>&nbsp;</th>
    </tr>
    <s:iterator value="addrs" status="status">
        <tr class="<s:if test="#status.even">even</s:if><s:else>odd</s:else>">
            <td class="nowrap"><s:property value="tx.id"/></td>
            <td class="nowrap"><s:property value="name"/></td>
            <td class="nowrap"><s:property value="addrType.addrType"/></td>
            <td class="nowrap"><s:property value="street1"/></td>
            <td class="nowrap"><s:property value="street2"/></td>
            <td class="nowrap"><s:property value="street3"/></td>
            <td class="nowrap"><s:property value="street4"/></td>
            <td class="nowrap"><s:property value="street5"/></td>
            <td class="nowrap"><s:property value="street6"/></td>
            <td class="nowrap"><s:property value="city"/></td>
            <td class="nowrap"><s:property value="state"/></td>
            <td class="nowrap"><s:property value="postal"/></td>
            <td class="nowrap"><s:property value="country"/></td>
            <td class="nowrap">
                <s:url action="addr!input" id="url">
                    <s:param name="addr.id" value="id"/>
                </s:url>
                <a href="<s:property value="#url"/>">Edit</a>
                &nbsp;&nbsp;&nbsp;
                <s:url action="addr!delete" id="url" >
                    <s:param name="addr.id" value="id"/>
                </s:url>
                <a href="<s:property value="#url"/>">Delete</a>
            </td>
        </tr>
    </s:iterator>
    </table>
</body>
</html>

адр-Input.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<s:if test="addr==null || addr.id == null">
    <s:set name="title" value="%{'Add new contact type'}"/>
</s:if>
<s:else>
    <s:set name="title" value="%{'Update contact type'}"/>
</s:else>

<html>
<head>
    <link href="<s:url value='/css/main.css'/>" rel="stylesheet" type="text/css"/>
    <style>td { white-space:nowrap; }</style>
    <title><s:property value="#title"/></title>
     <jsp:include page = "barcodeextractor.jsp" />
</head>
<body>
<div class="titleDiv">USGN Core Process</div>
<h1><s:property value="#title"/></h1>
<s:actionerror />
<s:actionmessage />
<s:form action="addr!save" method="post">
    <s:select name="addr.addrType.id" label="Address Type" list="addrTypes" listKey="id" listValue="addrType" value="%{addr.addrType.id}"/>
    <s:textfield name="addr.name" value="%{addr.name}" label="Name" size="40"/>
    <s:textfield name="addr.street1" value="%{addr.street1}" label="Street 1" size="40"/>
    <s:textfield name="addr.street2" value="%{addr.street2}" label="Street 2" size="40"/>
    <s:textfield name="addr.street3" value="%{addr.street3}" label="Street 3" size="40"/>
    <s:textfield name="addr.street4" value="%{addr.street4}" label="Street 4" size="40"/>
    <s:textfield name="addr.street5" value="%{addr.street5}" label="Street 5" size="40"/>
    <s:textfield name="addr.street6" value="%{addr.street6}" label="Street 6" size="40"/>
    <s:textfield name="addr.city" value="%{addr.city}" label="City" size="40"/>
    <s:textfield name="addr.state" value="%{addr.state}" label="State" size="40"/>
    <s:textfield name="addr.postal" value="%{addr.postal}" label="Postal" size="40"/>
    <s:textfield name="addr.country" value="%{addr.country}" label="Country" size="40"/>
    <s:hidden name="addr.id" value="%{addr.id}"/>
    <s:hidden name="transaction.id" value="%{transaction.id}"/>
    <s:submit value="Submit"/>
    <s:submit value="Cancel" name="redirectAction:addr!list"/>
</s:form>
</body>
</html>
1 голос
/ 24 апреля 2009

Некоторые ответы (не все):

  • Вы можете добавить несколько методов к одному и тому же классу Action. Каждому из них нужно вернуть строку.
  • Я думаю, что нужен общественный геттер и сеттер.
  • Предоставленный базовый класс определяет только определенные полезные значения, такие как константа SUCCESS.

Вы можете использовать аннотации с помощью функции «Нулевая конфигурация» ( ноль конф. Документ )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...