1、package继承 struts-default 就继承了其内定义的一系列拦截器。
2、
struts.action.extension=action,, 然后修改打包。
通常的做法是:在struts.xml中用constant常量标签进行配置,如下:
这里面所有的值都可以在上面的default.properties里面找到。 3、动态方法。在一个action的java源文件中,定义多个函数,如何分别调用?有四种方法。 struts.xml中就不要配置具体的执行方法了,只配置action中定义的不同返回结果对应的返回路径,如: 访问路径: 1)multi!fun1 multi!fun2 2)multi?method:fun1 multi?method:fun2 3)第三种方法,在提交表单中,添加域 也可以达到效果。(一般可加在submit域里) 4)第四种方法,通配符方法 4、结果集类型。不写默认就是dispatcher 服务器端转发 dispatcher 服务器端转发 redirect 客户端转发,网址要变了 chain 服务器端action转发 redirectAction 客户端action 转发 还有freemarker stream(上传下载时候使用) plainText(直接显示转发文件的源码)等类型 5、前台form表单,填写之后通过action的bean类写法取值的注意点,一些数值类型要定义成包装类,比如Integer,Long 。如果定义成int long 那么前台表单该属性对应的项目如果是空值的话,提交之后会报错。 6、注意,struts 的action类是多例多线程的,通过在类内添加System.out.println(this) 可以看出每次打印出的类名的后面的哈希码是不一样的。在SSH整合后,要将这个多例变成单例。servlet是单例多线程的。 7、ActionContext.getContext()用来取得Action的上下文环境,这里面包含了servlet request等等各种信息,并且也可以直接存值。ActionContext.getContext().put("name","zhangtao"); 在前台jsp页面中用struts标签取值时候,一定要在变量名前加# : 不加的话,出于容错考虑,不会出现错误。但是若ActionContext中定义的变量与Action类中的属性相同时,则会出现问题。 8、ServletActionContext 取得传统的Servlet那一套东西 赋值: ServletActionContext.getRequest().setAttribute("req", "request值"); 前台jsp取值: request: 9、ActionContext去设置Servlet那一套东西的值 以及取值 ActionContext.getContext().put(key, value) 这个其实类同request赋值 取值的等同写法:(针对 request session application) ${requestScope.req} EL表达式写法 ${req} -- 注意,不写范围,默认的取值范围顺序是:pageContext request session application 10、给复杂对象传值。 前端jsp 提交 ---------------- 后台取值 Action.java中 private User user; ... getter and setter User.java中 private String username; private Address address; ... getter and setter Address.java中 private String homeaddress ... getter and setter ------------------- 前台jsp显示值 11、集合传值 在Action中,定义一个List List // User 中有 username 和 password属性,给list添加若干个构造好的User对象,然后将list加入到ActionContext中 ActionContext.getContext().put("list",list); 前台jsp 循环显示集合值 还可以这样: 12、OGNL对各种方法的调用。 假设com.zhang.src包内的文件Test.java中的一个方法 fun() 前台jsp页面中静态方法调用: 动态方法调用 调用Action类中定义的方法,可以直接调用 13、OGNL就是一种对象导航关系,可以用在jsp、传递的参数以及struts配置文件中 类中定义了user对象,假设User类中包含address对象,address对象中包含phone对象,phone对象中有number属性,则有: Ognl.getValue("address.phone.number",user); 或 Ognl.getValue("#root.address.phone.number",user); Ognl.setValue("address.phone.number",user,"123456"); 或Ognl.setValue("#root.address.phone.number",user,"123456"); 14、拦截器总结 拦截器会对所拦截的Action内的所有方法实施拦截。定义方式如下: //----位置 2 包内,action外定义好。action内使用。 定义拦截器需继承AbstractInterceptor类,实现intercept方法,其中的该方法内的ActionInvocation变量invocation可以取得ActionContext,从而取得一系列servlet ActionContext actionContext = invocation.getInvocationContext(); 15、配置技巧和全局结果集 在包内action外,如上位置1处,定义 全局结果集的问题。如果一包内很多action,都有一个结果需返回同一个地址,则这时不需要在每个action内都配置这个返回结果。可以直接抽取出来,做成全局结果集,放到所有action外面、前面,所有interceptor后面的位置,定义格式如下: 16、在struts.xml配置文件中使用OGNL表达式 在action中的属性,以及Action中定义在ActionContext中的变量,都可以直接用在struts.xml中。在struts.xml中的使用方式是 ${#valueInActionContext} ${valueInAction} 17、ModelDriven 简化赋值 Action 继承 ModelDriven接口,然后类内可以去除实体类的getter 和 Setter方法 ,并实现接口默认的方法 getModel private User user = null; @Override 则前台可以直接用user的属性值,如username,而不必再使用user.username; ModelDriven有陷阱,解决方法有三。待深究 18、局部类型转换器和全局类型转换器。待深究 19、文件上传 private File myfile; 前台form表单enctype="mulitpart/form-data" 必须设置 20、资源文件读取 abc.properties放在src下 ResourceBundle bundle = ResouceBundle.getBundle("abc"); String s = bundle.getString("item"); 21、convention 免配置 首先,struts.xml中需要的配置 形如com.mm.action.zhang.ChinaBeijingAction 会映射到 zhang/china_beijing 的URL地址,对应的文件是 /test/china_beijing_返回结果字符串.后缀 ,若找不到,会返回/test/china_beijing.后缀 action链的配置,满足三个条件: 1、第一个Action返回的逻辑视图字符串没有对应的视图资源 2、第二个Action与第一个Action处于同一个包内 3、第二个Action的名字是第一个Action名字加其返回结果。例 :第一个Action名字是 FirstAction 返回结果是 second ,则第二个Action名字应该为 FirstSecondAction
ServletActionContext.getRequest().getSession().setAttribute("ses", "session值");
ServletActionContext.getServletContext().setAttribute("con", "application值");
session:
context:
ActionContext.getContext().getSession().put(key, value) session赋值
ActionContext.getContext().getApplication().put(key, value) application赋值
//----位置1
public Object getModel() {
if( user == null){ user = new User(); }
return user;
}
private String myfileFileName; -- 文件名固定 ~~ + FileName
private String myfileContentType; -- 文件类型固定 ~~ + ContentType
FileUtils.copyFile(myfile, new File("c:/upload/"+myfileFileName));