how2j.cn

下载区
文件名 文件大小
struts.rar 9m
struts2-convention-plugin-2.1.7.jar 64k

解压rar如果失败,请用5.21版本或者更高版本的winrar

点击下载 winrar5.21

工具版本兼容问题
以上的教程都是基于XML进行配置的,除此之外,Struts还能够基于注解进行配置


步骤 1 : 先运行,看到效果,再学习   
步骤 2 : 模仿和排错   
步骤 3 : 基于前面的教程   
步骤 4 : jar   
步骤 5 : 注释掉struts.xml   
步骤 6 : 添加注解   
步骤 7 : 运行测试   
步骤 8 : 其他常用注解   
步骤 9 : 总结   

步骤 1 :

先运行,看到效果,再学习

edit
老规矩,先下载右上角的可运行项目,配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。

访问页面:

http://127.0.0.1:8080/struts/showProduct
先运行,看到效果,再学习
在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。
模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较正确答案 ( 可运行项目 ) 和自己的代码,来定位问题所在。
采用这种方式,学习有效果,排错有效率,可以较为明显地提升学习速度,跨过学习路上的各个槛。

推荐使用diffmerge软件,进行文件夹比较。把你自己做的项目文件夹,和我的可运行项目文件夹进行比较。
这个软件很牛逼的,可以知道文件夹里哪两个文件不对,并且很明显地标记出来
这里提供了绿色安装和使用教程:diffmerge 下载和使用教程
步骤 3 :

基于前面的教程

edit
这个知识,基于显示数据到JSP 这个知识点,把其由xml配置方式,改造为注解方式
1. 为了使struts支持注解,需要用到struts2-convention-plugin-x.x.x.jar 这个jar包,在前面的教程中是没有使用的,所以这里需要从右侧下载

2. 下载好了之后,放在WEB-INF/lib 下

3. 不仅如此,还要在项目导入jar,以使得eclipse能够编译通过
jar
步骤 5 :

注释掉struts.xml

edit
接着就把struts.xml中的配置信息注释掉,以确保最后生效的是注解方式
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="basicstruts" extends="struts-default"> <!-- <action name="showProduct" class="com.how2java.action.ProductAction" method="show"> --> <!-- <result name="show">show.jsp</result> --> <!-- </action> --> </package> </struts>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
 
<struts>
  <package name="basicstruts" extends="struts-default">
 
<!--   <action name="showProduct" class="com.how2java.action.ProductAction" method="show"> -->
<!--     <result name="show">show.jsp</result> -->
<!--   </action>     -->
 
</package>
 
</struts>
然后就是在ProductAction类上面添加注解
1. 在类前面添加3个注解

@Namespace("/")

表示访问路径,如果是@Namespace("/test"),那么访问的时候,就需要写成http://127.0.0.1:8080/struts/test/showProduct

@ParentPackage("struts-default")

与配置文件中的struts-default相同,表示使用默认的一套拦截器

@Results({@Result(name="show", location="/show.jsp"),
@Result(name="home", location="/index.jsp")})

预先定义多个results, "show" 返回"/show.jsp" , "home" 返回 "/index.jsp".
注: 这里并没有用到"home",写出来的目的是为了演示这种定义多个result 的代码风格。

2. 在show方法前加上注解:

@Action("showProduct")

表示当访问路径是showProduct的时候,就会调用show方法
package com.how2java.action; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Namespace; import org.apache.struts2.convention.annotation.ParentPackage; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.Results; import com.how2java.bean.Product; @Namespace("/") @ParentPackage("struts-default") @Results({@Result(name="show", location="/show.jsp"), @Result(name="home", location="/index.jsp")}) public class ProductAction { private Product product; @Action("showProduct") public String show() { product = new Product(); product.setName("iphone7"); return "show"; } public Product getProduct() { return product; } public void setProduct(Product product) { this.product = product; } }
显示数据到JSP一样,访问如下路径就可以看到一样的结果

http://127.0.0.1:8080/struts/showProduct
运行测试
步骤 8 :

其他常用注解

edit
Namespace:指定命名空间。
ParentPackage:指定父包。

Result:提供了Action结果的映射。(一个结果的映射)
Results:“Result”注解列表
ResultPath:指定结果页面的基路径。

Action:指定Action的访问URL。
Actions:“Action”注解列表。

ExceptionMapping:指定异常映射。(映射一个声明异常)
ExceptionMappings:一级声明异常的数组。

InterceptorRef:拦截器引用。
InterceptorRefs:拦截器引用组。

一般说来,不是所有的注解都会用到,真正用到哪个的时候再来查一下就知道怎么回事了。
可以看出来,注解方式,就是把本来做在struts.xml里的事情,搬到了Action类里面来做。
那么到底应该用注解还是配置呢?从个人经验来讲,小项目适合用注解,大项目因为其复杂性,采用注解会导致配置信息难以维护和查询,更适合采用xml配置方式。

关于注解是如何生效的,请查看自定义注解相关知识。


HOW2J公众号,关注后实时获知最新的教程和优惠活动,谢谢。


问答区域    
2020-04-29 @InterceptorRef("InterceptorStack")报错没找到相关类
hz52




错误详情 Caused by: Unable to find interceptor class referenced by ref-name InterceptorStack - [unknown location]
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.InterceptorRefs;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

import lombok.Data;

@Data
@Namespace("/")
@ParentPackage("struts-default")
public class ProductAction 
{
	private Product product;
	private List<Product> list;
	private List<Integer> checkList;
	private List<Category> categories=new ArrayList<>();
	private Date date;
	private String name;
	
	@Action(value="showProduct",results= {@Result(name="show",location="/show.jsp")})
	public String show()
	{
		product=new Product(1,"小米");
		HttpSession s=ServletActionContext.getRequest().getSession();
		s.setAttribute("name1", "苹果");
		Map map=ActionContext.getContext().getSession();
		map.put("name2", "oppo");
		return "show";
	}
	
	public String add()
	{
		System.out.println("product name: "+product.getName());
		return "show";
	}
	
	@Action(value="list",results= {@Result(name="success",location="/list.jsp")} 
	,interceptorRefs= {@InterceptorRef("InterceptorStack"),@InterceptorRef("defaultStack")})
	public String list()
	{
		list=new ArrayList<>();
		
		Product p1=new Product(1,"小米");
		Product p2=new Product(2, "华为");
		Product p3=new Product(3,"oppo");
		Product p4=new Product(4, "vivo");
		
		list.add(p1);
		list.add(p2);
		list.add(p3);
		list.add(p4);
		
		checkList=new ArrayList();
		checkList.add(1);
		checkList.add(2);
		
		Category c1=new Category(1,"c1",list);
		Category c2=new Category();
		c2.setId(2);
		c2.setName("c2");
		List<Product> list2=new ArrayList<Product>();
		list2.add(p4);
		list2.add(p3);
		c2.setProducts(list2);
		
		categories.add(c1);
		categories.add(c2);
		return "success";
	}
	
	public String addPage()
	{
		name="default_name";
		System.out.println(name);
		return "addPage";
	}
	
	
}
XML

<package name="basicstruts" extends="struts-default">
 
<interceptors >
<interceptor name="dateInterceptor" class="action.DateInterceptor"></interceptor>
<interceptor-stack name="InterceptorStack">
	<interceptor-ref name="dateInterceptor"/>
</interceptor-stack>

</interceptors> 





回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到





2019-11-08 404错误
Jqh




在使用注解的时候 jar导入了而且放在lib里面了 但是还是显示404错误
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Namespace("/")//表示默认路径下/下面定义的action
@ParentPackage("struts-default")//默认拦截器
@Results({
	@Result(name="show",location="/show.jsp")//返回的字符串 和跳转的jsp
})
public class ProductAction {
    private Product product;
    @Action("showProduct")
    public String show() {
    	
    	//用于控制product
        product = new Product();
        product.setName("iphone7");
        //这个返回值要和struts里对应Action里的一个result的name属性值相同
        return "show";
    }
    private String name;
    
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
Type Status Report

Message There is no Action mapped for namespace / and action name showProduct.

Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.


2 个答案

丹心
答案时间:2022-12-03
厉害,感谢楼上的回答,解决了我的问题。

hz52
答案时间:2020-04-29
你的包名是不是不是啥Action 我在网上查到了这个问题的答案,夸我!夸我! 以下是Struts2的原文文档: First the Convention plugin finds packages named struts, struts2, action or actions. Any packages that match those names are considered the root packages for the Convention plugin. Next, the plugin looks at all of the classes in those packages as well as sub-packages and determines if the classes implementcom.opensymphony.xwork2.Action or if their name ends with Action (i.e. FooAction). 也就是说,如果要用Struts2的注解,你还非得将action处理类放在struts, struts2, action, actions包或者其子包中。以前总是习惯性的将所有的action处理类放在com.xxx.action下,以为仅仅是习惯而已,没曾想Struts2还就是这么规定的。



回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到





2018-05-02 404错误




提问之前请登陆
提问已经提交成功,正在审核。 请于 我的提问 处查看提问记录,谢谢
关于 JAVA 框架-Struts-注解方式 的提问

尽量提供截图代码异常信息,有助于分析和解决问题。 也可进本站QQ群交流: 578362961
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
在已经存在的几千个提问里,有相当大的比例,是因为使用了和站长不同版本的开发环境导致的,比如 jdk, eclpise, idea, mysql,tomcat 等等软件的版本不一致。
请使用和站长一样的版本,可以节约自己大量的学习时间。 站长把教学中用的软件版本整理了,都统一放在了这里, 方便大家下载: https://how2j.cn/k/helloworld/helloworld-version/1718.html

上传截图