要加载的jar有: log4j-1.2.16.jar
commons-logging-1.1.1.jar
commons-beanutils-1.8.0.jar
commons-chain-1.2.jar
commons-digester-1.8.jar
struts-core-1.3.10.jar
struts-taglib-1.3.10.jar
文件结构图如下:
LoginForm.java (为表单的字段提供get() set() 初始化 校验等操作)
package org.baicai.struts1.form;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
public class LoginForm extends ActionForm {
private static Logger logger = Logger.getLogger(LoginForm.class);
private static final long serialVersionUID = -8914763639472230373L;
private String username; // 登陆用户名
private String password; // 登陆密码
public LoginForm() {
}
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;
}
@Override
public void reset(ActionMapping mapping, HttpServletRequest request) {
logger.debug("reset");
// reset方法用于初始化字段数据
username = "请输入用户名";
password = "";
}
@Override
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request) {
logger.debug("validate");
// validate方法用于校验用户输入
ActionErrors errors = new ActionErrors(); // 放置错误提示信息
if ("".equals(username.trim())) { // 校验用户名称是否填写
// 第一个参数是页面提示错误的键值
// 第二个参数是info.properties中的键值
errors.add("un", new ActionMessage("index.error.un"));
} else if ("".equals(password.trim())) { // 校验密码是否填写
errors.add("pwd", new ActionMessage("index.error.pwd"));
}
// 如果返回的是null或者errors里面没有错误提示信息,校验流程就会通过
return errors;
}
}
LoginAction.java(业务逻辑处理)
package org.baicai.struts1.action;
import javax.servlet.http.HttpServletRequest;
public class LoginAction extends Action {
private static Logger logger = Logger.getLogger(LoginAction.class);
public LoginAction() {
}
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// 获取表单数据(ActionForm和Action的关系在配置文件里面设置)
LoginForm f = (LoginForm) form;
logger.debug(f.getUsername() + "," + f.getPassword());
// 模拟登陆校验
if (f.getUsername().equals("admin") && f.getPassword().equals("8888")) {
// 如果登录成功就转到名称为main的视图(逻辑视图的关系也在配置文件里面设置)
return mapping.findForward("main");
} else {
// 登陆失败就提示信息,并回到输入页
ActionErrors errors = new ActionErrors();// 放置错误提示信息(和ActionForm一样)
// 也需要在info.properties中添加信息
errors.add("fail", new ActionMessage("index.error.fail"));
// 保存错误信息
this.addErrors(request, errors);
// 输入页也是在配置文件里面设置
return mapping.getInputForward();
}
}
}
EncodingFilter.java(对request,response设置编码)
package org.baicai.servlet;
import java.io.IOException;
public class EncodingFilter implements Filter {
public static final String DEFAULT_ENCODING = "UTF-8";
private static Logger logger = Logger.getLogger(EncodingFilter.class);
private String encoding;
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 设置请求和应答的默认编码
request.setCharacterEncoding(encoding);
response.setCharacterEncoding(encoding);
// 请求继续
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
// 读取web.xml文件配置的编码参数
encoding = filterConfig.getInitParameter("encoding");
// 如果没有配置编码参数,就使用默认的编码
if (encoding == null || encoding.trim().equals("")) {
encoding = DEFAULT_ENCODING;
}
logger.debug(String.format("字符编码设定:%s", encoding));
}
}
info.properties (国际资源化文件)
index.error.un \u7528\u6237\u540D\u6CA1\u6709\u586B\u5199\uFF01
index.error.pwd=\u5BC6\u7801\u6CA1\u6709\u586B\u5199\uFF01
index.error.fail=\u767B\u9646\u5931\u8D25\uFF01
log4j.dtd (logger打印配置文件的规范文件 你只需要copy下来就行了)
<?xml version="1.0" encoding="UTF-8" ?>
<!-- Authors: Chris Taylor, Ceki Gulcu. -->
<!-- Version: 1.2 -->
<!-- A configuration element consists of optional renderer
elements,appender elements, categories and an optional root
element. -->
<!ELEMENT log4j:configuration (renderer*, appender*,(category|logger)*,root?,
categoryFactory?)>
<!-- The "threshold" attribute takes a level value such that all -->
<!-- logging statements with a level equal or below this value are -->
<!-- disabled. -->
<!-- Setting the "debug" enable the printing of internal log4j logging -->
<!-- statements. -->
<!-- By default, debug attribute is "null", meaning that we not do touch -->
<!-- internal log4j logging settings. The "null" value for the threshold -->
<!-- attribute can be misleading. The threshold field of a repository -->
<!-- cannot be set to null. The "null" value for the threshold attribute -->
<!-- simply means don't touch the threshold field, the threshold field -->
<!-- keeps its old value. -->
<!ATTLIST log4j:configuration
xmlns:log4j CDATA #FIXED "http://jakarta.apache.org/log4j/"
threshold (all|debug|info|warn|error|fatal|off|null) "null"
debug (true|false|null) "null"
>
<!-- renderer elements allow the user to customize the conversion of -->
<!-- message objects to String. -->
<!ELEMENT renderer EMPTY>
<!ATTLIST renderer
renderedClass CDATA #REQUIRED
renderingClass CDATA #REQUIRED
>
<!-- Appenders must have a name and a class. -->
<!-- Appenders may contain an error handler, a layout, optional parameters -->
<!-- and filters. They may also reference (or include) other appenders. -->
<!ELEMENT appender (errorHandler?, param*, layout?, filter*, appender-ref*)>
<!ATTLIST appender
name ID #REQUIRED
class CDATA #REQUIRED
>
<!ELEMENT layout (param*)>
<!ATTLIST layout
class CDATA #REQUIRED
>
<!ELEMENT filter (param*)>
<!ATTLIST filter
class CDATA #REQUIRED
>
<!-- ErrorHandlers can be of any class. They can admit any number of -->
<!-- parameters. -->
<!ELEMENT errorHandler (param*, root-ref?, logger-ref*, appender-ref?)>
<!ATTLIST errorHandler
class CDATA #REQUIRED
>
<!ELEMENT root-ref EMPTY>
<!ELEMENT logger-ref EMPTY>
<!ATTLIST logger-ref
ref IDREF #REQUIRED
>
<!ELEMENT param EMPTY>
<!ATTLIST param
name CDATA #REQUIRED
value CDATA #REQUIRED
>
<!-- The priority class is org.apache.log4j.Level by default -->
<!ELEMENT priority (param*)>
<!ATTLIST priority
class CDATA #IMPLIED
value CDATA #REQUIRED
>
<!-- The level class is org.apache.log4j.Level by default -->
<!ELEMENT level (param*)>
<!ATTLIST level
class CDATA #IMPLIED
value CDATA #REQUIRED
>
<!-- If no level element is specified, then the configurator MUST not -->
<!-- touch the level of the named category. -->
<!ELEMENT category (param*,(priority|level)?,appender-ref*)>
<!ATTLIST category
class CDATA #IMPLIED
name CDATA #REQUIRED
additivity (true|false) "true"
>
<!-- If no level element is specified, then the configurator MUST not -->
<!-- touch the level of the named logger. -->
<!ELEMENT logger (level?,appender-ref*)>
<!ATTLIST logger
name ID #REQUIRED
additivity (true|false) "true"
>
<!ELEMENT categoryFactory (param*)>
<!ATTLIST categoryFactory
class CDATA #REQUIRED>
<!ELEMENT appender-ref EMPTY>
<!ATTLIST appender-ref
ref IDREF #REQUIRED
>
<!-- If no priority element is specified, then the configurator MUST not -->
<!-- touch the priority of root. -->
<!-- The root category always exists and cannot be subclassed. -->
<!ELEMENT root (param*, (priority|level)?, appender-ref*)>
<!-- ==================================================================== -->
<!-- A logging event -->
<!-- ==================================================================== -->
<!ELEMENT log4j:eventSet (log4j:event*)>
<!ATTLIST log4j:eventSet
xmlns:log4j CDATA #FIXED "http://jakarta.apache.org/log4j/"
version (1.1|1.2) "1.2"
includesLocationInfo (true|false) "true"
>
<!ELEMENT log4j:event (log4j:message, log4j:NDC?, log4j:throwable?,
log4j:locationInfo?) >
<!-- The timestamp format is application dependent. -->
<!ATTLIST log4j:event
logger CDATA #REQUIRED
level CDATA #REQUIRED
thread CDATA #REQUIRED
timestamp CDATA #REQUIRED
>
<!ELEMENT log4j:message (#PCDATA)>
<!ELEMENT log4j:NDC (#PCDATA)>
<!ELEMENT log4j:throwable (#PCDATA)>
<!ELEMENT log4j:locationInfo EMPTY>
<!ATTLIST log4j:locationInfo
class CDATA #REQUIRED
method CDATA #REQUIRED
file CDATA #REQUIRED
line CDATA #REQUIRED
>
log4j.xml (logger打印级别的配置)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<!-- 控制台输出 -->
<appender name="baicai.console"
class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%l:%d{hh:mm:ss}%n%p:%m %n" />
</layout>
</appender>
<!-- 文件输出 -->
<appender name="baicai.file"
class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${baicai.appRoot}/mylog.txt" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%l:%d{hh:mm:ss}%n%p:%m %n" />
</layout>
</appender>
<!-- org.baicai包的Logger配置 -->
<logger name="org.baicai" additivity="false">
<level value="DEBUG" />
<appender-ref ref="baicai.console" />
</logger>
<logger name="org.baicai.jquery" additivity="false">
<level value="DEBUG" />
<appender-ref ref="baicai.console" />
<appender-ref ref="baicai.file" />
</logger>
<!-- RootLogger配置 -->
<root>
<level value="INFO" />
<appender-ref ref="baicai.console" />
</root>
</log4j:configuration>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- struts核心控制配置 -->
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>
org.apache.struts.action.ActionServlet
</servlet-class>
<init-param>
<!-- 指定配置文件的路径 -->
<param-name>config</param-name>
<param-value>/WEB-INF/struts.xml</param-value>
</init-param>
<!-- 加载顺序 -->
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- 编码连接器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>
org.baicai.servlet.EncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<!-- 拦截所有的请求url -->
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
"http://struts.apache.org/dtds/struts-config_1_3.dtd">
<struts-config>
<form-beans>
<!-- ActionForm配置,name参数为ActionForm的逻辑名称, type为ActionForm的完整类名称-->
<form-bean name="login"
type="org.baicai.struts1.form.LoginForm" />
</form-beans>
<global-exceptions></global-exceptions>
<global-forwards></global-forwards>
<action-mappings>
<!--
Action配置 path为Action的访问路径(省略了.do扩展名) path="/login"的action的真实访问路径为:/应用路径/login.do
name为Action对应的ActionForm的逻辑名称 scope表示ActionForm的存放作用域 input表示输入页 type为Action的完整类名称
forward为逻辑视图配置,name为逻辑名称,path表示实际的页面路径名称
-->
<action path="/login" name="login" scope="request"
input="/index.jsp" type="org.baicai.struts1.action.LoginAction">
<forward name="main" path="/pages/main.jsp" />
</action>
</action-mappings>
<!-- 资源文件配置,所有的ActionMessage信息都放在这个文件里面 -->
<message-resources parameter="info"></message-resources>
</struts-config>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- 需要使用struts标签库来完成表单的构建 -->
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<!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">
<style type="text/css">span {color: red}</style>
</head>
<body>
<center>
<!-- 使用html:form标签配置表单提交 action属性为Action配置小节中path -->
<html:form action="/login" method="post">
<table border="1">
<tr>
<td>用户名:</td>
<td>
<!-- 使用html:text标签配置信息提交文本框,property属性为Action配置的中AcitonForm对象的字段名称,提交的数据将会填充给这个字段 -->
<html:text property="username"></html:text>
<!-- 使用html:errors标签配置错误提示信息,property属性为ActionErrors.add方法的第一个参数字符串 -->
<span><html:errors property="un" /></span>
</td>
</tr>
<tr>
<td>密码:</td>
<td>
<!-- 使用html:password标签配置密码信息提交文本框,property属性为Action配置的中AcitonForm对象的字段名称,提交的数据将会填充给这个字段 -->
<html:password property="password"></html:password>
<span><html:errors property="pwd" /></span>
</td>
</tr>
<tr>
<td align="center" colspan="2">
<input type="submit" value="登陆">
</td>
</tr>
</table>
<!-- Action的错误信息显示方法和ActionForm的一致 -->
<div><span><html:errors property="fail" /></span></div>
</html:form>
</center>
</body>
</html>
pages/main.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">
</head>
<body>
<center>
<h1>
恭喜你!struts第一课完成
</h1>
</center>
</body>
</html>
执行结果如图所示: