Introduction to struts2

osc_bvincwvq 2020-11-10 12:48:15
introduction struts2 struts


Struts2 Introduction to learning notes in detail :

Struts2 Origin and background :

To learn a technology is to understand its history , Know its background The factors that appear … This is my study habit
Once upon a time, there was a framework Struts1
Struts1
For a long time , stay MVC In the framework of absolute dominance … Probably 04 Years! … I just went to kindergarten …
Struts1: It can be realized very well The separation of control and business logic …
But there are also some defects in itself :
The presentation layer is single : Only the presentation layer is supported , Limit Struts1 The development of ;
Yes Servlet APl Dependence : Struts1 Based on the framework of Model2 Pattern development , So it needs to involve a lot of Servlet APl Further to Web Containers create dependencies ;
Not conducive to code reuse :: In code development, in addition to self-defined classes You must also use Struts1 Class in ; The coupling between types is serious !








WebWork
In order to solve such problems , There's a new technology WebWork;
It emphasizes more Loose coupling between systems : Use interceptors to control , So it's no longer dependent on web Containers
Loose coupling , The presentation layer supports more views , Make development more flexible ; But because the propaganda is not high The usage rate is not much … It's not famous !! To improve access Changed the name Struts2 There is ;



Struts2
With WebWork The design idea of the framework is the core , Absorbed Struts 1 Some of the advantages of ;
WebWork + Struts1 = Sturts2
 Insert picture description here


Struts 2 Acquisition

Struts 2 Official address :http://struts.apache.org
This time choose Struts 2.3.16.3 Explain
 Insert picture description here

Struts2 application :

introduce Struts2 Jar

newly build Java Web project , introduce Jar File added to project lib
Struts2 Project basis jar file :

Documentation explain
struts2-core-xxx.jar Struts 2 The core class library of the framework
xwork-core-xxx.jar XWork Class library ,Struts 2 Building foundation
ognl-xxx.jar Struts 2 An expression language class library is used
freemarker-xxx.jar Struts 2 The tag template for the
javassist-xxx.GA.jar Processing bytecode
commons-fileupload-xxx.jar You need to use
commons-io-xxx.jar Java IO Expand
commons-lang-xxx.jar Tool classes that contain some data types
…jar Here's just some basic Jar As the program expands, there are many more jar Keep learning ~

Start the first one Struts2 project :

 Insert picture description here

To configure web.xml

To write web project , Struts2 What the framework needs filter :web.xml ( I like configuration first , It's usually cope)
Be careful :
At present, due to the progress of development tools , There may be some web By default, items will not be displayed web.xml file But it must not have been made by hand ! You can set the tool project version ——myelicpse
 Insert picture description here


web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<!-- Project name -->
<display-name>Struts2</display-name>
<!-- web File specified default access page .. -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- Struts2 filter -->
<!-- effect : Start loading struts.xml file -->
<filter>
<filter-name>struts</filter-name>
<!-- Struts2 Core controller class :
In the early days, it was still :org.apache.struts2.dispatcher.FilterDispatcher
-->
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> <!-- Now? ! -->
</filter>
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>/*</url-pattern> <!-- /*: Any request must go through .. -->
</filter-mapping>
</web-app>

Write page :

This is just a simple study Struts It doesn't deal with databases, access databases or whatever …
Struts It's like learning before SpringMVC equally , It's like a controller Servlet equally Receive page request response result data
( General collocation Hibernate Database interaction is not explained here Welcome to watch the following blog I have explained in detail … );
Here the page uses : JSP


HelloWord.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %> <!-- introduce Struts2 Tag library -->
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<p>${msg }</p> <!-- Just use it directly EL You can't get it ...EL No data in the scope is saved ~ -->
<h1>
<s:property value="msg"/> <!-- Use Struts2 Tag library , You can get the response directly action Data of global variables of ; -->
</h1>
<!-- Forms : name="name" Can be used to pass parameters .. -->
<form action="hello" method="post">
name : <input type="text" name="name"> <input type="submit"value=" Submit ">
</form>
</body>
</html>

To write Action Java class ;( Equivalent to the operation of the controller )

I like to write , Build a bag action package Used to exist exclusively action class ;
Here's the most basic implementation Action Interface mode to achieve , rewrite execute();
According to the return value String Find the corresponding response page …
It's a little bit like Servlet 了 , For a variety of different requests, it is not very convenient to adopt this method , Multiple judgment execution Return to different result pages …
We'll expand a variety of Action Realization way …



HelloWordAction.java

package com.wsm.action;
// Be careful not to pour the wrong package 
import com.opensymphony.xwork2.Action;
/*Action:
* Struts To receive a response in , Requested Java class , amount to " controller "
*
* Global variables :
* Struts For " receive " or " Show " data ;
* It needs to be provided to get/set();
* Receive page information : The variable name should be the same as the form name Same name ;
* Output... To the page : The page can be accessed through : Struts2 expression / Or exist in the scope through EL The expression takes out the progressive data display ;
*/
public class HelloWordAction implements Action {

// Get page form name ;
private String name;
// Variables that will be output to the page ...
private String msg;
//Struts2 It also supports the use of complex data types : aggregate Array object ...
// Implementation method 
@Override
public String execute() throws Exception {

System.out.println(name);
msg="hello:"+name; // Concatenate the information output to the page ;
return "hello"; // return " Logical view name ",struts.xml according to :<result name=" Returned logical view name " > Find the last response page </result>
}
/*
about return " Logical view name "; Action The interface also provides 5 String type static constants :
For more standardized , Specify corresponding " Logical view ";
In fact, it is a common string , There is no special mechanism .. The page specified in logical view should be defined by itself , It's just Struts2 It's a perfect mechanism ;
*/
//get/set
public String getName() {

return name;
}
public void setName(String name) {

this.name = name;
}
public String getMsg() {

return msg;
}
public void setMsg(String msg) {

this.msg = msg;
}
}

Action Interface constant string logical meaning

Constant value Logical meaning
SUCCESS “success” Indicates that the program is processing normally , And return the result of success to the user ;
NONE “none” Indicates that the program is processing normally , But it doesn't return any display to the user …
ERROR “error” Failed to return processing result …
INPUT “input” Indicates that more user input is required for smooth execution
LOGIN “login” Indicates that the user needs to log in correctly to execute successfully

establish Struts2 The configuration file :

Page send request —— after web,xml Filter ——Struts2 The configuration file : Handle ——
Find the corresponding xxaction class After a series of operations, it returns a " Logical view name "—— to Struts2 The configuration file is based on result Find the corresponding response page …;
Be careful : The document must be built in Project Src Under the document , Only when the server is deployed is : WEB-INF/classes In the catalog , In order to get the execution correctly …
It's usually named :struts.xml


struts.xml
stay src Create a new directory named struts.xml The file of

<?xml version="1.0" encoding="UTF-8"?>
<!-- struts.xml Declaration part , The tool is not configured DTD file , Can directly cope Below ... -->
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<!-- struts.xml The root node -->
<struts>
<!-- establish : One default Package name , namespace Namespace "/" It means to find the request in the root directory action.., Inherit struts-default(Struts2 At the bottom ...) Detailed explanation later ...-->
<package name="default" namespace="/" extends="struts-default" >
<!-- action: Used to receive requests for pages , Specify corresponding action Class to perform ...(package You can configure multiple )
name: According to the page request according to name Find the designated action class: Specify for action java Class to execute ;
-->
<action name="hello" class="com.wsm.action.HelloWordAction" >
<result name="hello" >/HelloWord.jsp</result> <!-- according to xxxaction class , The returned logical view name specifies the response page for ... -->
<!-- If not specified name The default value is success, therefore action returu "success"; You don't specify name -->
</action>
</package>
</struts>

Struts2 Using objects to receive user input data / visit Servlet Apl

Use Struts2 Implement login function :

Expand on the previous project …
 Insert picture description here

Extending an entity class ( Object data transfer );

User .Java

package com.wsm.entity;
public class User {

// attribute 
private String userName;
private String userPwd;
// No arguments structure 
public User(){
};
// Belt structure 
public User(String userName, String userPwd) {

super();
this.userName = userName;
this.userPwd = userPwd;
}
//get/set
public String getUserName() {

return userName;
}
public void setUserName(String userName) {

this.userName = userName;
}
public String getUserPwd() {

return userPwd;
}
public void setUserPwd(String userPwd) {

this.userPwd = userPwd;
}
}

Login required login page ;

login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<form action="login" method="post">
<!-- For object type , Read through action Class : Object name . attribute Read the assignment -->
name <input type="text" name="user.userName"> <!-- For attribute names, use and Java Class consistency And case sensitive -->
password <input type="text" name="user.userPwd" >
<input type="submit" value=" Submit ">
</form>
<!-- Because the controller request Login failure information is stored in ,EL Expression view ~ -->
<p>${shibai }</p>
</body>
</html>

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<p> Login successful !${user.userName }</p>
</body>
</html>

Logon action And struts2 visit ServletApl object ;

struts2 visit ServletApl object

stay Struts2 It was introduced in the overview that , Struts2 Of Action With no ServletApl Send coupling ; So it can be realized easily Action Test of ;
But in web Development process , The need to use ServletApl Objects in the ;
Struts2 There are many ways to implement ServletApl The interview of :( Two categories: )

Decoupling mode operation ServletAPl object Two implementations ( The following example is a form of decoupling ) ;

  1. Use ActionContext Class gets ServletApl object (Map object )
    Struts2 The framework uses normal Map The object replaced :HttpServletRequest HttpSession ServletContext …
    Action Class , You can easily get the corresponding Map An alternative to type , The decoupling form is realized …
    The scope object is obtained by decoupling , The following code example


  2. Action Class implements a specific interface to implement ServletApl object ; ( In other words, the injection method is used to realize )
    benefits : This approach facilitates unit testing , because ActionContext It needs to be initialized with the help of a framework , This method does not need to be initialized directly to obtain and use …
    The following example

Action Class implements a specific interface to implement ServletApl object ServletAction.java

package com.wsm.action;
// Pay attention to import the corresponding package ~
import java.util.Map;
import org.apache.struts2.interceptor.ApplicationAware;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.SessionAware;
import com.opensymphony.xwork2.Action;
public class ServletAction implements Action, RequestAware,SessionAware,ApplicationAware {

// Note that what is defined here is also a Action;
// It's just for you to know , You can implement the corresponding interface by , Decouple to get the corresponding Servlet object , So there is no specific implementation function ... Don't confuse ~
// Custom decoupled scoped objects ;
Map request;
Map session;
Map application;
//action: Method of implementation .. It's not used here. I don't introduce it in detail ...
@Override
public String execute() throws Exception {

// TODO Auto-generated method stub
return null;
}
// Implement the corresponding method , Each interface has only one implementation method (); The user returns the corresponding Map type , Simulate scope objects ;
@Override
public void setApplication(Map<String, Object> appliction) {

this.application = appliction;
}
@Override
public void setSession(Map<String, Object> session) {

this.session = session;
}
@Override
public void setRequest(Map<String, Object> request) {

this.request = request;
}
}

Coupled mode operation ServletAPl object ;
Direct access Servlet API Will make Action Class and Servlet API Couple together ;
Servlet API The objects are all made up of Servlet Containers to construct , Bind to these objects , There must be Servlet Containers , It's not convenient to Action Class testing
But sometimes , You really need to access these objects ,Struts2 It also provides direct access to ServletAPI How objects work .
To get directly to Servlet API Object can be used org.apache.struts2.ServletActionContext class , This category is ActionContext Subclasses of classes .
// Guide pack
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;









HttpServletRequest request=ServletActionContext.getRequest(); // obtain requset
ServletContext application=ServletActionContext.getServletContext(); // obtain appliction
HttpSession session=request.getSession(); // according to requset obtain session;
In addition to direct use ServletActionContext To get Servlet Apl object ; You can also inject ServletApl object ... omitted ;


LoginAction.java

package com.wsm.action;
// Be careful not to pour the wrong package 
import java.util.Map;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.wsm.entity.User;
public class LoginAction implements Action {

// Global variables 
public User user; // object type , Page passing Object name . Property name Can be read ...
// The scope object is obtained by decoupling 
ActionContext ac = ActionContext.getContext();
Map<String,Object> request = (Map<String,Object>)ac.get("request"); // obtain request
Map<String,Object> session = ac.getSession(); // obtain session
Map<String,Object> appliction = ac.getApplication(); // obtain appliction
@Override
public String execute() throws Exception {

// Verify login success / Failure ! admin 123
if("admin".equals(user.getUserName()) && "123".equals(user.getUserPwd()) ){

// Login successful ! Users save session
session.put("user",user);
return "index";
}
// Go to request Store failure information ;
request.put("shibai"," Login failed ");
return "login"; // Failure back to login page ~
}
//get/set
public User getUser() {

return user;
}
public void setUser(User user) {

this.user = user;
}
}

action It's all written , Finally, don't forget struts2 Configuration file for !

I won't write it all … Directly in package Add a group of action that will do ~
struts.xml

<action name="login" class="com.wsm.action.LoginAction" >
<result name="index" >/index.jsp</result>
<result name="login" >/login.jsp</result>
</action>

Struts2 data verification :

For one web In terms of application , All user data is through the browser , Collected ;
The user's input information is very complex and changeable , If in the process : Hardware device / The Internet / User malicious damage … Input information may cause program exception …
For this kind of problem Applications need to be able to , Handling exception input …
The usual way is , Control layer found exception , Go back directly to the browser , Prompt abnormal user must re-enter legal …
For this operation , Can pass Struts2 Data validation mechanism , To improve the …
Use Struts2 Data verification of , action Classes will no longer be implemented by Action Interface to implement .. But through inheritance ActionSupport Class to improve data validation operations
ActionSupport class
It's a default Action Implementation class of interface .
This class provides many default methods : International Information data verification User requests are processed by default … Other methods ;
because ActionSupport class yes Struts2 The default implementation class . therefore Struts.xml in < action > You don't specify class attribute
ActionSupport Class validate() Realize data verification , So we need to rewrite …









Add non null validation to user login operations :

Need modification LoginAction
LoginAction.java

package com.wsm.action;
// Be careful not to pour the wrong package 
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.wsm.entity.User;
public class LoginAction extends ActionSupport {
 // Inherit ActionSupport
// Global variables 
public User user; // object type 
// The scope object is obtained by decoupling 
ActionContext ac = ActionContext.getContext();
Map<String,Object> request = (Map<String,Object>)ac.get("request"); // obtain request
Map<String,Object> session = ac.getSession(); // obtain session
Map<String,Object> appliction = ac.getApplication(); // obtain appliction
@Override
public String execute() throws Exception {

// Verify login success / Failure ! admin 123
if("admin".equals(user.getUserName()) && "123".equals(user.getUserPwd()) ){

// Login successful ! Users save session
session.put("user",user);
return "index";
}
// Go to request Store failure information ;
request.put("shibai"," Login failed ");
return "login"; // Failure back to login page ~
}
// rewrite validate(); Data validation methods ;
@Override
public void validate() {

if(user.getUserName().length()==0){

super.addFieldError("username", " The username cannot be empty ");
}
if(user.getUserPwd().length()==0){

super.addFieldError("userpwd", " The password cannot be empty ");
}
}
/*
When the page , Send a request , Find the right one action when , The first entry is validate(); Method for data validation ..
If during the validation process addFieldError(); Added validation information , Then you won't be entering execute(); Method ;
But directly back to a "input" Logical view name , Go to struts.xml Find the specified page ...
So be sure to be in struts.xml Corresponding action Configure a... In the tag : <result name="input" > Response page </result>
The page can be accessed by :Struts2 Tag, check exception information display ..
*/
//get/set
public User getUser() {

return user;
}
public void setUser(User user) {

this.user = user;
}
}

struts.xml

 <action name="login" class="com.wsm.action.LoginAction" >
<result name="index" >/index.jsp</result>
<result name="login" >/login.jsp</result>
<result name="input" >/login.jsp</result> <!-- input: Indicates that the data is abnormal and returns to the login page ; -->
</action>

Modify the page to display the verification results :login.jsp

Be careful : Don't forget to import <%@ taglib prefix=“s” uri="/struts-tags" %> < !-- Struts2 Tag library -->
Can pass <s:fielderror></s:fielderror> Display abnormal data information …

%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %> <!-- Struts2 Tag library -->
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<!-- Data validation abnormal information output display .. -->
<div>
<s:fielderror></s:fielderror>
</div>
<form action="login" method="post">
<!-- For object type , Read through action Class : Object name . attribute Read the assignment -->
<!-- For attribute names, use and Java Class consistency And case sensitive -->
name <input type="text" name="user.userName"> <s:fielderror fieldName="username" ></s:fielderror> <!-- according to fieldName Specifies to display the exception information .. -->
<hr/>
password <input type="text" name="user.userPwd" > <s:fielderror fieldName="userpwd" ></s:fielderror>
<input type="submit" value=" Submit ">
</form>
<!-- Because the controller request Login failure information is stored in ,EL Expression view ~ -->
<p>${shibai }</p>
</body>
</html>

Struts2 label :

Struts2 Provides a lot of powerful tag libraries in , And far beyond the basic functions of the traditional tag library :( The above verification information is a kind of …)
There are two main categories :UI label Universal label
You need to import Struts2 Tag library : <%@ taglib prefix=“s” uri="/struts-tags" %>

UI label

UI Labels can be divided into three categories : Form labels Non form labels Ajax label

Struts2 Common form tags :

label explain
<s:form>…</s:form> Form labels
<s:textfield>…</s: textfield> Text input box
<s:password>…</s: password> Password input box
<s:textarea>…</s: textarea> Text field input box
<s:radio>…</s: radio> Radio button
<s:checkbox>…</s: checkbox> Checkbox
<s:submit/> Submit tags
<s:reset/> Reset tag
<s:hidden/> Hide field tags
<s:actionerror/> Show Action error
<s:actionmessage/> Show Action news
<s:fielderror/> Display field error , Output addFieldError("",""); Stored information … Commonly used in data verification !

These tags will be used by browsers , Translation load run , Maybe with a kind of <table/><tr/><td/> Form packaging output …
This is a Struts2 The default format for : Can be in struts.xml Modify its default style :

<struts>
<!-- Set user interface defaults XHTML style :value=" Value optional .." -->
<constant name="struts.ui.thems" value="simple" />
</struts>

Universal label

Struts2 UI Tags are mainly used for view design , In the process of view design, there are always some Business control behavior ;
eg: Judge Action Whether the set read in is empty , On the assembly Traverse !

Struts2 Common universal tags :

 Insert picture description here

if/else if/else label
All three are conditional judgments Branch control label , It's almost like Java similar :

Of the three tags, only <s:if /> Can be used alone
<s:elseif /> <s:else /> You can talk to <s:if /> Use it with , But it can't be used alone !
 Insert picture description here

iterator Iteration tags
 Insert picture description here

example Demo

Login successful , Query all user information, traverse , And change color every other line
modify LoginAction.java

// modify execute();
@Override
public String execute() throws Exception {

// Verify login success / Failure ! admin 123
if("admin".equals(user.getUserName()) && "123".equals(user.getUserPwd()) ){

// Login successful ! Users save session
session.put("user",user);
// Store a few users , Simulation query , Test page struts2 Tag library , Don't forget to add a parameter constructor to the entity class (name,pwd);
List<User> users = new ArrayList<User>();
users.add(new User(" Zhang San 1", "123"));
users.add(new User(" Zhang San 2", "123"));
users.add(new User(" Zhang San 3", "123"));
users.add(new User(" Zhang San 4", "123"));
request.put("users",users);
return "index";
}
// Go to request Store failure information ;
request.put("shibai"," Login failed ");
return "login"; // Failure back to login page ~
}

index.jsp Page output :

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<p> Login successful !${user.userName }</p>
<!-- s:iterator: Iterate through , obtain request Data in the ! Have been requset In fact, it can also be used directly JSTL 了 .. It feels like chicken ribs ... -->
<s:iterator var="user" value="#request.users" status="status">
<!-- Judge the color of the element subscript -->
<s:if test="#status.index % 2==0">
<div style="background-color: red">
<s:property value="#user.userName"/>---<s:property value="#user.userPwd"/>
</div>
</s:if>
<s:else>
<div style="background-color: blue;">
<s:property value="#user.userName"/>---<s:property value="#user.userPwd"/>
</div>
</s:else>
</s:iterator>
</body>
</html>

Finally finished , Thank you for watching. , The interlaced color of the last example is a bit ugly , Don't suggest ~


版权声明
本文为[osc_bvincwvq]所创,转载请带上原文链接,感谢

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云