⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 详细分析三.txt

📁 开源论坛实现
💻 TXT
📖 第 1 页 / 共 4 页
字号:
			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(" &copy; 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 + -