首先说明,struts必须拼写对,不要忘记第2个t
1.1.新建第一个项目
①先在新建web project中的web.xml添加配置项。这个可以在struts2-blank.war文件夹里找到
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
②再建个struts.xml(一定要拼写正确,并且该
名称是固定的,
不能写成struts2.xml),写入属性.可放在src文件夹内
<struts>
<package name="default" namespace="/" extends="struts-default">
<action name="firstAction" class="com.bjsxt.action.FirstAction"></action>
</package>
</struts>
注意action name相当于以前的<url-pattern>,name是什么,就在浏览器输入相应的值即可。
③新建action文件,可以简单地写为
public class FirstAction {
public String execute(){
System.out.println("跑了!");
return null;
}
}
可以发现struts与servlet相比有几点不同
--1.不用继承HttpServlet
--2.少了doGet()和doPost()方法
④在浏览器输入http://localhost:8080/Struts2/firstAcion,即可看到输出结果。注意不要写“.java”后缀。
PS: struts2里默认的方法是execute(),上边若改为其它名称,如add(),则要用动态调用,加!。即浏览器地址变为
http://localhost:8080/Struts2/firstAcion!add
2.struts2的action是多例模式,每一次请求(即一个url就是一个请求)都实例化一个action对象,彼此之间完全独立,多例是线程安全的。而servlet是单例,只会实例化一个对象。
3.一般自己写的方法,不包括继承,都要抛出异常来使代码更完善。如
public String add() throws Exception(){}
4.可通过动态方法调用,即在url内添加“actionname!methodname”来直接使用相应的方法。如在地址栏输入:
http://localhost:8080/Struts2_001/firstAction!test2
5.属性驱动(property-driven)和模型驱动(model-driven)
这两个主要是用来进行表单数据的封装,以便于在action直接调用。以后再也不需要用getParameter()方法来获取属性,简化了不少。
①model-driven(模型驱动)使用时必须new一个实例才能获取到值,即需要添加类似的
private User user = new User();
而property-driven(属性驱动)则不需要这一步。
②使用ModelDriven 模型实例对象虽然在valueStack中, 但是我们只能通过实例对象的属性直接获取对应的value。
即类似${name}这样的,而不是${user.name}。后边的这种取不到值。
property-driven,必须添加相应的get和set方法。而model-driven,不需添加。因为不加set/get方法,value stack中也会传入name,id,password等值,但没有user对象,此时用${name}获取属性即可,不能用${user.name}获取。添加get/set方法后,会增加user对象,但也有name,id等属性,重复了。所以添加get/set方法后,仍然只能用${name}等取得属性。不管加没加get/set方法,都只能直接通过属性获取值,即只能用${name}这样的,不能用${user.name}这样的。
综上所述:
Property Driven:利用属性驱动利用对象把参数注入到当前的Action类(必须使用getters setters方法),一般要继承ActionSupport
Model Driven:利用模型驱动把参数注入到当前的Action类 必须实现ModelDriven接口,实现接口时必须重写getModel方法, 并且实例化其注入对象(专门应用于数据传输层的VO对象),即有类似于下边这样的:
private UserVO userVO = new UserVO();
再如:
public class ModelAction implements ModelDriven<UserVO> {
private UserVO userVO = new UserVO();
public UserVO getModel(){//实现接口时必须重写getModel方法,并且ModelDriven<UserVO>中的UserVO和返回值类型UserVO对应return userVO;
}
}
③从jsp页面往action中传值时:
在property-driven中,jsp页面只能为
id<input name="user.id">
姓名<input name = "user.name">
不能为
id<input name="id">
姓名<input name = "name">
因为property-driven通过属性注入的,前边需要加对象。
而在model-driven中,既可以是
id<input name="user.id"> 姓名<input name = "user.name">
也可以用
id<input name="id">
姓名<input name = "name">
不需要添加模型名称,直接写属性即可。
获取值时还是只能用${id},${name}等来直接获取,而不能用${user.id},jsp页面上可以这样写${user.name},取值时不能这样取${user.name}
④若想获取从浏览器地址栏的值,还是拿user举例。则模型驱动中用${name}即可。地址栏为:
http://localhost:8080/Struts_001_helloworld/model!add?username=y
属性驱动中用${user.name},否则无法显示。地址栏为:
http://localhost:8080/Struts_001_helloworld/property!add?user.username=y
同时注意传递参数的写法,model中没有属性,property中必须写属性user才能获取到。
6.指定web的默认字符集可使用
<constant name="struts.i18n.encoding" value="utf-8">
这等价于
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
指定开发模式则是:
<constant name="struts.devMode" value="true">
添加该段代码后,在struts.xml修改数据后,就可以不再重启服务器。这句话只是针对struts.xml,而在action添加或删除方法后还是需要重启服务器。
7.namespace与路径有关。默认的为“/”,可以自己修改,但相应地在地址栏内也要发生变化。如
namespace="/";
url地址为
http://localhost:8080/Struts2/firstAction
当变为:
namespace="/admin"
url地址为:
http://localhost:8080/Struts2/admin/firstAction
8.web.xml中的filter默认拦截的是/*,为了减少冲突,可改为*.action,Action默认的后缀都是.action。然后在浏览器输入时,在最后添加.action
9.struts.xml中的action的配置信息是将url,action类,展示页面三者联系起来。
url跟action的name相关联
class指定了action类
result将action中返回的字符串(通过result的name属性匹配,name如果不指定值,默认是"success")跟展示页面(通过path或者result元素的文本值指定)映射起来。如
<action name="firstAction" class="com.bjsxt.action.FirstAction">
<result name="success">/success.jsp</result>
<!--可以有多个rsult元素-->
</action>
<result>元素告诉我们调用完action后下一步做什么,映射到什么地方。
<result>还有type属性。默认的为dispatcher(用来转向jsp页面),常用的有redirect(重定向到url),redirectAction(重定向到一个action)
<result name="getList" type="redirect">userAction!getList.action</result>
10.通过struts2实现增删改查时,一般有三个页面,save.jsp(保存用户),view.jsp(展示结果),update.jsp(修改用户信息)。保存(save)用户后,需要
重定向到展示(view)页面来显示增加用户后的效果。而view()方法则把结果
重定向到jsp页面使结果显示。
11.struts2的action为多例模式,所以在预修改preUpdate()中的this.user与save()方法中的this.user不是同一个。因为每一次请求都会new一个实例。同理,各个方法的this.user都不一样。
12.怎么通过在地址栏向action传值?如
public class FirstAction {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public FirstAction() {
System.out.println("你好");
}
public String hh() throws Exception{
System.out.println(this.message);
if("aaa".equals(message)){
return "success";
}else{
return "failure";
}
}
}
需要在地址栏输入:
http://localhost:8080/Struts_001_helloworld/firstAction!hh?message=aa
此时会return 到failure,只有?后边的message=aaa才能return 到success.
注意传值必须写出哪个属性等于什么值,必须有等号"=",否则值传过去了,但无法识别。
若hh()改为execute,则地址栏中无需加"!",因为execute是struts2默认会执行的.即
http://localhost:8080/Struts_001_helloworld/firstAction?message=aa
即可。
13.
String a = null;
String c = "sss";
a.equals(c);//会报空指针异常
c.equals(a);//只是不相等,不会报任何异常。
这些和前边提到的
String name = request.getParameter("name");
if("admin".equals(name)){
//方法内容
}
做了个深化理解。防止name为null时出现空指针异常。因此不推荐下边这种写法,不严谨。
String name = request.getParameter("name");
if(name.equals("admin")){
//方法内容
}