web学习笔记24-Struts2结果视图

1、Struts2的结果视图:

a.局部视图
        <package name="p1" extends="default">
            <action name="demo1" class="com.example.action.Demo1Action">
                <result>/demo1.jspresult>
            action>
            <action name="demo2">
            action>
        package>
b.全局视图:
        <package name="default" extends="struts-default">
            <global-results>
                全局视图:访问动作时,如果没有局部视图,则找全局视图 
                <result name="success" type="dispatcher">/demo1.jspresult>
            global-results>
        package>

2、result元素的配置:

属性:
    name:逻辑视图名称。它对应的是动作方法的返回值。默认值:success。
    type:到达目标的形式。默认值:dispatcher。转发。

Struts2提供的结果类型(result type属性)
    在struts-default.xml中有定义,可以看看源码就知道

    chain:用户转发到另外一个动作。 
    dispatcher(默认):用于转发到另外一个JSP页面。
    freemarker:用于转发到另外一个freemarker模板。(页面静态化)
    velocity:用于转发到另外一个velocity模板。
    httpheader:用于输出http协议的消息头。
    xslt:XML有关的样式
    redirect(常用):用于重定向到另外一个JSP页面。
    redirectAction(常用):用于重定向到另外一个动作。
    stream(常用):用于文件下载(日后再讲。文件上传和下载)
    plainText:以纯文本的形式展现页面。输出源码。

3、自定义结果视图:(输出页面上的验证码)

例如我们自定义一个 captcha 输出结果类型
步骤:
a.编写一个类,直接或间接实现com.opensymphony.xwork2.Result接口。一般继承org.apache.struts2.dispatcher.StrutsResultSupport类
        public class CaptachaResult extends StrutsResultSupport{
            private int width = 120;
            private int height = 80;
            private int numCount = 4;
            private int grLineNum = 100;
            public void setWidth(int width) {
                this.width = width;
            }
            public void setHeight(int height) {
                this.height = height;
            }
            public void setNumCount(int numCount) {
                this.numCount = numCount;
            }
            public void setGrLineNum(int grLineNum) {
                this.grLineNum = grLineNum;
            }
            //实现这个方法,输出你的结果即可
            protected void doExecute(String finalLocation, ActionInvocation invocation)
                    throws Exception {
                ValidateCode vc = new ValidateCode(width, height, numCount, grLineNum);
                BufferedImage image = vc.getBuffImg();
                //输出即可
                HttpServletResponse response = ServletActionContext.getResponse();
                ImageIO.write(image, "jpeg", response.getOutputStream());
            }
        }
b.声明结果类型,然后才能使用(struts.xml配置)
        <package name="p3" extends="struts-default">
            <result-types>
                
                <result-type name="captcha" class="com.example.results.CaptachaResult">result-type>
            result-types>
            <action name="captcha">
                <result name="success" type="captcha">
                    <param name="width">200param>
                result>
            action>
        package>
c.使用
        我们在jsp页面中使用
        <body>
            <form action="">
                username:<input/><br/>
                password:<input/><br/>
                验证码:<input name="code" size="4"/><img src="${pageContext.request.contextPath}/captcha.action"/><br/>
                <input type="submit" value="登录"/>
            form>
        body>
界面上就可以显示4位数字的随机验证码了。

4、封装请求参数-动态参数注入-方式1:

动态参数注入:(请求参数,用户输入的)。
用Action动作类作为模型对象:
    例如:
    jsp页面:
        <body>
            <form action="${pageContext.request.contextPath}/regist.action" method="post">
                用户名:<input type="text" name="username"/><br/>
                密码:<input type="password" name="password"/><br/>
                <input type="submit" value="登录"/>
            form>
        body>
    struts.xml配置:
        <package name="p1" extends="struts-default">
            <action name="regist" class="com.example.action.UserAction" method="regist">
                <result>/success.jspresult>
                <result name="login">/login.jspresult>
            action>
        package>
    动作类:
        public class UserAction extends ActionSupport {
            private String username;
            private String password;

            public String getUsername() {
                return username;
            }
            //框架会按照表单的name值,调用对应的setter属性
            public void setUsername(String username) {
                this.username = username;
            }
            public String getPassword() {
                return password;
            }
            public void setPassword(String password) {
                this.password = password;
            }
            public String regist(){
                System.out.println(username+":"+password);
                if("wzhting".equals(username)&&"sorry".equals(password))
                    return SUCCESS;
                else
                    return LOGIN;
            }
        }
    这种方式是直接用动作类来封装请求的参数

5、封装请求参数-动态参数注入-方式2(推荐):

动作类和模型分开
a.编写一个javabean用来封装请求的参数
    Person.java:
        public class Person implements Serializable {
            private String username;
            private String password;
            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 String toString() {
                return "Person [username=" + username + ", password=" + password + "]";
            }
        }
b.编写动作类:
    PersonAction.java:
        public class PersonAction extends ActionSupport {
            private Person person = new Person();//这种方法可以直接new个Person对象初始化,也可以不用。
            //private Person person;//如果不new,框架也会帮你new出来

            public Person getPerson() {
                System.out.println("getter");
                return person;
            }

            public void setPerson(Person person) {
                System.out.println("setter");
                this.person = person;
            }
            public String regist(){
                System.out.println(person);
                //如果用户 hehe 密码123 就成功
                if("hehe".equals(person.getUsername())&&"123".equals(person.getPassword()))
                    return SUCCESS;
                else
                    return LOGIN;
            }
        }
c.编写struts.xml配置文件:
        <package name="p2" extends="struts-default" namespace="/person">
            <action name="regist" class="com.example.action.PersonAction" method="regist">
                <result>/success.jspresult>
                <result name="login">/login1.jspresult>
            action>
        package>
d.编写jsp页面:**(特别注意使用person.username)**
        <body>
            <form action="${pageContext.request.contextPath}/person/regist.action" method="post">
                用户名:<input type="text" name="person.username"/><br/>
                密码:<input type="password" name="person.password"/><br/>
                <input type="submit" value="登录"/>
            form>
        body>

web学习笔记24-Struts2结果视图_第1张图片
这种方式就是动作和模型分开了,比较清晰。
优点;动作类写起来简单点;
弊端:页面需要用到命名空间person.username

6、封装请求参数-动态参数注入-方式3:

模型驱动:ModelDriven
配置的要求就要高一点

a.编写一个javabean用于封装参数:(对属性字段要求比较高)
Customer.java:
        //属性和form中的字段名一致
        public class Customer implements Serializable {
            private String username;
            private String password;
            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;
            }
        }
b.编写一个动作类:**(这个地方要求比较高)**
CustomerAction.java:
        public class CustomerAction extends ActionSupport implements ModelDriven<Customer>{
            private Customer customer = new Customer();//注意一定要初始化这个地方

            public Customer getCustomer() {
                return customer;
            }
            public void setCustomer(Customer customer) {
                this.customer = customer;
            }
            public String regist(){
                System.out.println(customer);
                if("hehe".equals(customer.getUsername())&&"123".equals(customer.getPassword()))
                    return SUCCESS;
                else
                    return LOGIN;
            }
            //此方法会在动作方法执行前先执行;得到当前对应的模型对象并把模型对象压入值栈的栈顶。setUsername先调用栈顶对象的该方法。
            public Customer getModel() {
                return customer;
            }
        }

web学习笔记24-Struts2结果视图_第2张图片
c.编写struts.xml配置文件:

        <package name="p3" extends="struts-default" namespace="/customer">
            <action name="regist" class="com.example.action.CustomerAction" method="regist">
                <result>/success.jspresult>
                <result name="login">/login2.jspresult>
            action>
        package>
d.编写jsp页面:(页面写起来就不用customer.username了,相对简单)
      <body>
        <form action="${pageContext.request.contextPath}/customer/regist.action" method="post">
            用户名:<input type="text" name="username"/><br/>
            密码:<input type="password" name="password"/><br/>
            <input type="submit" value="登录"/>
        form>
      body>
优点:页面不需要用到命名空间contomer.username了。
弊端:动作类写法相对麻烦点,写javabean的时候属性要和这个页面的这个name值对应起来。

个人推荐使用第二种方式。

7、封装请求参数-静态参数注入:

动作类:
        public class StudentAction extends ActionSupport {
            private String name;

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }
            public String regist(){
                System.out.println(name);
                return null;
            }
        }
struts.xml配置:
        <package name="p4" extends="struts-default" namespace="/student">
            <action name="regist" class="com.example.action.StudentAction" method="regist">
                
                <param name="name">游客param>
            action>
        package>

你可能感兴趣的:(Web)