📄 详细分析三.txt
字号:
tourl = this.getBasePath() + "main.html"; //注意,曾经有sb.append("/");
} else {
tourl = this.getBasePath() + BBSCSUtil.getActionMappingURLWithoutPrefix("main");//此工具方法加后缀main.bbscs
}
return this.input();
}
-->
public String input() {//是否要登录
if (this.getSysConfig().getUsePass() == 0) {//usePass=1表示使用通行证登录
return INPUT;//action=login,hiddenLogin=0,tourl=XXXX:80/main.bbscs,urlRewrite=false,userAuthCodeValue,注意到:
private boolean urlRewrite = false;
private boolean useAuthCode = true;
private int cookieTime = -1;
还有basePath,remoteAddress,UserCookie,以及两组List等等} else {
this.setActionUrl(this.getSysConfig().getPassUrl());//PassUrl=http://www.laoer.com/login.do
return "loginPass";
}
}
我们返回struts.xml中可以找到它将result到哪里:
<result name="success" type="redirect">${tourl}</result>
<result name="input">/WEB-INF/jsp/login.jsp</result>
<result name="loginPass">/WEB-INF/jsp/passLogin.jsp</result>
好,我们已经INPUT到/WEB-INF/jsp/login.jsp界面中了:
<%@page contentType="text/html; charset=UTF-8"%>
<%@taglib uri="/WEB-INF/struts-tags.tld" prefix="s"%>
<%@taglib uri="/WEB-INF/bbscs.tld" prefix="bbscs"%>
另外还有<%@ taglib uri="/WEB-INF/FCKeditor.tld" prefix="FCK" %>
其中的,s是struts2的,而bbscs是本系统的...
<%@page contentType="text/html; charset=UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; //basePath!
%>
其中,bbscs:webinfo是网站信息用的标签!<title><bbscs:webinfo type="forumname"/> - <s:text name="login.title"/><bbscs:webinfo type="poweredby"/></title>
<tag>
<name>webinfo</name>
<tag-class>com.laoer.bbscs.web.taglib.WebInfoTag</tag-class>//WebInfoTag
<body-content>empty</body-content> //无内容的!
<attribute>
<name>type</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue> //run time expression value运行时表达式
</attribute>
</tag>
我们进入WebInfoTag一看:它有一个属性type及其get/set方法
public Component getBean(ValueStack arg0, HttpServletRequest arg1, HttpServletResponse arg2) {
return new WebInfo(arg0, pageContext); //构造一个Component
}
protected void populateParams() {
super.populateParams();
WebInfo tag = (WebInfo) component;
tag.setType(type);
}
而WebInfo实现了Component接口,它的构造方法:
public WebInfo(ValueStack stack, PageContext pageContext) {
super(stack);
this.pageContext = pageContext;
}
这里关键的地方是:
public boolean start(Writer writer) {
boolean result = super.start(writer);
WebApplicationContext wc = WebApplicationContextUtils.getWebApplicationContext(this.pageContext
.getServletContext()); //调用服务层
SysConfig sysConfig = (SysConfig) wc.getBean("sysConfig");//这里主要用了sysConfg
StringBuffer sb = new StringBuffer();
if (this.getType().equalsIgnoreCase("forumname")) { //type="forunname"
sb.append(sysConfig.getForumName());
}
if (this.getType().equalsIgnoreCase("poweredby")) {//type="poweredby"
sb.append(" - ");
sb.append("Powered By BBS-CS[天乙社区]");
}
if (this.getType().equalsIgnoreCase("meta")) {//type="meta"
sb.append("<meta name=\"keywords\" content=\"");
sb.append(sysConfig.getMetaKeywords());
sb.append("\"/>\n");
sb.append("<meta name=\"description\" content=\"");
sb.append(sysConfig.getMetaDescription());
sb.append("\"/>");
}
if (this.getType().equalsIgnoreCase("pagefoot")) {//type="pagefoot"
Locale locale = this.pageContext.getRequest().getLocale();
ResourceBundleMessageSource messageSource = (ResourceBundleMessageSource) wc.getBean("messageSource");//从消息资源文件获得
if (StringUtils.isNotBlank(sysConfig.getWebName())) {
if (StringUtils.isNotBlank(sysConfig.getWebUrl())) {
sb.append("<a href=\"");
sb.append(sysConfig.getWebUrl());
sb.append("\" target=\"_blank\">");
sb.append(sysConfig.getWebName());
sb.append("</a>");
} else {
sb.append(sysConfig.getWebName());
}
}
if (StringUtils.isNotBlank(sysConfig.getForumName())) {
sb.append(" | ");
if (StringUtils.isNotBlank(sysConfig.getForumUrl())) {
sb.append("<a href=\"");
sb.append(sysConfig.getForumUrl());
sb.append("\" target=\"_blank\">");
sb.append(sysConfig.getForumName());
sb.append("</a>");
} else {
sb.append(sysConfig.getForumName());
}
}
if (StringUtils.isNotBlank(sysConfig.getWebmasterEmail())) {
sb.append(" | ");
sb.append("<a href=\"mailto:");
sb.append(sysConfig.getWebmasterEmail());
sb.append("\">");
sb.append(messageSource.getMessage("bbscs.contactus", null, locale));
sb.append("</a>");
}
if (StringUtils.isNotBlank(sysConfig.getPrivacyUrl())) {
sb.append(" | ");
sb.append("<a href=\"");
sb.append(sysConfig.getPrivacyUrl());
sb.append("\" target=\"_blank\">");
sb.append(messageSource.getMessage("bbscs.privacy", null, locale));
sb.append("</a>");
}
if (StringUtils.isNotBlank(sysConfig.getCopyRightMsg())) {
sb.append("<BR/>");
sb.append(sysConfig.getCopyRightMsg()); //加入版权信息
}
sb.append("<BR/>");
sb.append("<strong><font face=\"Tahoma\" size=\"1\" color=\"#A0A0A4\">");
sb.append("Powered By ");
sb.append("<a href=\"http://www.laoer.com\" target='_blank'>BBS-CS</a>");
sb.append(" V");
sb.append(Constant.VSERION);
sb.append(" © 2007</font></strong>");
}
try {
writer.write(sb.toString()); //输入
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
我们看login.jsp中,有许多struts2的标签,如s:form s:hidden s:text s:actionerror s:textfield s:if s:else s:radio s:submit s:submit s:url (样式用cssClass)对于具体的使用请看:http://www.blogjava.net/max/archive/2006/10/18/75857.html
注意<img alt="<s:text name="login.authcode"/>" src="authimg" align="absmiddle" />是从authimg得到图片的(注意这里是相对URL)
也注意到:s:actionerror也用到了template.bbscs0 <s:actionerror theme="bbscs0"/>
<#if (actionErrors?exists && actionErrors?size > 0)>
<div class="errormsg">
<#list actionErrors as error>
<span class="errorMessage">${error}</span><br/>
</#list>
</div>
</#if>
注意到struts.properties文件中:
struts.ui.theme=simple
//struts.ui.templateDir=template 默认
//struts.ui.templateSuffix=ftl 默认
好的,我们提交表单,进入login.bbscs,还是最终达到Login.java
public String execute() {
this.setUrlRewrite(Constant.USE_URL_REWRITE);
this.setUserAuthCodeValue();
-->
private void setUserAuthCodeValue() {
this.setUseAuthCode(this.getSysConfig().isUseAuthCode()); //=true
}
if (this.getAction().equalsIgnoreCase("login")) {
return this.login();
}
--->
public String login() {
if (StringUtils.isBlank(this.username) || StringUtils.isBlank(this.passwd)) { //输入的帐号和密码是否为否
this.addActionError(this.getText("error.nullerror"));
return INPUT;
}
UserInfo ui = this.getUserService().findUserInfoByUserName(this.getUsername());//查找有没有这个用户
if (ui == null) {
this.addActionError(this.getText("error.user.notexist"));
return INPUT;
}
if (this.getSysConfig().isUseSafeLogin()) { //是否安全登录模式(例如3次登录机会)
if (this.getLoginErrorService().isCanNotLogin(ui.getId())) {
this.addActionError(this.getText("error.login.times"));
return INPUT;
}
}
if (!Util.hash(this.getPasswd()).equals(ui.getRePasswd())) { // 密码错误
/**
public synchronized static final String hash(String data) {
if (digest == null) {
try {
digest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException nsae) {
System.err
.println("Failed to load the MD5 MessageDigest. " + "We will be unable to function normally.");
nsae.printStackTrace();
}
}
// Now, compute hash.
digest.update(data.getBytes());
return encodeHex(digest.digest());
}
*/
if (this.getSysConfig().isUseSafeLogin()) {
try {
this.getLoginErrorService().createLoginErrorui.getId());//加入错误服务中!
} catch (BbscsException ex1) {
logger.error(ex1);
}
}
this.addActionError(this.getText("error.login.passwd"));
return INPUT;
}
if (this.getSysConfig().isUseAuthCode()) { //使用验证码
String cauthCode = this.getUserCookie().getAuthCode();//Cookie中得到AuthCode!
if (StringUtils.isBlank(cauthCode) || !cauthCode.equals(this.getAuthCode())) {
this.addActionError(this.getText("error.login.authcode"));
return INPUT;
}
}
ui.setLastLoginIP(ui.getLoginIP());//上一次的
ui.setLastLoginTime(ui.getLoginTime());//上一次
ui.setLoginIP(this.getRemoteAddr());
ui.setLoginTime(new Date()); //时间类型哦
ui.setUserLocale(this.getLocale().toString());
long nowTime = System.currentTimeMillis();
UserOnline uo = new UserOnline();
uo.setAtPlace("");
uo.setBoardID(0);
uo.setNickName(ui.getNickName());
uo.setOnlineTime(nowTime);//long类型的时间
uo.setUserGroupID(ui.getGroupID());
uo.setUserID(ui.getId());
uo.setUserName(ui.getUserName());
uo.setValidateCode(ui.getId() + "_" + nowTime);//构造出来的,用于避免重复登录吧!
if (this.getHiddenLogin() == 1 || ui.getHiddenLogin() == 1) { // 用户隐身登录
uo.setHiddenUser(1);
}
try {
ui = this.getUserService().saveAtLogin(ui); // 用户登录处理
/**
public UserInfo saveAtLogin(UserInfo userInfo) throws BbscsException {
try {
if ((System.currentTimeMillis() - userInfo.getLastLoginTime().getTime()) > 30 * 60000) {
userInfo.setLoginTimes(userInfo.getLoginTimes() + 1);//不一样吧!
userInfo.setExperience(userInfo.getExperience() + 1);
}
userInfo = this.getUserInfoDAO().saveUserInfo(userInfo);
this.getUserInfoFileIO().writeUserFile(userInfo);
return userInfo;
} catch (Exception ex) {
logger.error(ex);
throw new BbscsException(ex);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -