您的位置:首页 > 职场人生

项目经验分享--strust2一个程序员难解难分的队友啊!

2016-04-19 17:50 323 查看
队友就是你NB的时候还能让你冷静思考的那货;言归正传

1、放置路径:

Struts2默认的配置文件为struts.xml ,该文件需要存放在项目中的WEB-INF/classes文件下

2、启动方式:采用过滤器的方式启动:

<filter>

<filter-name>struts2</filter-name>

<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>struts2</filter-name>

<url-pattern>*.do</url-pattern>

</filter-mapping>

<filter-mapping>

<filter-name>struts2</filter-name>

<url-pattern>*.action</url-pattern>

</filter-mapping>

<filter-mapping>

<filter-name>struts2</filter-name>

<url-pattern>*.htm</url-pattern>

</filter-mapping>

<filter-mapping>

<filter-name>struts2</filter-name>

<url-pattern>*.jsp</url-pattern>

</filter-mapping>

3.具体的注解方式的配置:

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

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"

"http://struts.apache.org/dtds/struts-2.1.dtd">

<struts>

<constant name="struts.devMode" value="true" />

<!-- 约定Action类执行完毕以后返回资源的结果路径,必须以 "/" 开头 -->

<constant name="struts.convention.result.path" value="/main,/members" />

<!-- 这个属性指定的是Strtus.xml中配置的 <package>节点的父节点 -->

<!-- <constant name="struts.convention.default.parent.package" value="admin-default" /> -->

<!-- 确定搜索包的路径。只要是结尾为action的包都要搜索 -->

<constant name="struts.convention.package.locators" value="action" />

<!-- 约定Action 类的项目根包 :值得注意的命名空间-->

<constant name="struts.convention.package.locators.basePackage" value="com.san.console.action" />

<package name="admin-default" extends="convention-default">

<interceptors>

<!--权限拦截器-->

<interceptor name="permissionInterceptor" class="com.san.console.interceptor.PermissionInterceptor" />

<interceptor-stack name="permitStack">

<interceptor-ref name="permissionInterceptor"/>

<interceptor-ref name="actionMappingParams"/>

<interceptor-ref name="params">

<param name="excludeParams">dojo\..*,^struts\..*</param>

</interceptor-ref>

<interceptor-ref name="conversionError"/>

<!-- 一定要加上默认的拦截器 如果不写会被覆盖的 -->

<interceptor-ref name="defaultStack"/>

</interceptor-stack>

</interceptors>

<!-- 配置struts2框架运行时,默认执行自定义拦截器栈 -->

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

<!-- 全局返回值 -->

<global-results>

<!-- 登录页 -->

<result name="loginpage" type="redirect">/login.jsp</result>

<!-- 无权提示页 -->

<result name="nopermit" type="redirect">/main/common/nopermit.jsp</result>

<!-- 异常错误页 -->

<result name="allException">/main/common/error.jsp</result>

</global-results>

<global-exception-mappings>

<exception-mapping result="allException" exception="java.lang.Exception" />

</global-exception-mappings>

</package>

</struts>

解释几点概念吧

<constant name="struts.convention.result.path" value="/main,/members" />

就是struts2返回页面的结果(页面)的结合。就是说返回页面也在main,或者members这两个文件夹下面;

还有一个权限拦截器:(在未来的某篇博客中我会重点解释下sessionId这个穿越APP和服务端的好东西)

public class PermissionInterceptor extends AbstractInterceptor {
public String intercept(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction();
String classType = action.getClass().getName();
Class className = Class.forName(classType);
Method method = action.getClass().getMethods()[0];
String res = "";
String reqActionName = invocation.getProxy().getActionName();
String actionname = invocation.getProxy().getActionName();
String methodname = invocation.getProxy().getMethod();
ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletActionContext.getServletContext());
String actionDesc = LocalizedTextUtil.findDefaultText(className.getSimpleName()+"."+methodname, new Locale(ApplicationConfig.DEFAULT_LOCALE));
LogRecord logRecord = method.getAnnotation(LogRecord.class);
if (!StringUtils.isNotBlank(actionDesc) && logRecord != null) {
actionDesc = logRecord.actionDesc();
}
if (action instanceof Protected) {
Protected pro = (Protected) action;
if (!pro.hasPermission(actionname, methodname)) {
//return "nopermission";注释掉,先不使用
}
if(StringUtils.equals(actionname, "systemlogin") && StringUtils.equals(methodname, "login")){//跳过登陆action
return invocation.invoke();
}else{
//根据session获取用户相关的权限
ManageUser gmacUser = (ManageUser) Struts2Utils.getSession().getAttribute(WebConstant.SESSION_EMPLOYEE_BEAN);
if(gmacUser==null){
return "loginpage";
}
}
}
return invocation.invoke();
}
}


注意:拦截器在session中会找一次用户。如果发现没有的话。就会退出到登录页面

//根据session获取用户相关的权限

ManageUser gmacUser = (ManageUser) Struts2Utils.getSession().getAttribute(WebConstant.SESSION_EMPLOYEE_BEAN);

if(gmacUser==null){

return "loginpage";

}

这里就必须提一下strust2的标签了:global-results、具有全局属性、

<global-results>

<result name="loginpage" type="redirect">/index2.jsp</result>

<result name="nopermit" type="redirect">/main/common/nopermit.jsp</result>

<result name="allException">/main/common/error.jsp</result>

</global-results>

4、最少依赖JAR包:

struts2-core-2.x.x.jar :Struts 2框架的核心类库

xwork-core-2.x.x.jar :XWork类库,Struts 2在其上构建

ognl-2.6.x.jar :对象图导航语言(Object Graph Navigation Language),struts2框架通过其读写对象的属性

freemarker-2.3.x.jar :Struts 2的UI标签的模板使用FreeMarker编写

commons-logging-1.x.x.jar :ASF出品的日志包,Struts 2框架使用这个日志包来支持Log4J和JDK 1.4+的日志记录。

commons-fileupload-1.2.1.jar 文件上传组件,2.1.6版本后必须加入此文件;

5、案例分析

登录案例,只做路径和配置方面的介绍

5.1 登录页面:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@include file="/main/common/taglibs.jsp"%>
<!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>
<title>${ APP_NAME}</title>
<%@include file="/main/common/meta.jsp"%>
<link href="${ctx }/css/login.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="${ctx }/js/plugin/jquery.cookie.js"></script>
<!-- 引用登录的js -->
<script type="text/javascript" src="${ctx }/js/login.js"></script>
</head>
<body>
<form action="#" method="post" name="loginForm">
<dl>
<dd>
<table border="0" cellpadding="4" cellspacing="0">
<tr>
<td><div id="loading" style="position:absolute; text-align:center; display: none;"><img src="images/ajax-loader.gif" alt="登录中……" /> </div></td>
<td colspan="2"><div id="msg" class="red" style="height:15px;"></div></td>
</tr>
<tr>
<td align="right" width="40">用户名</td>
<td align="left" width="198"><input name="userName" type="text" class="input_bg" id="name" /></td>
<td rowspan="2" align="left"><img src="images/login_button.jpg" width="62" height="62" style="cursor: pointer;" onClick="javascript:login();"/></td>
</tr>
<tr>
<td align="right">密 码</td>
<td align="left"><input name="password" type="password" class="input_bg" id="pwd" /></td>
</tr>
<tr>
<td> </td>
<td align="left" valign="top"><input type="checkbox" name="rememberloginname" id="rememberloginname" />
记住用户名</td>
<td> </td>
</tr>
</table>
</dd>
</dl>
</form>
</body>
</html>
<script type="text/javascript">
//get cookie name
if($.cookie('loginname')!=null){
$("#name").val($.cookie('loginname'));
$("#rememberloginname").attr("checked",true);
}
</script>


5.2 login.js

// JavaScript Document
if (self != top)
{
parent.location.href = webroot+"index.jsp";
}
function showMsg(msg)
{
var obj = document.getElementById("msg");
obj.innerHTML=msg;
}
function vaildateForm()
{
var name = document.getElementById("name");
var pwd = document.getElementById("pwd");
var v = document.getElementById("vaildate");
if(name.value=='') {
showMsg("帐号不能为空!");
name.focus();
return false;
}else if(!(/^[A-Za-z]{1}[A-Za-z0-9\_]+$/.test(name.value) && name.value.length >=5 && name.value.length<=35)){
showMsg("帐号必须是由5~35位英文字母或数字组成的字符!");
name.focus();
return false;
}
if(pwd.value=='') {
showMsg("密码不能为空!");
pwd.focus();
return false;
}
/*if(!/(?=^.{8,16}$)(?=(?:.*?\d){1})(?=.*[a-z])(?=(?:.*?[A-Z]){1})(?=(?:.*?[!@#$%*()_+^&}{:;?.]){1})(?!.*\s)[0-9a-zA-Z!@#$%*()_+^&]*$/.test(pwd.value)){
showMsg("密码必须由8~16位大小写字母、数字和特殊字符组成!");
pwd.focus();
return false;
}*/
return true;
}

function login(){
if(vaildateForm()){
//登录跳转
$.ajax({
type:"POST",   //传值方式
url:"manage/systemlogin!login.action",  //请求的路径
dataType: "json",
data:{username:$("#name").val(),password:$("#pwd").val()},   //数据格式
beforeSend:function(){
$("#loading").css('display','block');//加载效果
},
success:function(d, textStatus){
if(d.success==true){
if($("#rememberloginname").attr("checked")){//记住用户名
$.cookie('loginname', $("#name").val(),{expires: 7});
}else{
$.cookie('loginname', null);
}
//登录成功,跳转到导航页面
window.location.href = "manage/systemmanage!toIndexPage.action";
}else{
//师表小时
$("#loading").css('display','none');
showMsg(d.message);
}
},
//错误展示
error: function (xhttp, textStatus, errorThrown) {
$("#loading").css('display','none');
//showMsg("System error!");
alert(errorThrown);
}
});
}
}

function fireFoxHandler(evt){
if(evt.keyCode==13){
login();
}
}

function ieHandler(evt){
if(evt.keyCode==13){
login();
}
}

if(document.addEventListener){//Firefox
document.addEventListener("keypress",fireFoxHandler, true);
}else{
document.attachEvent("onkeypress",ieHandler);
}
注意strust2的命名空间:url:"manage/systemlogin!login.action"

5.3 strust2后台配置调用

@Namespace("/manage")
@Actions({
@Action(value="systemlogin",
results={
@Result(name="loginpage", location="/index.jsp", type="redirect")
}),
@Action(value="systemmanage",
results={
@Result(name="main", location="/main/main.jsp"),
@Result(name="desktopPage", location="/main/desktop.jsp"),
})
})
public class LoginAction  extends BaseActionSupport<ManageUser>{
<pre name="code" class="html">@LogRecord(logType="5", actionDesc = "用户登录")
public void login() {
String username = null;
String password = null;
try{
username = Struts2Utils.getParameter("username");
password = Struts2Utils.getParameter("password");
}catch(Exception e){
e.printStackTrace();
}
boolean loginResult = false;
String loginMessage = "";
Des3Util des3Util = new Des3Util(ApplicationConfig.PASSWORD_KEY);

ManageUser gmacUser = userService.findGmacUserByLoginName(username);
//记录登录日志
SysOperateLog operateLog = new SysOperateLog();
operateLog.setLogTime(new Date());
operateLog.setLogOperate(WebConstant.LOG_OPERATE_SECURITY);
operateLog.setLogUser(username);
operateLog.setLogOperateClass(LoginAction.class.getSimpleName());
operateLog.setLogOperateMethod("login");
operateLog.setLogOperateActionName("systemlogin_login");
if(gmacUser==null){//用户不存在,记录不存在用户尝试登录日志
loginMessage = "用户不存在";
//			loginMessage = LocalizedTextUtil.findDefaultText("tips.login.noexist", new Locale(ApplicationConfig.DEFAULT_LOCALE));
//记录无效用户名登录尝试记录日志
operateLog.setLogOperateResult(WebConstant.OPERATE_FAIL);//操作失败
//			operateLog.setLogContent(MessageFormat.format(LocalizedTextUtil.findDefaultText("tips.login.fail", new Locale(ApplicationConfig.DEFAULT_LOCALE)),Struts2Utils.getRequest().getRemoteAddr())+loginMessage);
}else {//用户存在,也记录登录日志
String enCodePassward = des3Util.getEncString(password);//加密后匹配
if(userService.userLogin(username, enCodePassward)==true){//验证初始密码
loginResult = true;
}else{//密码错误
loginMessage = "密码错误";
//						loginMessage = LocalizedTextUtil.findDefaultText("tips.login.passwrong", new Locale(ApplicationConfig.DEFAULT_LOCALE));
}
if(loginResult){//验证成功,进行登录操作并存储用户信息到session,存储最近登录信息
gmacUser.setLastIp(gmacUser.getLoginIp());
gmacUser.setLastTime(gmacUser.getLoginTime()==null?(new Date()):gmacUser.getLoginTime());//2012.03.05修改用户未过期禁用bug
gmacUser.setLoginFails(0);
gmacUser.setLoginTime(new Date());
gmacUser.setLoginIp(Struts2Utils.getRequest().getRemoteAddr());
List list = userService.findRootSysMenuListByUserId(gmacUser.getId());
if((list==null || list.size()<1) && !ApplicationConfig.getSupperUserList().contains(gmacUser.getUserLoginName())){
loginResult = false;
operateLog.setLogOperateResult(WebConstant.OPERATE_FAIL);//操作失败
}else{
Struts2Utils.getSession().setAttribute(WebConstant.SESSION_EMPLOYEE_BEAN, gmacUser);
//设置用户可用的action name属性
ServletContext sctx = Struts2Utils.getSession().getServletContext();
String accesslist = "systemmanage_openDeskTopPage,systemmanage_toIndexPage,account_openChangePwdPage,systemlogin_logout,account_getUserPrivateMenuList,account_changePwd,ira_getUploadStatusBar4Br4";
sctx.setAttribute(WebConstant.ACCESS_ACTIONLIST, accesslist);
operateLog.setLogOperateResult(WebConstant.OPERATE_SUCCESS);//操作成功
}
}else{//登录失败
gmacUser.setLoginFails(1);
gmacUser.setLoginTime(new Date());
gmacUser.setLoginIp(Struts2Utils.getRequest().getRemoteAddr());
if(!StringUtils.isNotBlank(loginMessage)){
loginMessage = LocalizedTextUtil.findDefaultText("tips.login.systemerror", new Locale(ApplicationConfig.DEFAULT_LOCALE));
}
operateLog.setLogOperateResult(WebConstant.OPERATE_FAIL);//操作失败
//				operateLog.setLogContent(MessageFormat.format(LocalizedTextUtil.findDefaultText("tips.login.fail", new Locale(ApplicationConfig.DEFAULT_LOCALE)),gmacUser.getLoginIp())+loginMessage);
}
userService.modifyAccount(gmacUser);
}
operateLog.setIsAuthed(true);
operateLog.setLogType(WebConstant.LOG_ENVENT_TYPE6);
operateLogService.writeOperateLog(operateLog);

Struts2Utils.renderJson("{\"success\":"+loginResult+",\"message\":\""+loginMessage+"\"}");
}


这里为什么要返回的json字符串。理由是ajax请求要拿到返回值解析啊!

找一个相对比较正规的解析:

add信息(js中的部分内容):

case 'add':

openDialog(webroot+'san/cusInfo!cusInfoAddPage.action'+'?channel_no='+channel_no,700,150);

break;

后台action:Namespace和action和URL:san/cusInfo!对应;

@Namespace("/san")

@Actions({

@Action(value="cusInfo",

results={

//返回值和对应页面路径

@Result(name="cusInfoAddPage", location="/main/san/cusinfo_add.jsp"),

@Result(name="channelCusInfoAddPage", location="/main/san/channelcusInfo_add.jsp")

})

})

/***

* 打开新增页面的方法

*/

public String cusInfoAddPage(){

String channel_no = Struts2Utils.getParameter("channel_no");

if(StringUtils.isNotBlank(channel_no)){

Struts2Utils.getRequest().setAttribute("channel_no", channel_no);

}

return "cusInfoAddPage";

}

以上完整Ok
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: