Java后台处理框架之struts2学习总结

最近我在网上了解到,在实际的开发项目中struts2的使用率在不断降低,取而代之的是springMVC。可能有很多的朋友看到这里就会说,那还不如不学struts2,直接学习springMVC算了。如果你急于忙着开发项目,这个想法没错。但是,我在这里想说一下的就是,框架其实是对基础代码的封装,对流行功能的优化,为了提高开发效率而存在的。好比武林大会上降龙十八掌,金钟罩,铁布衫,说到底大家还是要靠拳打脚踢的嘛。Struts2,springMVC就是各种招式,我们学习它,学的是招式,以便于更好的见招拆招。闲话不多扯,我来对我这几天的struts2学习做一次总结。

1.struts2防重复提交。

首先要在jsp提交页面导入<%@taglib prefix="s" uri="/struts-tags" %>

在这里有两种方法:一个是在要提交的表单里面嵌入标签<s:token></s:token>,如下:

<s:actionerror/><!--提示错误信息-->

<form action="student" method="post" >

<s:token></s:token>

姓名:<input type="text" name="student.name"/><br/>

年龄:<input type="text" name="student.age"/><br/>

<input type="submit" value="提交"/>

</form>

接着,在项目src下配置struts.xml如下:

<package name="main" extends="struts-default">

<action name="student" class="action.StudentAction" method="add">

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

<result name="invalid.token">/student.jsp</result><!--令牌提醒重复提交-->

<interceptor-ref name="token"></interceptor-ref>

<interceptor-ref name="defaultStack"></interceptor-ref>

</action>

</package>

另一种方法是:直接在struts.xml中配置为无视重复提交(推荐使用这种方法),如下

<package name="main" extends="struts-default">

<action name="student" class="action.StudentAction" method="add">

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

<interceptor-ref name="tokenSession"></interceptor-ref><!--无视重复提交-->

<interceptor-ref name="defaultStack"></interceptor-ref>

</action>

</package>

2.struts2过滤敏感词汇。比如在进行用户注册时,对用户提交的姓名进行过滤。

假如有个提交页面:

<s:form action="/validationAction" method="post">

<s:textfield name="name" label="姓名"></s:textfield>

<s:submit value="提交"></s:submit>

</s:form>

提交之后,在struts.xml(src直接目录下)中找到配置,

<package name="manager" extends="struts-default">

<action name="validationAction" class="action.ValidationAction">

<result name="input">/validation.jsp</result><!-- 错误,内部返回的是input-->

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

</action>

</package>

此时,在包action下找到ValidationAction.java里面代码如下:

package action;

import java.util.Map;

import org.apache.struts2.components.ActionComponent;

import com.opensymphony.xwork2.ActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class ValidationAction extends ActionSupport{

/**

*

*/

private static final long serialVersionUID = 1L;

private String name;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@Override

public String execute() throws Exception {

ActionContext actionComtext=ActionContext.getContext();

Map<String, Object> session=actionComtext.getSession();

session.put("name", name);

System.out.println("姓名:"+name);

return SUCCESS;

}

}

配置文件为ValidationAction-validation.xml(不可随便命名,格式为xx-validation.xml),代码如下:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">

<validators>

<field name="name">

<field-validator type="requiredstring"><!-- 系统自带验证是否为空-->

<message>请输入姓名</message>

</field-validator>

<field-validator type="sensitive"><!-- 自定义验证。注意此文件是validationAction的配置文件,命名格式一定得为xx-validation.xml,前面的xx一定要和上面的验证validationAction一致 -->

<message>有敏感词汇</message><!-- 此处的自定义验证名为sensitive,自动到validators.xml中去找 -->

</field-validator>

</field>

</validators>

在上面的配置中,我们自定义了一个sensitive验证,在src目录下与struts平级的还得有一个配置文件validators.xml,代码如下:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE validators PUBLIC

"-//Apache Struts//XWork Validator Config 1.0//EN"

"http://struts.apache.org/dtds/xwork-validator-config-1.0.dtd">

<validators>

<validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>

<validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>

<validator name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/>

<validator name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/>

<validator name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/>

<validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/>

<validator name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/>

<validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/>

<validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/>

<validator name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/>

<validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/>

<validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/>

<validator name="regex" class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/>

<validator name="conditionalvisitor" class="com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator"/>

<!-- 下面的为自定义验证,上面的是系统验证 -->

<validator name="sensitive" class="validators.SensitiveWordValidators"/>

</validators>

根据此配置找到包validators下的SensitiveWordValidators.java,代码如下:

package validators;

import com.opensymphony.xwork2.validator.ValidationException;

import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport;

public class SensitiveWordValidators extends FieldValidatorSupport{

@Override

public void validate(Object object) throws ValidationException {

String fieldName=this.getFieldName();

String value=this.getFieldValue(fieldName, object).toString();//获取输入值

if(!check(value)){

this.addFieldError(fieldName, object);//返回页面提示有敏感词汇(此句话在ValidationAction-validation.xml中)

}

}

public boolean check(String value){

String sensitiveWords[]={"操","你妈","屌","尼玛","日","cao","艹"}; for(int i=0;i<sensitiveWords.length;i++){

if(value.indexOf(sensitiveWords[i])!=-1){

return false;

}

}

return true;

}

}

执行到这里之后,如果有敏感词汇,则直接返回页面提示有敏感词汇。没有敏感词汇的话,则跳转到success.jsp页面。(struts.xml中可知道)

3.Struts2实现文件上传与下载。Struts2实现文件上传是基于拦截器实现的,使用的是fileupload,文件上传大小、类型控制是在struts.xml中配置(src目录下),默认上传最大为2M。

首先来总结单文件上传:假如有个上传页面,如下

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

pageEncoding="UTF-8"%>

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

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

<s:fielderror></s:fielderror><!-- 提示上传 错误信息 -->

<form action="upload" method="post" enctype="multipart/form-data">

文件:<input type="file" name="java1234"/><br/>

<input type="submit" value="提交"/>

</form>

</body>

</html>

struts.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>

<package name="manager" extends="struts-default">

<action name="upload" class="action.FileUploadAction">

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

<result name="input">/fileupload.jsp</result>

<!-- <interceptor-ref name="fileUpload">用来进行上传文件限制,只能为图片和大小不超过81101b

<param name="allowedTypes">image/bmp,image/x-png,image/gif,image/jpg,image/jpeg</param>

<param name="maximumSize">81101</param>

</interceptor-ref>

<interceptor-ref name="defaultStack"></interceptor-ref> -->

</action>

</package>

</struts>

在action包下找到FileUploadAction.java,代码如下:

package action;

import java.io.File;

import org.apache.commons.io.FileUtils;

import com.opensymphony.xwork2.ActionSupport;

public class FileUploadAction extends ActionSupport {

/**

*

*/

private static final long serialVersionUID = 1L;

private File java1234;// 文件

private String java1234FileName;//文件名,格式为提交页面name(java1234)+FileName

private String java1234ContentType;// 文件类型。格式为提交页面name(java1234)+ContentType

public File getJava1234() {

return java1234;

}

public void setJava1234(File java1234) {

this.java1234 = java1234;

}

public String getJava1234FileName() {

return java1234FileName;

}

public void setJava1234FileName(String java1234FileName) {

this.java1234FileName = java1234FileName;

}

public String getJava1234ContentType() {

return java1234ContentType;

}

public void setJava1234ContentType(String java1234ContentType) {

this.java1234ContentType = java1234ContentType;

}

@Override

public String execute() throws Exception {

System.out.println("文件名:" + java1234FileName);

System.out.println("文件类型:" + java1234ContentType);

String filePath="E:/"+java1234FileName;

File savePath=new File(filePath);

FileUtils.copyFile(java1234, savePath);

return SUCCESS;

}

}

上传成功则跳转到success.jsp页面,失败则继续留在原界面(struts.xml可知)

其次来总结多文件上传:多文件上传和单文件上传不同之处便是FileUploadAction.java中用数组来处理文件。代码如下:

package com.java1234.action;

import java.io.File;

import org.apache.commons.io.FileUtils;

import com.opensymphony.xwork2.ActionSupport;

public class FilesUploadAction extends ActionSupport{

/**

*

*/

private static final long serialVersionUID = 1L;

private File[] java1234; // 文件

private String[] java1234FileName;  // 文件名

private String[] java1234ContentType;  // 文件类型

public File[] getJava1234() {

return java1234;

}

public void setJava1234(File[] java1234) {

this.java1234 = java1234;

}

public String[] getJava1234FileName() {

return java1234FileName;

}

public void setJava1234FileName(String[] java1234FileName) {

this.java1234FileName = java1234FileName;

}

public String[] getJava1234ContentType() {

return java1234ContentType;

}

public void setJava1234ContentType(String[] java1234ContentType) {

this.java1234ContentType = java1234ContentType;

}

@Override

public String execute() throws Exception {

for(int i=0;i<java1234.length;i++){

System.out.println("文件名:"+java1234FileName[i]);

System.out.println("文件类型:"+java1234ContentType[i]);

String filePath="C:/"+java1234FileName[i];

File saveFile=new File(filePath);

FileUtils.copyFile(java1234[i], saveFile);

}

return SUCCESS;

}

}

最后来总结文件下载:返回的是一个文件流

假如有个下载页面如下:

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

pageEncoding="UTF-8"%>

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

<!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>Insert title here</title>

</head>

<body>

<a href="download">文件下载</a>

</body>

</html>

struts.xml中配置为:

<package name="manager" extends="struts-default">

<action name="download" class="action.FileDownloadAction">

<result type="stream"><!-- 前面处理返回的是InputStream -->

<param name="contentDisposition">attachment;filename=${fileName}</param>

</result>

</action>

</package>

根据配置找到action包下面的FileDownloadAction.java,代码如下:

package action;

import java.io.File;

import java.io.FileInputStream;

import java.io.InputStream;

import com.opensymphony.xwork2.ActionSupport;

public class FileDownloadAction extends ActionSupport{

/**

*

*/

private static final long serialVersionUID = 1L;

private String fileName;

public String getFileName() throws Exception{

fileName=new String(fileName.getBytes(),"ISO8859-1");//解决乱码      return fileName;

}

public void setFileName(String fileName) {

this.fileName = fileName;

}

public InputStream getInputStream()throws Exception{

File file=new File("C:/美女1.jpg");//假设下载的为此文件

this.fileName="美女1号";//自己定义下载的文件名字,系统会补上文件后缀名无需自己添加

return new FileInputStream(file);//和上传不同,返回的是一个InputStream

}

}

4.struts2实现国际化。什么意思呢,就是根据浏览器语言环境,显示不同语言网页。不同国家地区访问网站,给出相应版本语言的网页。

直接先贴出struts.xml配置文件(src目录下)。如下:

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

<!-- struts配置支持多语言,根据浏览器环境 -->

<constant name="struts.custom.i18n.resources" value="java1234"></constant>

<!--注意上面的value="java1234",后面的默认properties文件也要java1234此名字-->

</struts>

假如有这么一个登录网页和欢迎界面:注意<s:text name="xx"></s:text>

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

pageEncoding="UTF-8"%>

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

<!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>Insert title here</title>

</head>

<body>

<table>

<tr>

<td><s:text name="userName"></s:text></td>

<td>

<input type="text"/>

</td>

</tr>

<tr>

<td><s:text name="password"></s:text></td>

<td>

<input type="text"/>

</td>

</tr>

<tr>

<td>

<input type="button" value="<s:text name=‘login‘></s:text>"/>

</td>

</tr>

</table>

</body>

</html>

欢迎网页:

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

pageEncoding="UTF-8"%>

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

<!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>Insert title here</title>

</head>

<body>

<s:text name="welcomeInfo">

<s:param>Jack</s:param><!--此处一般从登录后从session取值-->

</s:text>

</body>

</html>

此时,需要在src下配置properties文件相应的转换规则。此处配置三个properties文件,默认,英文,中文。其他国家的自己去搞,这里只展示三个。默认文件是必须的,文件名要和struts.xml中配置的一致。

Java1234.properties(src目录下)[默认文件],采用Uicode编码,代码如下:

userName=\u7528\u6237\u540d

password=\u5bc6\u7801

login=\u767b\u5f55

welcomeInfo=\u6b22\u8fce{0}

Java1234_en_US.properties(src目录下)[英文],采用Uicode编码,代码如下:

userName=userName

password=password

login=login

welcomeInfo=welcome{0}

Java1234_zh_CN.properties(src目录下)[中文],采用Uicode编码,代码如下:

userName=\u7528\u6237\u540d

password=\u5bc6\u7801

login=\u767b\u5f55

welcomeInfo=\u6b22\u8fce{0}

5.struts2标签。Struts2标签是封装完全的,可以换几套皮肤。

数据标签:

①bean标签:

<s:bean name="com.java1234.model.Student" var="student">

<s:param name="name" value="‘张三‘"></s:param>

<s:param name="age" value="10"></s:param>

</s:bean>

<s:property value="#student.name"/>

<s:property value="#student.age"/>

②date标签:

<s:date name="#request.date" format="yyyy-MM-dd"/>

举例如下:

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

pageEncoding="UTF-8"%>

<%@ page import="java.util.*" %>

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

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

<html>

<head>

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

<title>Insert title here</title>

<%

request.setAttribute("date",new Date());

%>

</head>

<body>

${date }<br/>

当前日期:<s:date name="#request.date" format="yyyy-MM-dd"/>

</body>

</html>

③debug标签:

<s:debug></s:debug>

④include标签:

<s:include value="head.html"></s:include>

⑤property标签:

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

pageEncoding="UTF-8"%>

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

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

<html>

<head>

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

<title>Insert title here</title>

<%

request.setAttribute("name","<font color=red>张三</font>");

%>

</head>

<body>

<s:property value="#request.name" /><br/>

<s:property value="#request.name2" default="某某人"/><br/>

<s:property value="#request.name" default="某某人" escapeHtml="false"/><br/>

</body>

</html>

⑥set标签:

<s:set var="i" value="1"></s:set>

<s:property value="#i" /><br/>

<s:set var="a"  value="‘action范围的值‘" scope="action"></s:set>

<s:set var="p"  value="‘page范围的值‘" scope="page"></s:set>

<s:set var="r"  value="‘request范围的值‘" scope="request"></s:set>

<s:set var="s"  value="‘session范围的值‘" scope="session"></s:set>

<s:set var="app"  value="‘application范围的值‘" scope="application"></s:set>

<s:property value="#a" /><br/>

<s:property value="#attr.p"/><br/>

<s:property value="#request.r"/><br/>

<s:property value="#session.s"/><br/>

<s:property value="#application.app"/><br/>

⑥url标签:

<s:url action="hello" namespace="/foreground" id="h">

<s:param name="name" value="‘struts2‘"></s:param>

</s:url>

<s:a href="%{h}">超链接</s:a>

<s:a action="hello" namespace="/foreground">

<s:param name="name" value="‘struts2‘"></s:param>

超链接2

</s:a>

控制标签:

Append标签(叠加标签)

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

pageEncoding="UTF-8"%>

<%@ page import="com.java1234.model.Student" %>

<%@ page import="java.util.*" %>

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

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

<html>

<head>

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

<title>Insert title here</title>

<%

List<Student> studentList1=new ArrayList<Student>();

List<Student> studentList2=new ArrayList<Student>();

studentList1.add(new Student(1,"张三",10));

studentList1.add(new Student(3,"李四",20));

studentList2.add(new Student(5,"王五",30));

studentList2.add(new Student(7,"赵六",40));

request.setAttribute("studentList1",studentList1);

request.setAttribute("studentList2",studentList2);

%>

</head>

<body>

<s:append var="studentList3">

<s:param value="#request.studentList1"></s:param>

<s:param value="#request.studentList2"></s:param>

</s:append>

<table>

<tr>

<th>序号</th>

<th>编号</th>

<th>姓名</th>

<th>年龄</th>

</tr>

<s:iterator value="studentList3" status="status">

<tr>

<td><s:property value="#status.index+1"/></td>

<td><s:property value="id"/></td>

<td><s:property value="name"/></td>

<td><s:property value="age"/></td>

</tr>

</s:iterator>

</table>

</body>

</html>

generator标签(分割标签)

<s:generator separator="," val="‘张三,李四,王五‘" var="nameList"></s:generator>

<s:iterator value="#nameList"><!--相当于去掉,-->

<s:property/>

</s:iterator>

ifelse标签(判断标签)

<title>Insert title here</title>

<%

int age=11;

request.setAttribute("age",age);

%>

</head>

<body>

<s:if test="#request.age<20">

年龄小于20岁

</s:if>

<s:elseif test="#request.age==20">

年龄等于20岁

</s:elseif>

<s:else>

年龄大于20岁

</s:else>

</body>

UI标签:

<s:checkboxlist list="#{0: ‘游泳‘, 1:‘唱歌 ‘,2:‘跳舞‘}" name="hobby" value="1" />

<s:form action="hello" method="post" namespace="/foreground">

<s:radio list="#{0: ‘男 ‘, 1:‘女 ‘}" name="sex" value="0" />

<s:select list="#{0: ‘游泳‘, 1:‘唱歌 ‘,2:‘跳舞‘}" name="hobby" value="1" multiple="true"/>

<s:textfield name="userName"></s:textfield><br/>

<s:password name="password"></s:password><br/>

<s:textarea name="desc"></s:textarea><br/>

其他标签:

<s:optiontransferselect label="选择你喜欢图书"

name="cnbook" leftTitle="中文图书"  list="{‘struts2权威指南‘,‘轻量级javaeye 企业应用空实战‘,‘ajax讲义‘}"

doubleName="enBook"  rightTitle="外文图书" doubleList="{‘JavaScrip:The definitive Guide‘,‘export one-to-one‘}"  multiple="true"

addToLeftLabel="向左移动" addToRightLabel="向右移动" addAllToRightLabel="全部右移" addAllToLeftLabel="全部左移"

allowSelectAll="true" headerKey="cnKey" headerValue="选择图书" emptyOption="true"   doubleHeaderKey="enKey"

doubleHeaderValue="选择外文图书" doubleMultiple="true" doubleEmptyOption="true"  leftDownLabel="向下移动"

rightDownLabel="向下移动"

leftUpLabel="向上移动"

rightUpLabel="向上移动" >

</s:optiontransferselect>

<s:updownselect

list="#{0:‘游泳‘, 1:‘唱歌‘, 2:‘跳舞‘}"

name="hobby"

headerKey="-1"

headerValue="请选择"

emptyOption="true"

allowMoveUp="true"

allowMoveDown="true"

allowSelectAll="true"

moveUpLabel="Move Up"

moveDownLabel="Move Down"

  selectAllLabel="Select All" />

6.struts2中用ognl(对象图导航语言)访问复杂对象,静态方法和静态属性(此功能太过于强大,请慎用。注意数据的安全性)

此处要获取静态方法和属性,必须为public。默认状态下,是不允许访问静态方法,因此要在struts.xml配置<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant><!-- 此处配置为可以使用ognl访问静态方法 -->

在jsp页面访问代码如下:

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

pageEncoding="UTF-8"%>

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

<!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>Insert title here</title>

</head>

<body>

ognl获取静态属性:<s:property value="@[email protected]"/><br />

ognl获取静态方法:<s:property value="@[email protected]()"/><!-- 在此处要获取静态方法必须在struts.xml中配置<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>,默认是不能直接访问的,保证安全性 -->

</body>

</html>

获取对象代码如下:

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

pageEncoding="UTF-8"%>

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

<!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>Insert title here</title>

</head>

ognl获取对象值:

<s:property value="student.name"/><s:property value="student.age"/><br />

ognl获取list对象

<s:property value="students[0].name"/><s:property value="students[0].age"/><s:property value="students[1].name"/><s:property value="students[1].age"/><br />

ognl访问Map:<s:property value="studentMap[‘goodStudent‘].name"/><s:property value="studentMap[‘goodStudent‘].age"/><br/>

<s:property value="studentMap[‘badStudent‘].name"/><s:property value="studentMap[‘badStudent‘].age"/><br/>

</body>

</html>

7.struts2中的值的存储与获取

首先配置struts.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>

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

<action name="hello" class="com.java1234.action.HelloAction">

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

</action>

</package>

</struts>

配置接着找到action包下面的HelloAction.java,代码如下:

package com.java1234.action;

import java.util.Map;

import com.opensymphony.xwork2.ActionContext;

import com.opensymphony.xwork2.ActionSupport;

import com.opensymphony.xwork2.util.ValueStack;

public class HelloAction extends ActionSupport{

/**

*

*/

private static final long serialVersionUID = 1L;

@Override

public String execute() throws Exception {

ActionContext actionContext=ActionContext.getContext();

//设置狭义上的值栈

ValueStack valueStack= actionContext.getValueStack();

valueStack.set("name", "女神(ValueStack)");

valueStack.set("age", 21);

//设置session中的值

Map<String, Object> session=actionContext.getSession();

session.put("name", "女神(session)");

session.put("age", 22);

//设置application中的值

Map<String, Object> application=actionContext.getApplication();

application.put("name", "女神(application)");

application.put("age", 23);

return SUCCESS;

}

}

现在怎么取值呢,代码如下:

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

pageEncoding="UTF-8"%>

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

<!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>Insert title here</title>

<%

request.setAttribute("name", "女神(request)");

request.setAttribute("age", "24");

%>

</head>

getValueStack‘s value is:<s:property value="name"/><s:property value="age"/><br />

getSession‘s value is:<s:property value="#session.name"/><s:property value="#session.age"/><br />

getApplication‘s value is:<s:property value="#application.name"/><s:property value="#application.age"/><br />

getRequest‘s value is:<s:property value="#request.name"/><s:property value="#request.age" /><br />

getAttr‘s value is:<s:property value="#attr.name" /><s:property value="age"/><!-- attr默认的获取值的方式是:ValueStack Page Request Session Application顺序来找一个 -->

</body>

</html>

8.struts2中登录验证,也就是服务器端的验证了。在这里我要谈谈我对js登录验证和struts登录验证的联系和区别。一开始我学习到这里的时候很迷糊,我以前学习过js,很好用。为什么在这里还有学习登录验证呢。原来,struts2是服务器端验证。两种方式都是对用户身份进行验证,区别便是一个是客户端验证,一个是服务器验证。客户端验证也是就是js验证,反应速度很快,无需刷新页面,用户体验度很高。但是提升用户体验度的同时,也付出了安全性代价,js验证可以人为的跳过,使黑客能不经身份验证便访问服务器资源。服务器验证也就是这里的struts2验证,用户每次验证都要刷新页面,用户体验度不高,验证速度较慢,但是安全性高。所以验证最好的方式便是双重验证,至于为什么,想想很快就能明白了。

现在总结struts2登录验证,Struts2验证是基于拦截器的。

首先贴出struts.xml配置文件(src目录下),代码如下:

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

<interceptors>

<interceptor name="loginInterceptor" class="com.java1234.interceptor.LoginInterceptor"></interceptor>

<interceptor-stack name="myStack">

<interceptor-ref name="loginInterceptor"></interceptor-ref>

<interceptor-ref name="defaultStack"></interceptor-ref>

</interceptor-stack>

</interceptors>

<default-interceptor-ref name="myStack"></default-interceptor-ref>

<global-results>

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

</global-results>

<!-- 在这里的action中class都要指向有的,不然浏览器直接无法访问所有的 -->

<action name="user" class="com.java1234.action.UserAction">

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

<interceptor-ref name="defaultStack"></interceptor-ref><!-- 必须加上这句话,不然永远拦截没有通过 -->

</action>

<!--gril是模拟的登录之后的后续访问操作,没有验证通过便不能访问-->

<action name="gril" class="com.java1234.action.GrilAction">

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

</action>

</package>

</struts>

当页面访问user后,找到UserAction.java,代码如下:

package com.java1234.action;

import java.util.Map;

import com.java1234.model.User;//放用户数据

import com.java1234.service.UserService;//登录具体的验证方法

import com.opensymphony.xwork2.ActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class UserAction extends ActionSupport{

/**

*

*/

private static final long serialVersionUID = 1L;

private UserService userService=new UserService();

private User user;

private String error;

public User getUser() {

return user;

}

public void setUser(User user) {

this.user = user;

}

public String getError() {

return error;

}

public void setError(String error) {

this.error = error;

}

@Override

public String execute() throws Exception {

if(userService.login(user)){

ActionContext actionContext=ActionContext.getContext();

Map<String, Object> session=actionContext.getSession();

session.put("currentUser", user);

return SUCCESS;

}else{

this.error="用户名或密码错误";

return "error";

}

}

}

上面的代码意思为:如果验证通过,则把数据放到session中,如果没有通过则返回用户名或者密码错误。这里要说明的是,Useraction.java中为最后的验证,验证数据放在User.java中,验证方法放在UserService.java中。

现在贴出拦截器代码:

package com.java1234.interceptor;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;

import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.Interceptor;

public class LoginInterceptor implements Interceptor{

@Override

public void destroy() {

// TODO Auto-generated method stub

System.out.println("LoginInterceptor销毁");

}

@Override

public void init() {

// TODO Auto-generated method stub

System.out.println("LoginInterceptor初始化");

}

@Override

public String intercept(ActionInvocation invocation) throws Exception {

System.out.println("在Action执行之前");

ActionContext actionContext=invocation.getInvocationContext();

Map<String, Object> session=actionContext.getSession();

Object currentUser=session.get("currentUser");

String result=null;

if(currentUser!=null){

result=invocation.invoke();

}else{

HttpServletRequest request=(HttpServletRequest)invocation.getInvocationContext().get(ServletActionContext.HTTP_REQUEST);

request.setAttribute("error", "请先登录!");

result="error";

}

System.out.println("result:"+result);

return result;

}

}

上面的代码其实就是验证session是否为空,空的话提醒先登录,不能有后续的gril操作。注意,在程序运行的时候就已经初始化拦截器,在struts.xml可以知道,拦截器是放在user的前面的。还有要注意的就是,在struts.xml中<action name=”user”.....>中后面要添加上<interceptor-ref name="defaultStack"></interceptor-ref>,不然没法通过拦截器

在struts.xml还配置了一个全局error页面,

<global-results>

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

</global-results>

这样只需一个就可以搞定所有的出错页面,不用再在每个<result>中写<result name=”error”>error.jsp</result>,error.jsp代码贴出来:

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

pageEncoding="UTF-8"%>

<!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>Insert title here</title>

</head>

<body>

错误信息:${error }  <a href="login.jsp">登录</a>

</body>

</html>

还有要说明的是,有四个包分别为:action、interceptor、model、service

action中写UserAction.java(最后的验证),interceptor中写LoginInterceptor.java(判断session中是否为空),空的话直接返回error,不为空则进行下一步操作

ActionContext actionContext=invocation.getInvocationContext();

Map<String, Object> session=actionContext.getSession();

Object currentUser=session.get("currentUser");

String result=null;

if(currentUser!=null){

result=invocation.invoke();//

}else{

HttpServletRequest request=(HttpServletRequest)invocation.getInvocationContext().get(ServletActionContext.HTTP_REQUEST);

request.setAttribute("error", "请先登录!");

result="error";

}

model中写User.java放用户数据

package com.java1234.model;

public class User {

private String userName;

private String password;

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

}

Service中写UserService.java,判断登录方法:

package com.java1234.service;

import com.java1234.model.User;

public class UserService {

public boolean login(User user){

if("java1234".equals(user.getUserName())&&"123456".equals(user.getPassword())){

return true;

}else{

return false;

}

}

}

9.struts2处理多值传入(批量添加)

比如有个提交页面,添加多个学生:

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

pageEncoding="UTF-8"%>

<!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>Insert title here</title>

</head>

<body>

<form action="student" method="post">

<table>

<tr>

<th>姓名</th>

<th>性别</th>

<th>年龄</th>

</tr>

<tr>

<td><input type="text" name="students[0].name"/></td>

<td><input type="text" name="students[0].sex"/></td>

<td><input type="text" name="students[0].age"/></td>

</tr>

<tr>

<td><input type="text" name="students[1].name"/></td>

<td><input type="text" name="students[1].sex"/></td>

<td><input type="text" name="students[1].age"/></td>

</tr>

<tr>

<td colspan="3">

<input type="submit" value="提交"/>

</td>

</tr>

</table>

</form>

</body>

</html>

struts.xml(src目录下)配置如下

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

<action name="student" namespace="/fore" class="com.java1234.action.StudentAction" method="show" >

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

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

</action>

</package>

</struts>

根据配置找到StudentAction.java,代码如下:

package com.java1234.action;

import java.util.List;

import com.java1234.model.Student;//放数据,并重写toString方法

import com.opensymphony.xwork2.Action;

public class StudentAction implements Action {

private List<Student> students;

public List<Student> getStudents() {

return students;

}

public void setStudents(List<Student> students) {

this.students = students;

}

@Override

public String execute() throws Exception {

System.out.println("执行了Action的默认方法");

for (Student s : students) {

System.out.println(s);

}

return SUCCESS;

}

public void show() throws Exception {

System.out.println("执行了show的方法");

for (Student s : students) {

System.out.println(s);

}

}

}

再来举个例子,比如处理多选框值:

假如有个提交页面如下:

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

pageEncoding="UTF-8"%>

<!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>Insert title here</title>

</head>

<body>

<form action="hobby" method="post">

爱好:

<input type="checkbox" name="hobby" value="吃饭"/>吃饭

<input type="checkbox" name="hobby" value="睡觉"/>睡觉

<input type="checkbox" name="hobby" value="打豆豆"/>打豆豆

<input type="checkbox" name="hobby" value="数绵阳"/>数绵阳

<input type="submit" value="提交"/>

</form>

</body>

</html>

struts.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>

<package name="helloWorld" extends="struts-default">

<action name="hobby" class="com.java1234.action.HobbyAction">

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

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

</action>

</package>

</struts>

根据配置找到HobbyAction.java代码如下:

package com.java1234.action;

import com.opensymphony.xwork2.ActionSupport;

public class HobbyAction extends ActionSupport {

/**

*

*/

private static final long serialVersionUID = 1L;

private String[] hobby;

public String[] getHobby() {

return hobby;

}

public void setHobby(String[] hobby) {

this.hobby = hobby;

}

@Override

public String execute() throws Exception {

System.out.println("执行了Action的默认方法");

if (hobby != null) {

for (String h : hobby) {

System.out.println(h);

}

}

return SUCCESS;

}

}

好了,以上便是我这几天所学struts2我认为应该总结的东西,还有很多细枝末节就不再累述了。学完了struts2感触最深的就是拦截器,功能很强大,能处理很多用户需求。但是使用struts2的时候要小心,会出现意想不到的情况,数据要保护好,异常也要处理得当。我学习的是小锋老师的视频,在这里特别感谢!

时间: 2024-10-11 07:03:33

Java后台处理框架之struts2学习总结的相关文章

Java集合与框架总结与学习

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 本文将主要讲解Java中集合的使用与区别,主要讲List.Set.Map的原理.使用方法.注意事项等. 一.Collection与Collectons的区别 Java集合框架是Java语言的重要组成部分,它包含了系统而完整的集合层次体系,封装了大量的数据结构的实现.深刻理解Java集合框架的组成结构及其中的实现类和算法,能极大提高程序员编码的能力.本章讲述Java集合框架,主要包括集合框架的

快速上手代码示例 Java后台最新框架

A 代码生成器(开发利器);     增删改查的处理类,service层,mybatis的xml,SQL( mysql   和oracle)脚本,   jsp页面 都生成   就不用写搬砖的代码了,生成的放到项目里,可以直接运行B 阿里巴巴数据库连接池druid;  数据库连接池  阿里巴巴的 druid.Druid在监控.可扩展性.稳定性和性能方面都有明显的优势C 安全权限框架shiro ;  Shiro 是一个用 Java 语言实现的框架,通过一个简单易用的 API 提供身份验证和授权,更安

app后台管理系统框架metronic的学习笔记

先来看效果: 给出当前页面的代码: <!DOCTYPE html> <!--[if IE 8]> <html lang="zh" class="ie8 no-js"> <![endif]--> <!--[if IE 9]> <html lang="zh" class="ie9 no-js"> <![endif]--> <!--[if !I

关于java字节码框架ASM的学习

一.什么是ASM ASM是一个java字节码操纵框架,它能被用来动态生成类或者增强既有类的功能.ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为.Java class 被存储在严格格式定义的 .class文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称.方法.属性以及 Java 字节码(指令).ASM从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类.asm字节码增强技术主要是用来反射的时候提升性能的,

java后台SSH框架之Hibernate心得一

双向关联和单向关联 双向关联:这两个表无论哪一个更新另外一个表都更新 单向关联:就是只有一个主表更新从表才更新 从表更新主表不管 双向关联配置 表1配置 <set name="对象名称" order-by="id asc" inverse="true" lazy="false"> <key> <column name="列名" not-null="true"

struts2学习笔记(三)—— 在用户注册程序中使用验证框架

实现目标: 1.使用验证框架对用户注册信息进行验证 2.验证用户名.密码.邮箱不能为空 3.验证用户名.密码长度 4.验证邮件地址格式 具体实现 一.Struts2应用的基础配置 这里不做详细阐述,具体为web.xml.相关jar包的配置 二.将页面显示的文本内容放到资源文件中 1.查看用户注册程序中的所有页面,找到所有可以显示的文本内容,将它们分离出来放到资源文件中. 2.与相关的Action类同名,以.preperties为扩展名,与Action类位于同一个包中,只能由该Action访问 R

[原创]java WEB学习笔记59:Struts2学习之路---OGNL,值栈,读取对象栈中的对象的属性,读取 Context Map 里的对象的属性,调用字段和方法,数组,list,map

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

[原创]java WEB学习笔记6:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) 使用 paramsPrepareParamsStack 重构代码 ,PrepareInterceptor拦截器,paramsPrepareParamsStack 拦截器栈

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

【新技术】现在最流行的java后台框架组合java springmvc mybaits mysql oracle html5 后台框架源码

升级报捷:通过服务于服务之间调用,生成二维码,可直接用户手机app(详细查看截图) 框架集成lucene搜索引擎,使您的信息在毫秒内抓取(详细查看截图) 1.  创建.初始化索引.统一搜索入口.搜索结果展现--内容.标题高亮.关键词搜索 2.  高级搜索:高级搜索增加多入口查询(精确查询.模糊查询.前缀查询等),每页显示条数自定义.索引结果数据设置.选择索引文档类型等 3. 通过A系统调用B系统的Rest服务,生成相关的二维码,可以直接用户手机app ----------------------