Saturday, May 18, 2013

Struts 2 - Sample MVC

See project structure.

























Core files -
1 web.xml
2 action classes: Login.java and SearchTicket.java
2 struts xml: login.xml and struts.xml
3 JSP pages: index.jsp, searchTicket.jsp and showTicket.jsp

web.xml

 
 Struts2Demo
 
  index.jsp
 

 
  struts2
  org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
 

 
  struts2
  /*
 



StrutsPrepareAndExecuteFilter deals with all requests and it is responsible for selecting which action to be executed.

index.jsp
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Please login...</title>
</head>
<body>
    <s:form action="login">
        <s:textfield label="User ID" key="userId"></s:textfield>
        <s:password label="Password" key="password"></s:password>
        <s:submit></s:submit>
    </s:form>
</body>
</html>

Once the login form is submitted, OGNL calls setter method of the action to store the values.

Login.java
package com.mqin.struts2.demo.login;

import com.opensymphony.xwork2.Action;

public class Login implements Action {
    private String userId;
    private String password;

    public String execute() throws Exception {
        if (getUserId().equals("James") && getPassword().equals("Bond")) {
            return SUCCESS;
        }
        return ERROR;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}


The business logic is done in execute and return SUCCESS or ERROR to the framework, and since Action class has both business logic and data, it acts like both controller and model.

login.xml


 
 
  
   /searchTicket.jsp
   /index.jsp
  
 



Set struts.devMode to true to get more log information, and it defines the business flow by the result of action, here success and error.

If error, stay at index and if success, go to searchTicket page.

searchTicket.jsp
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Ticket Search</title>
</head>
<body>

    <s:form action="searchTicket">
        <s:textfield label="From" key="fromCity"></s:textfield>
        <s:textfield label="To" key="toCity"></s:textfield>
        <s:submit></s:submit>
    </s:form>

</body>
</html>

Submit the form to action SearchTicket.
package com.mqin.struts2.demo.search;

import com.opensymphony.xwork2.Action;

public class SearchTicket implements Action {
    private String fromCity;
    private String toCity;
    private int ticketNo;

    public String execute() throws Exception {
        if (getFromCity().equals("Adelaide") && getToCity().equals("Melbourne")) {
            setTicketNo(10);            
        }
        return SUCCESS;
    }

    public String getFromCity() {
        return fromCity;
    }

    public void setFromCity(String fromCity) {
        this.fromCity = fromCity;
    }

    public String getToCity() {
        return toCity;
    }

    public void setToCity(String toCity) {
        this.toCity = toCity;
    }

    public int getTicketNo() {
        return ticketNo;
    }

    public void setTicketNo(int ticketNo) {
        this.ticketNo = ticketNo;
    }

}


struts.xml


 

 
  
   /showTicket.jsp
  
 



showTicket.jsp
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Ticket Search Result</title>
</head>
<body>

    <s:property value="ticketNo" />
    tickets found from
    <s:property value="fromCity" />
    to
    <s:property value="toCity" />
    .

</body>
</html>

Please notice that you don't have to specify object.attribute to get the value, that is because object and attribute is decoupled and stored in Value Stack and can be received by OGNL directly.

Execution flow.










No comments:

Post a Comment