struts入门笔记总结

struts入门笔记总结

Servlet与struts的区别

启动

servlet:无
struts:配置filter

创建

servlet:继承HttpServlet,实现doget,dopost,
添加注解,或者配置web.xml
struts:继承ActionSupport,写一个带有String返回值且抛出一个异常的函数
配置struts.xml,struts.xml是在src目录下

创建Action举例 UserAction.java

package com.sikiedu.web;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.sikiedu.domain.User;
import com.sikiedu.service.UserService;

public class UserAction extends ActionSupport implements ModelDriven<User>{

	public User user=new User();
	
	
	public String execute() throws Exception {
		System.err.println("我已经运行");
		UserService userService=new UserService();
		boolean success=userService.findUser(user);
		if(success) {
			return "success";
		}else {
			ServletActionContext.getRequest().setAttribute("error", "用户名或密码错误");
			return "error";
		}	
	}
	@Override
	public User getModel() {
		// TODO Auto-generated method stub
		return user;
	}
}	

配置举例

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
	<!-- name配置包名 -->
	<package name="MyPackage" namespace="/" extends="struts-default">	
		<action name="LoginAction" class="com.sikiedu.web.UserAction" method="execute">
			<result name="success" type="redirect">/index.html</result>
			<result name="error">/login.jsp</result>
		</action>
 	</package>
</struts>

封装参数

servlet:导入包BeanUtils,根据name属性自动封装
struts:实现ModelDriven接口,实现getModel方法

转发与重定向

Servlet

转发
request.getRequestDispatcher("/login.jsp").forward(request, response);;
重定向
response.sendRedirect(request.getContextPath()+"/index.html");

struts

转发:package—action—result默认为转发

<!-- name配置包名 -->
	<package name="MyPackage" namespace="/" extends="struts-default">	
		<action name="LoginAction" class="com.sikiedu.web.UserAction" method="execute">
			<result name="success" >/index.html</result><!-- 默认此处为转发-->
			<result name="error">/login.jsp</result>
		</action>
 	</package>

重定向 package—action—result中的type=“redirect”

<package name="MyPackage" namespace="/" extends="struts-default">	
		<action name="LoginAction" class="com.sikiedu.web.UserAction" method="execute">
			<result name="success" type="redirect">/index.html</result><!--重定向 -->
			<result name="error">/login.jsp</result>
		</action>
 	</package>

struts创建Action的三种方式

继承ActionSupport并实现ModelDriven的接口然后在struts.xml中配置action

package com.sikiedu.web;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.sikiedu.domain.User;
import com.sikiedu.service.UserService;

public class UserAction extends ActionSupport implements ModelDriven<User>{

	public User user=new User();
	
	
	public String execute() throws Exception {
		System.err.println("我已经运行");
		UserService userService=new UserService();
		boolean success=userService.findUser(user);
		if(success) {
			return "success";
		}else {
			ServletActionContext.getRequest().setAttribute("error", "用户名或密码错误");
			return "error";
		}	
	}
	@Override
	public User getModel() {
		// TODO Auto-generated method stub
		return user;
	}
}
<struts>
	<!-- name配置包名 -->
	<package name="MyPackage" namespace="/" extends="struts-default">	
		<action name="LoginAction" class="com.sikiedu.web.UserAction" method="execute">
			<result name="success" type="redirect">/index.html</result>
			<result name="error">/login.jsp</result>
		</action>
 	</package>
</struts>

不继承父类也不实现任何接口,创建一个XXXAction类并构建一个execute方法,然后在struts.xml中配置

package com.sikiedu.web;

public class DefaultAction {
	public String execute(){
		System.out.println("这是一个普通的action");
		return null;
	}
}
<package name="MyPackage" namespace="/" extends="struts-default">	
		<action name="LoginActionDefault" class="com.sikiedu.web.DefaultAction" method="execute"></action>
 </package>

创建一个XXXAction只实现Action接口,然后在struts.xml中配置

package com.sikiedu.web;

import com.opensymphony.xwork2.Action;

public class ImplAction implements Action {

	@Override
	public String execute() throws Exception {
		System.out.println("这是实现了Action接口的Action");
		return null;
	}
	
}
<action name="LoginImplAction" class="com.sikiedu.web.ImplAction" method="execute"></action>

总结

实现Action接口的方法比什么都不继承和实现的方法要好

继承ActionSupport并实现ModelDriven接口的方法要比只实现Action接口的方法更完善

如何创建struts.xml

核心配置

<struts>
	
	<!-- name配置包名 -->
	<!--namespace:给Action的访问路径定义一个命名空间   namespace="/user"  则需要访问http://localhost:8080/StrutsForum/user/LoginAction -->
	<package name="MyPackage" namespace="/" extends="struts-default">	
		<!-- action:配置action类
			name:决定了action访问的资源名称 相当于servlet:url-pattern
			class:action的完整类名
			method:制定调用action中的哪个方法来去处理请求-->
		<action name="LoginAction" class="com.sikiedu.web.UserAction" method="execute">
			<result name="success" type="redirect">/index.html</result>
			<result name="error">/login.jsp</result>
		</action>
		
		<action name="LoginActionDefault" class="com.sikiedu.web.DefaultAction" method="execute"></action>
 		
 		<action name="LoginActionImpl" class="com.sikiedu.web.ImplAction" method="execute"></action>
 	</package>
</struts>

动态方法调用

struts.xml 根目录/LoginAction_方法名

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
	<!--struts2.5版本之后  动态方法需要声明下 -->
	<constant name="struts.devMode" value="true"></constant>
	<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
	
	<package name="MyPackage" namespace="/" extends="struts-default">	
		<global-allowed-methods>login,register</global-allowed-methods>
		<action name="LoginAction_*" class="com.sikiedu.web.UserAction" method="{1}">
			<result name="success" type="redirect">/index.html</result>
			<result name="error">/login.jsp</result>
		</action>
 	</package>
</struts> 
	public String login() throws Exception {
		System.err.println("login方法");
		UserService userService=new UserService();
		boolean success=userService.findUser(user);
		if(success) {
			return "success";
		}else {
			ServletActionContext.getRequest().setAttribute("error", "用户名或密码错误");
			return "error";
		}	
	}
	
	public String register() throws Exception{
		System.out.println("register方法");
		return null;
	}

结果集的处理

1.转发

2.重定向

3.转发到Action

struts.xml

		<action name="LoginActionDefault" class="com.sikiedu.web.DefaultAction" method="execute"></action>
 		
 		<action name="LoginActionImpl" class="com.sikiedu.web.ImplAction" method="execute">
 			<!-- 转发到LoginActionDefault -->
 			<result name="defaultAction" type="chain">LoginActionDefault</result>
 		</action>

ImplAction.java

public class ImplAction implements Action {

	@Override
	public String execute() throws Exception {
		System.out.println("这是实现了Action接口的Action");
		return "defaultAction";
	}
	
}

DefaultAction.java

public class DefaultAction { 
	public String execute(){
		System.out.println("这是一个普通的action");
		return null;
	}
}

输入 根目录/LoginActionImpl 控制台输出顺序 这是实现了Action接口的Action—>这是一个普通的action

跳转是由result来完成 而此时的路径还是根目录/LoginActionImp 转发路径是不会更改的

4.重定向到Action

ImplAction.java

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;

public class ImplAction implements Action {

	@Override
	public String execute() throws Exception {
		System.out.println("这是实现了Action接口的Action");
		return "defaultAction";
	}
	
	public String login() {
		//得到原生的request域  这里设置的名字和密码都是错误的
//		ServletActionContext.getRequest().setAttribute("username", "123");
//		ServletActionContext.getRequest().setAttribute("password", "123");
		
		//使用的是ActionContext
		ActionContext.getContext().put("username", "123");
		ActionContext.getContext().put("password", "123");
		return "toLogin";
	}
}

struts.xml 浏览器输入 根目录/LoginActionImpl_login 即为调用LoginActionImpl的login方法

然后在LoginActionImpl的login方法中接收到toLogin的参数正好调用result name=“toLogin” type="redirectAction"的结果集,在这个结果集中

又指定了重定向到LoginAction_Login方法上,并传出两个参数

<struts>
	<!--struts2.5版本之后  动态方法需要声明下 -->
	<constant name="struts.devMode" value="true"></constant>
	<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
	
	<package name="MyPackage" namespace="/" extends="struts-default">	
		<!-- regex:.*   可以指代所有方法 -->
		<global-allowed-methods>regex:.*</global-allowed-methods>

		<action name="LoginAction_*" class="com.sikiedu.web.UserAction" method="{1}">
			<result name="success" type="redirect">/index.html</result>
			<result name="error">/login.jsp</result>
		</action>
		
		<action name="LoginActionDefault" class="com.sikiedu.web.DefaultAction" method="execute"></action>
 		
 		<action name="LoginActionImpl_*" class="com.sikiedu.web.ImplAction" method="{1}">
 			<!-- 转发到LoginActionDefault -->
 			<result name="defaultAction" type="chain">LoginActionDefault</result>
            
 			<!-- 重定向到Action(LoginAction_*) -->
 			<result name="toLogin" type="redirectAction">
 				<param name="actionName">LoginAction_login</param><!-- 这个是指定重定向action的名字 -->
 				<param name="username">${username}</param>
 				<param name="password">${password}</param>
 			</result>
 		</action>
 	</package>
</struts>

UserAction.java LoginAction_login方法

	public String login() throws Exception {
		System.err.println("login方法");
		System.err.println(user.getUsername());
		
        UserService userService=new UserService();
		boolean success=userService.findUser(user);
		if(success) {
			return "success";
		}else {
			ServletActionContext.getRequest().setAttribute("error", "用户名或密码错误");
			return "error";
		}	
	}

最终页面链接显示 根目录/LoginAction_login.action?username=123&password=123

页面显示 用户名或密码错误 控制台打印 login方法 123

log4j的配置以及解决中文乱码

lib下需要加入log4j-api-2.12.1.jar和log4j-core-2.11.0.jar并buildPath,然后在src下创建log4j.xml

<?xml version="1.0" encoding="UTF-8"?>
    <Configuration>
        <Appenders>
            <Console name="STDOUT" target="SYSTEM_OUT">
                <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
            </Console>
            <RollingFile name="RollingFile" fileName="logs/strutslog1.log"
                         filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
                <PatternLayout>
                    <Pattern>%d{MM-dd-yyyy} %p %c{1.} [%t] -%M-%L- %m%n</Pattern>
                </PatternLayout>
                <Policies>
                    <TimeBasedTriggeringPolicy />
                    <SizeBasedTriggeringPolicy size="1 KB"/>
                </Policies>
                <DefaultRolloverStrategy fileIndex="max" max="2"/>
            </RollingFile>
        </Appenders>
        <Loggers>
            <Logger name="com.opensymphony.xwork2" level="WAN"/>
            <Logger name="org.apache.struts2" level="WAN"/>
            <Root level="warn">
                <AppenderRef ref="STDOUT"/>
            </Root>
        </Loggers>
    </Configuration>

解决中文乱码,如下所示

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>StrutsForum</display-name>
  
  <filter>
  	<filter-name>struts2</filter-name>
  	<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter.class</filter-class>
  	<init-param><!-- 解决中文乱码 -->
  		<param-name>encoding</param-name>
  		<param-value>UTF-8</param-value>
  	</init-param>
  </filter>
  
  <filter-mapping>
  	<filter-name>struts2</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

参数传递

接收参数

第一种

在XxxAction(此Action要继承ActionSupport并且实现ModelDriven<传入对象>接口)中New一个domain包下的对象,并在getModel方法中返回你New的那个对象

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.sikiedu.domain.User;
import com.sikiedu.service.UserService;

public class UserAction extends ActionSupport implements ModelDriven<User>{

	public User user=new User();//一定要New出来,并且不能加get和set方法
	
	
	public String login() throws Exception {
		System.out.println("login方法");
		System.out.println(user.getUsername());
		UserService userService=new UserService();
		boolean success=userService.findUser(user);
		if(success) {
			return "success";
		}else {
			ServletActionContext.getRequest().setAttribute("error", "用户名或密码错误");
			return "error";
		}	
	}
	
	public String register() throws Exception{
		System.out.println("register方法");
		return null;
	}

	@Override
	public User getModel() {
		// TODO Auto-generated method stub
		return user;//这里要返回你创建的那个对象
	}
		
}

第二种方法 属性驱动

此Action只继承ActionSupport但并不实现ModelDriven<对象>接口,你需要把使用的属性和对象创建出来并把属性加入对象中

这种方法需要在此类中添加属性的get和set方法

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.sikiedu.domain.User;
import com.sikiedu.service.UserService;

public class UserAction extends ActionSupport {

	public String username;
	public String password;
	
	public String login() throws Exception {
		System.out.println("login方法");
		System.out.println(username+":"+password);
		
		User user=new User();
		user.setUsername(username);
		user.setPassword(password);
		UserService userService=new UserService();
		boolean success=userService.findUser(user);
		if(success) {
			return "success";
		}else {
			ServletActionContext.getRequest().setAttribute("error", "用户名或密码错误");
			return "error";
		}	
	}
	
	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;
	}

	public String register() throws Exception{
		System.out.println("register方法");
		return null;
	}
		
}

第三种

此Action只继承ActionSupport但并不实现ModelDriven<对象>接口,需要声明一个对象并添加get和set方法,而且在login.jsp中的登陆表单中的input标签中的name="username"变成name=“user.username”,password与这个一样

<form action="${pageContext.request.contextPath}/LoginAction_login" method="post">
			<div class="register-box">
				<label for="username" class="username_label"> 用 户 名 <input
					maxlength="20" name="user.username" type="text" placeholder="您的用户名和登录名" />
				</label>       <!--本来是name="username"  更改了name属性-->
				<div class="tips"></div>
			</div>
			<div class="register-box">
				<label for="username" class="other_label"> 设 置 密 码 <input
					maxlength="20" type="password" name="user.password"   
					placeholder="建议至少使用两种字符组合" />   <!--本来是name="password"  更改了name属性-
				</label>
				<div class="tips" style="color:red">${error }</div>
			</div>
			<div class="arguement">
				<input type="checkbox" id="xieyi" /> 阅读并同意 <a
					href="javascript:void(0)">《你问我答用户注册协议》</a> <a href="register.html">没有账号,立即注册</a>
				<div class="tips"></div>
			</div>
			<div class="submit_btn">
				<button type="submit" id="submit_btn">立 即 登录</button>
			</div>
		</form>
import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.sikiedu.domain.User;
import com.sikiedu.service.UserService;

public class UserAction extends ActionSupport {

	public User user; //注意 声明的这个对象需要添加get和set方法
	public String login() throws Exception {
		System.out.println("login方法");
		System.out.println(user.getUsername()+":"+user.getPassword());

		UserService userService=new UserService();
		boolean success=userService.findUser(user);
		if(success) {
			return "success";
		}else {
			ServletActionContext.getRequest().setAttribute("error", "用户名或密码错误");
			return "error";
		}	
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String register() throws Exception{
		System.out.println("register方法");
		return null;
	}
		
}

传递参数

ActionContext是一个Map集合 你想获取的参数都在ActionContext中,ActionContext域比原生的Request和Response域更加强大

在这里插入图片描述

public String login() {
		//得到原生的request域  这里设置的名字和密码都是错误的
//		ServletActionContext.getRequest().setAttribute("username", "123");
//		ServletActionContext.getRequest().setAttribute("password", "123");
		
		//ActionConext 与request 生命周期是一样的  但是这两个是两个域
		//使用的是ActionContext的put  其实是直接在request域的调用setAttr 
		ActionContext.getContext().put("username", "123");
		ActionContext.getContext().put("password", "123");
		
		//获取Session
		Map<String,Object> session=ActionContext.getContext().getSession();
		session.put(key, value);
		
		//获取Application
		Map<String,Object> application=ActionContext.getContext().getApplication();
		application.put(key, value);
    
    	//获得原生的request
		HttpServletRequest request=ServletActionContext.getRequest();
		
		//获得 原生的response
		HttpServletResponse response=ServletActionContext.getResponse();
	
		return "toLogin";
	}

接受传递过来的参数 这个两段代码是重定向到某一个Action里的方法内添加的

		System.out.println("session域:::::"+ActionContext.getContext().getSession().get("mysession"));
		System.out.println("application域::::"+ActionContext.getContext().getApplication().get("myapplication"));

ognl表达式

ognl其实就相当于jstl+el 导入标签 <%@taglib uri="/struts-tags" prefix=“s”%>

<div class="tab">
				<s:iterator value="pasteList" var="paste">
					<div class="dvques">
						<div class="quesCount">
							<div class="count">
								<s:property value="#paste.ansnum" /><!-- 如果要访问的数据是包装类型,我们要加# -->
							</div>
							<div class="ques">回答数</div>
						</div>
						<div class="quesContent">
							<div class="quesTitle">
								<s:property value="offer" />
								<image src="images/bean.jpg" class="bean"> <span
									class="spanques"> <s:property value="#paste.title" />
								</span>
							</div>
							<div class="qContent">
								<s:property value="#paste.content" />
							</div>
							<div class="tags">
								<span class="tag">excel</span><span class="tag">程序</span>
							</div>
							<div class="quesUser">
								<image src="images/0.gif" class="imguser" />
								<div class="userName">
									
									<s:if test="ansnum%2 == 0">
										张大值
									</s:if>
									<s:else>
										XXX
									</s:else>
									
									<div class="liulan">浏览(9) 30分钟前</div>
								</div>

							</div>
						</div>
					</div>
				</s:iterator>
			</div>

valueStack分析三种获得表单数据原理

像当request session application三个域中都有name属性,<s:property value="#name"/>会先从request中取,然后session,再application

在这里插入图片描述

action的原理

interceptor是拦截器,拦截器其实是个stack

在这里插入图片描述

result的原理

<action name="LoginActionImpl_*" class="com.sikiedu.web.ImplAction" method="{1}">
 			<!-- 转发到LoginActionDefault -->
 			<result name="defaultAction" type="chain">
 				<param name="actionName">LoginActionDefault</param>
 			</result>
 			<!-- 重定向到Action(LoginAction_*) -->
 			<result name="toLogin" type="redirectAction">
 				<param name="actionName">LoginAction_login</param><!-- 这个是指定重定向action的名字 -->
 				<param name="username">${username}</param>
 				<param name="password">${password}</param>
 			</result>
 </action>

拦截器

创建拦截器的两种方式

每次访问有拦截器的Action就会调用一次拦截器,拦截器只能控制访问Action,不能控制访问jsp

第一种 继承MethodFilterInterceptor类

package com.sikiedu.web.intercept;

import java.util.Map;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
//推荐这一种方法
public class MyIntercept  extends MethodFilterInterceptor{

	@Override
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		
		
		//获取session
		Map<String,Object> session=ActionContext.getContext().getSession();
		//判断session中是否有user数据
		Object object=session.get("user");
			if(object!=null) {
				//有 放行
				return invocation.invoke();
			}else {
				//没有,重定向到login.jsp
				return "toLogin";
			}
	}

第二种 实现Interceptor接口

package com.sikiedu.web.intercept;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;

public class Intercept  implements Interceptor{

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void init() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		
		
		//放行
		return invocation.invoke();
	}
	
}

struts.xml中拦截器的配置 配置全局结果集用global-results标签注意使用顺序

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
	<!--struts2.5版本之后  动态方法需要声明下 -->
	<constant name="struts.devMode" value="true"></constant>
	<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
	
	<package name="MyPackage" namespace="/" extends="struts-default">	
		<interceptors>
			<!--注册拦截器 -->
			<interceptor name="myIntercept" class="com.sikiedu.web.intercept.MyIntercept"></interceptor>
			<!-- 注册拦截器的栈 -->
			<interceptor-stack name="myStack">
				<!-- 引入自己创建的拦截器 -->
				<interceptor-ref name="myIntercept"></interceptor-ref>
				<!-- 引入struts给你写的拦截器(20个左右)-->
				<interceptor-ref name="defaultStack"></interceptor-ref>
			</interceptor-stack>
		</interceptors>
		
		<!-- 指定包中的默认拦截器栈 -->
		<default-interceptor-ref name="myStack"></default-interceptor-ref>
		
		<!-- 配置全局结果集   相当于在每一个包下的action下都写了一个,
			注意顺序 default-class-ref?, global-results?, global-allowed-methods?-->
		<global-results>
			<result name="toLogin" type="redirect">/login.jsp</result>
		</global-results>
	
		<!-- regex:.*   可以指代所有方法 -->
		<global-allowed-methods>regex:.*</global-allowed-methods>
		<action name="LoginAction_*" class="com.sikiedu.web.UserAction" method="{1}">
			<!-- 设置默认为转发 -->
			<result name="success" type="redirect">/index.html</result>
			<result name="error">/login.jsp</result>
		</action>
		<action name="LoginActionDefault" class="com.sikiedu.web.DefaultAction" method="execute"></action>
 		<action name="LoginActionImpl_*" class="com.sikiedu.web.ImplAction" method="{1}">
 			<!-- 转发到LoginActionDefault -->
 			<result name="defaultAction" type="chain">LoginActionDefault</result>
 			<!-- 重定向到Action(LoginAction_*) -->
 			<result name="toLogin" type="redirectAction">
 				<param name="actionName">LoginAction_login</param><!-- 这个是指定重定向action的名字 -->
 				<param name="username">${username}</param>
 				<param name="password">${password}</param>
 			</result>
 		</action>
 	</package>
</struts>

总结-一个struts小案例

bug

本人学习struts时,一直出现下面错误,上网搜索后没有得到正确的解决结果
处理方法是web.xml文件中配置struts的filter-class标签中引用filter的类名不要加.class后缀就可以了
就如org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter这样子去掉.class后缀即可

严重: 启动过滤器异常
java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter.class
	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1360)
	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1182)
	at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:546)
	at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:527)
	at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:150)
	at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:262)
	at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:108)
	at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4546)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5191)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1412)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1402)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)

这些是我导的jar包和目录工程

在这里插入图片描述

在这里插入图片描述

package包及class

com.sikiedu.dao

PasteDao.java
package com.sikiedu.dao;

import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import com.sikiedu.domain.Paste;
import com.yl.lain.utils.C3p0DataSourceUtils;

public class PasteDao {

	public List<Paste> findAllPaste() throws SQLException {
		QueryRunner runner=new QueryRunner(C3p0DataSourceUtils.getDataSource());
		String sql="select * from paste";
		return runner.query(sql, new BeanListHandler<Paste>(Paste.class));
	}
	
}
UserDao.java
package com.sikiedu.dao;

import java.sql.SQLException;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import com.sikiedu.domain.User;
import com.yl.lain.utils.C3p0DataSourceUtils;

public class UserDao {
	public User findUser(User user) throws SQLException {
		QueryRunner runner=new QueryRunner(C3p0DataSourceUtils.getDataSource());
		String sql="select * from user  where username=? and password=?";
		return runner.query(sql,new BeanHandler<User>(User.class),user.getUsername(),user.getPassword());
		
	}
}

com.sikiedu.domain

Paste.java
package com.sikiedu.domain;

public class Paste {
	
	private  String id;
	private Integer ansnum;
	private Integer offer;
	private String title;
	private String content;
	
	//这里是省略了get和set方法以及有参构造方法
	
}
User.java
package com.sikiedu.domain;

public class User {
	private String username;
	private String password;
	
	//这里是省略了get和set方法以及有参构造方法
}

com.sikiedu.service

PasteService.java
package com.sikiedu.service;

import java.sql.SQLException;
import java.util.List;

import com.sikiedu.dao.PasteDao;
import com.sikiedu.domain.Paste;

public class PasteService {

	public List<Paste> findAllPaste() throws SQLException {
		PasteDao pasteDao =new PasteDao();
		
		return pasteDao.findAllPaste();
	}
	
	
}
UserService.java
package com.sikiedu.service;

import java.sql.SQLException;

import com.sikiedu.dao.UserDao;
import com.sikiedu.domain.User;

public class UserService {
		public boolean findUser(User user) throws SQLException {
			UserDao userDao=new UserDao();
			User temp=userDao.findUser(user);
			return temp==null?false:true;
		}
}

com.sikiedu.web

PasteAction.java
package com.sikiedu.web;

import java.util.List;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.sikiedu.domain.Paste;
import com.sikiedu.service.PasteService;

public class PasteAction extends ActionSupport {

	public String getAllPaste() throws Exception {
		PasteService pasteService=new PasteService();
		List<Paste> pasteList=pasteService.findAllPaste();
		ActionContext.getContext().put("pasteList",pasteList );
		return "index";
	}
	
}
UserAction.java
package com.sikiedu.web;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.sikiedu.domain.User;
import com.sikiedu.service.UserService;

public class UserAction extends ActionSupport implements ModelDriven<User> {
	public User user=new User();
	
	public String login() throws Exception {
		
		//封装User
		
		//调用UserService中的判断用户是否存在的方法
		
		UserService userService=new UserService();
		boolean isSuccess=userService.findUser(user);
		//拿到返回值
		if(isSuccess) {
			//成功 在session域中放置user对象
			ActionContext.getContext().getSession().put("user", user);
			return "getAllPaste";
		}else {
			//失败  添加错误信息  转发到login.jsp
			ActionContext.getContext().put("error", "用户名或密码错误");
			return "login";	
		}
		
	}
	@Override
	public User getModel() {
		// TODO Auto-generated method stub
		return user;
	}
		
	
}

com.sikiedu.web.intercept

UserIntercept.java
package com.sikiedu.web.intercept;

import java.util.Map;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
//创建拦截器  如果用户没有登陆就在login.jsp页面
public class UserIntercept  extends MethodFilterInterceptor{

	@Override
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		
		
		//获取session
		Map<String,Object> session=ActionContext.getContext().getSession();
		//判断session中是否有user数据
		Object object=session.get("user");
			if(object!=null) {
				//有 放行
				return invocation.invoke();
			}else {
				//没有,重定向到login.jsp
				return "toLogin";
			}
	}
	
}

src下的c3p0-config.xml和struts.xml

c3p0-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
	<default-config>
		<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql://localhost:3306/struts?useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=GMT%2B8</property>
		<property name="user">login</property>
		<property name="password">123</property>
		<property name="initialPoolSize">5</property>
		<property name="maxPoolSize">20</property>
	</default-config>
</c3p0-config>

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
	<!-- 动态结果集 -->
	<constant name="struts.devMode" value="true"></constant>
	<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
	
	
	<package name="fourm" namespace="/" extends="struts-default">
		<interceptors>
			<!--注册拦截器 -->
			<interceptor name="UserIntercept" class="com.sikiedu.web.intercept.UserIntercept"></interceptor>
			<!-- 注册拦截器的栈 -->
			<interceptor-stack name="myStack">
				<!-- 引入自己创建的拦截器 -->
				<interceptor-ref name="UserIntercept">
					<!-- 不让拦截器拦截login方法 -->
					<param name="excludeMethods">login</param>
				</interceptor-ref>
				<!-- 引入struts自带的拦截器-->
				<interceptor-ref name="defaultStack"></interceptor-ref>
			</interceptor-stack>
		</interceptors>
		
		<!-- 指定包中的默认拦截器栈 -->
		<default-interceptor-ref name="myStack"></default-interceptor-ref>
		
		<!-- 在UserIntercept中没有的话会返回toLogin,但是在每个Action中写一个太麻烦了所以定义一个全局结果集 -->
		<global-results>
			<!-- 重定向 -->
			<result name="toLogin" type="redirect">/login.jsp</result>
		</global-results>
		<global-allowed-methods>regex:.*</global-allowed-methods> <!-- 动态方法调用 -->
		<action name="UserAction_*" class="com.sikiedu.web.UserAction" method="{1}">
 			<!-- 转发到Action --> 
		<!--<result name="getAllPaste" type="chain">PasteAction_getAllPaste</result> -->
			
			<!-- 重定向到Action -->
			<result name="getAllPaste" type="redirectAction">PasteAction_getAllPaste</result>
			<!-- 默认转发 -->
			<result name="login">/login.jsp</result>
		</action>
		
		<action name="PasteAction_*" class="com.sikiedu.web.PasteAction" method="{1}">
			<result name="index">/index.jsp</result>
		</action>
	</package>
</struts>

/ForumProject/WebContent/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>ForumProject</display-name>

  <filter>
  	<filter-name>Struts2</filter-name>
  	<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class><!--注意这里千万不能加.class后缀,会报过滤器异常错误-->
  	<init-param>
  		<param-name>encoding</param-name>
  		<param-value>UTF-8</param-value>
  	</init-param>
  </filter>
  <filter-mapping>
  	<filter-name>Struts2</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

ForumProject/WebContent/下的jsp文件

index.jsp 注意ognl表达式的使用 <s:property value=" "/>

<div class="tabContent">
			<div class="dvtags">
				<a class="curenttag">待解决</a><span class="line"></span><a>高分</a><span
					class="line"></span><a>新回答</a><span class="line"></span><a>已解决</a>
			</div>
			<div class="tab">
				<s:iterator value="pasteList" var="paste">
					<div class="dvques">
						<div class="quesCount">
							<div class="count">
								<s:property value="#paste.ansnum" /><!-- 如果要访问的数据是包装类型,我们要加# -->
							</div>
							<div class="ques">回答数</div>
						</div>
						<div class="quesContent">
							<div class="quesTitle">
								<s:property value="#paste.offer" />
								<image src="images/bean.jpg" class="bean"> <span
									class="spanques"> <s:property value="#paste.title" />
								</span>
							</div>
							<div class="qContent">
								<s:property value="#paste.content" /> <!-- ognl内置标签 -->
							</div>
							<div class="tags">
								<span class="tag">excel</span><span class="tag">程序</span>
							</div>
							<div class="quesUser">
								<image src="images/0.gif" class="imguser" />
								<div class="userName">
									
									<s:if test="ansnum%2 == 0">
										张大值
									</s:if>
									<s:else>
										XXX
									</s:else>
									
									<div class="liulan">浏览(9) 30分钟前</div>
								</div>

							</div>
						</div>
					</div>
				</s:iterator>
			</div>
			<div class="tab hidden">2</div>
			<div class="tab hidden">3</div>
			<div class="tab hidden">4</div>
		</div>

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
	<%@taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>

<head>
<meta charset="UTF-8">

<link rel="stylesheet" href="css/head.css" />
<link rel="stylesheet" type="text/css" href="css/login.css" />
</head>

<body>
	<div class="dvhead">
		<div class="dvlogo">
			<a href="index.html">你问我答</a>
		</div>
		<div class="dvsearch">10秒钟注册账号,找到你的同学</div>
		<div class="dvreg">
			已有账号,立即&nbsp;<a href="login.html">登录</a>
		</div>
	</div>
	<section class="sec">
		<form action="${pageContext.request.contextPath}/UserAction_login" method="post">
			<div class="register-box">
				<label for="username" class="username_label"> 用 户 名 <input
					maxlength="20" name="username" type="text" placeholder="您的用户名和登录名" />
				</label>
				<div class="tips"></div>
			</div>
			<div class="register-box">
				<label for="username" class="other_label"> 设 置 密 码 <input
					maxlength="20" type="password" name="password"
					placeholder="建议至少使用两种字符组合" />
				</label>
				<div class="tips" style="color:red">${error }</div>
			</div>
			<div class="arguement">
				<input type="checkbox" id="xieyi" /> 阅读并同意 <a
					href="javascript:void(0)">《你问我答用户注册协议》</a> <a href="register.html">没有账号,立即注册</a>
				<div class="tips" style="color:red"> <s:property value="#error"/> </div>
			</div>
			<div class="submit_btn">
				<button type="submit" id="submit_btn">立 即 登录</button>
			</div>
		</form>
	</section>
	<script src="js/index.js" type="text/javascript" charset="utf-8"></script>
</body>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值