• 第二章 struts2入门


    Struts2的配置文件:

    下面是它的配置顺序

       web.xml

       Default.properties

       Struts-default.xml

       Struts-plugin.xml

       Struts.xml

    <package name="one-package" extends="struts-default">

    <action name="one" class="cn.struts2.action.OneAction">

    <result>/jsps/show.jsp</result>

    </action>

    </package>

    1:extends="struts-default"继承且使用系统包中定义的资源

    <package name="one-package" extends="struts-default">

    <global-results>

    <!-- 如果没有,则找当前这个包中有没有全局的结果定义

    如果当前包中没有定义,则去父包中找有没有名称叫name=success的结果定义

     -->

    <result>/jsps/show.jsp</result>

    </global-results>

    <action name="one" class="cn.struts2.action.OneAction">

    </action>

    </package>

    <package name="two-package" extends="one-package">

    <action name="two" class="cn.struts2.action.TwoAction">

    <!-- 如果在twoAction的返回success字符串将会查找名称为name=successresult -->

    </action>

    </package>

    2namespace

    <!-- namespace的默认值=/(当前项目的根),如果写入其他的值,则访问里面的的action为:

    http://ip:port/project/aaa/two[.action]

     -->

    <package name="two-package" extends="one-package" namespace="/aaa">

    <action name="two" class="cn.struts2.action.TwoAction">

    <!-- 如果在twoAction的返回success字符串将会查找名称为name=successresult -->

    </action>

    </package>

    3action

    action可以是:

    1:pojo简单java对象

    如:

    package cn.struts2.action;

    public class OneAction {

    public String execute(){

    System.err.println("Hello"+this);

    return "success";

    }

    }

    2:可以实现接口Action

    public class OneAction implements Action {

    @Override

    public String execute(){

    System.err.println("Hello"+this);

    return SUCCESS;///可以直接使用Action中定义的常量

    }

    }

    3:可以继承一个类:ActionSupport

    好处是:

      1:可以使用常量。

      2:提供验证功能。

      3:可以访问国际化的信息。

    提供验证功能。

    public interface Validateable {

        /**

         * Performs validation.

         */

        void validate();

    }

    public class OneAction extends ActionSupport {

    private String name;

    public String getName() {

    return name;

    }

    public void setName(String name) {

    this.name = name;

    }

    @Override

    public String execute(){

    System.err.println("2Hello"+this);

    return SUCCESS;///可以直接使用Action中定义的常量

    }

    @Override

    public void validate() {

    System.err.println("1......先 验证");

    if(name==null){

    addFieldError("name", "姓名不能为空");

    }

    }

    }

    <action name="one" class="cn.struts2.action.OneAction">

    <result name="success">/jsps/show.jsp</result> //验证成功

    <result name="input">/index.jsp</result>  //验证不成功

    </action>

    表单:

    <s:fielderror></s:fielderror>  显示错误信息

    <form action="one" method="post">

    name:<input name="name" type="text"><br>

    <input type="submit">

    </form>

    访问国际化信息:

    两种方式配置国际化文件:

    @Override

    public void validate() {

    System.err.println("1......先 验证");

    if (name == null || name.trim().equals("")) {

    addFieldError("name", getText("nameError"));

    }

    }

    引用方式:

        <!-- 配置资源文件 -->

    <constant name="struts.custom.i18n.resources" value="msg"></constant>

    4:关于action的扩展名

    <action name="one" class="cn.struts2.action.OneAction">

    则可以通过以下的方式来访问:

      http://ip:port/project/one

      http://ip:port/project/one.action

    s2的常量里面配置了对*.action的识别:

    struts.action.extension=action,,

    修改这个常量:

       <!-- 修改默认的扩展名 -->

    <constant name="struts.action.extension" value="action,,"></constant>

    5:动态的调用某些个方法

    public class OneAction {

    public String say() {

    System.err.println("say.....");

    return Action.SUCCESS;

    }

    public String hi() {

    System.err.println("hi.....");

    return Action.SUCCESS;

    }

    public String execute() {

    System.err.println("execute...");

    return Action.SUCCESS;

    }

    }

    1:配置的方式,默认的是execute

    <action name="one" class="cn.struts2.action.OneAction">

    <result>/jsps/show.jsp</result>

    </action>

    <action name="onehi" class="cn.struts2.action.OneAction" method="hi">

    <result>/jsps/show.jsp</result>

    </action>

    <action name="onesay" class="cn.struts2.action.OneAction" method="say">

    <result>/jsps/show.jsp</result>

    </action>

    缺点:配置太多。

    2:使用通配置符号 *

    <!-- struts2.3.x版本中直接使用*即可,但是到了struts2.5版本中必须要声明方法可以这样去调用 -->

    <package name="one-package" extends="struts-default" strict-method-invocation="false">

    <action name="one*" class="cn.struts2.action.OneAction" method="{1}">

    <result>/jsps/show.jsp</result>

    </action>

    </package>

    能不能在name里面使用/符号

    <!-- 修改默认的扩展名 -->

    <constant name="struts.action.extension" value="action,,"></constant>

    <!-- 配置在name中,可以带 有斜线 -->

    <constant name="struts.enable.SlashesInActionNames" value="true"></constant>

    <!-- 配置资源文件 -->

    <constant name="struts.custom.i18n.resources" value="msg"></constant>

    <!-- struts2.3.x版本中直接使用*即可,但是到了struts2.5版本中必须要声明方法可以这样去调用 -->

    <package name="one-package" extends="struts-default" strict-method-invocation="false">

    <action name="one/*" class="cn.struts2.action.OneAction" method="{1}">

    <result>/jsps/show.jsp</result>

    </action>

    </package>

    3:直接使用struts2的 !(棒符号)实现动态的方法调用

    struts.enable.DynamicMethodInvocation = false  是否支持!符号

    <!-- 是否支持!符号 -->

    <constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>

    http://localhost/20160615/one!hi.action

    6:接收参数

    req.getPamater(...)/getParameterValue(..)

    两种方式:

      1: 属性驱动

    Get/set方法

      2:模型驱动

        实现一个接口:ModelDriven

    public class OneAction {

    private String name;

    private Integer age;

    private String[] hobby;// List<String>/Set<String>

    public void setName(String name) {

    this.name = name;

    }

    public void setAge(Integer age) {

    this.age = age;

    }

    public void setHobby(String[] hobby) {

    this.hobby = hobby;

    }
    http://localhost/20160615/one?name=Jack&age=90&hobby=football&hobby=mtv
    信息: Server startup in 3785 ms

    execute...OneAction [name=Jack, age=90, hobby=[football, mtv]]

    接收JavaBean -  通过属性驱动:

    public class OneAction {

    private User user;

    public User getUser() {

    return user;

    }

    public void setUser(User user) {

    this.user = user;

    }

    public String execute() {

    System.err.println("execute..." + user);

    return Action.SUCCESS;

    }

    }

    http://localhost/20160615/one?user.age=90&user.name=Jack&user.hobby=climb

    模型驱动:

      public class OneAction implements ModelDriven<User> {

    private User user = new User();

    @Override

    public User getModel() {

    return user;

    }

    public String execute() {

    System.err.println("execute..." + user);

    return Action.SUCCESS;

    }

    }

    http://localhost/20160615/one?name=Jack&age=89&hobby=music&hobby=reading

    7Struts2的容器ValueStack(值栈)

    ValueStack两部分组成:

     1:栈- Stack

     2:上下文对象 Map

    什么时间会创建这个栈对象:

      当用户每次请求时。

    查看ValueStack的结构:

       <s:debug/>

    如果你的类还实现的ModelDriven则栈中的数据会发生改变:

    public class OneAction implements ModelDriven<User> {

    private User user = new User();

    @Override

    public User getModel() {

    return user;

    }

    8:Struts2request对象的包装

    修改了getAttribute方法,让当前的获取从ValueStack中获取值。

    9:访问域对象

    S2为了解藕,将所有对象声明成Map类型。

    1:使用解耦的方式来访问域对象

    1:使用工具类的静态的方法ActionContext - 重点

    ActionContext req = ActionContext.getContext();

    req.put("addr", "山东济南在req");

    //获取Session

    Map<String, Object> session =

    req.getSession();

    session.put("addr", "地址在Session");

    //获取Application

    Map<String, Object> app =

    req.getApplication();

    app.put("addr", "地址在App");

    2:使用注入的方式来访问

    public class OneAction implements ModelDriven<User>, RequestAware, SessionAware, ApplicationAware {

    @Override

    public void setRequest(Map<String, Object> request) {

    request.put("addr", "1111");

    }

    @Override

    public void setApplication(Map<String, Object> application) {

    application.put("addr", "33333");

    }

    @Override

    public void setSession(Map<String, Object> session) {

    session.put("addr", "22222");

    }

    2:使用耦合的方式来访问原生的对象

    1:使用工具类ServletActionContext

    HttpServletRequest req =

    ServletActionContext.getRequest();

    req.setAttribute("addr", "100");

    HttpSession session = req.getSession();

    session.setAttribute("addr", "200");

    ServletContext app =  ServletActionContext.getServletContext();

    app.setAttribute("addr", "300");

    2:使用注入方式

    public class OneAction implements ServletRequestAware, ServletContextAware {

    @Override

    public void setServletRequest(HttpServletRequest request) {

    }

    @Override

    public void setServletContext(ServletContext context) {

    }

    10result

    struts2中,转换到某个页面,都是Result做的<result>/jsps/show.jsp</result>

    每一个Result都一个类:

       这个类是:

    public interface Result extends Serializable {

        public void execute(ActionInvocation invocation) throws Exception;

    }

    result的声明过程:

      <result>/jsps/show.jsp</result>

    <result name=”success” type=”disatcher”>/jsps/show.jsp</result>

    <result name=”success” type=”dispatcher”>

    <param name=”location”>/jsps/show.jsp</param>

    </result>

    type是在struts-default包中定义的 结果类型:

    1chain(转发到另一个Action)/dispatcher(转发到另一个页面)

      <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>

                <result-type name="dispatcher" class="org.apache.struts2.result.ServletDispatcherResult" default="true"/>

    • location (default) - the location to go to after execution (ex. jsp). 转发到哪一个页面
    • parse - true by default. If set to false, the location param will not be parsed for Ognl expressions. 是否在location中接收 OGNL表达式。

     

    <result>

    <param name="location">/jsps/show.jsp?nm=${name}</param>

    <param name="parse">false</param>

    </result>

     

     

    2redirect重定向到一个页面,redirectAction重定向到一个Ation

      <result-type name="redirect" class="org.apache.struts2.result.ServletRedirectResult"/>

                <result-type name="redirectAction" class="org.apache.struts2.result.ServletActionRedirectResult"/>

    3:plainText显示为文本

    4:自定义Result显示验证码

    1:开发一个自定义的Result

    public class ImgResult implements Result {

    @Override

    public void execute(ActionInvocation invocation) throws Exception {

    HttpServletResponse resp =

    ServletActionContext.getResponse();

    resp.setContentType("text/html;charset=UTF-8");

    resp.getWriter().print("Hello"+Math.random());

    }

    }

    2:配置到struts.xml中去

    <result-types>

    <result-type name="img" class="cn.result.ImgResult"></result-type>

    </result-types>

    3:使用这个result

    <!-- 默认的class : ActionSupport -->

    <action name="abc">

    <result type="img"></result>

    </action>

    package cn.result;

    import java.awt.Color;

    import java.awt.Font;

    import java.awt.Graphics;

    import java.awt.image.BufferedImage;

    import java.util.Random;

    import javax.imageio.ImageIO;

    import javax.servlet.http.HttpServletResponse;

    import org.apache.struts2.ServletActionContext;

    import com.opensymphony.xwork2.ActionContext;

    import com.opensymphony.xwork2.ActionInvocation;

    import com.opensymphony.xwork2.Result;

    public class ImgResult implements Result {

    @Override

    public void execute(ActionInvocation invocation) throws Exception {

    // 1:声明图片的大小

    int width = 60;

    int height = 30;

    // 2:

    BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

    Graphics g = img.getGraphics();

    g.setColor(Color.WHITE);

    g.fillRect(0, 0, width, height);

    g.setFont(new Font("ST", Font.BOLD, 18));

    Random r = new Random();

    // 声明一个字符串,用于保存4个字符

    String sCode = "";

    for (int i = 0; i < 4; i++) {

    String a = "" + r.nextInt(10);

    sCode += a;// 串联字符串

    g.setColor(new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256)));

    g.drawString(a, i * 15, 10 + r.nextInt(20));

    }

    // 放到session中去

    ActionContext.getContext().getSession().put("sCode",sCode);

    for (int i = 0; i < 5; i++) {

    g.setColor(new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256)));

    g.drawLine(r.nextInt(width), r.nextInt(height), r.nextInt(width), r.nextInt(height));

    }

    g.dispose();

    // 输出图片到浏览器

    HttpServletResponse response =

    ServletActionContext.getResponse();

    response.setContentType("image/jpeg");

    ImageIO.write(img, "JPEG", response.getOutputStream());// 字节码

    }

    }

    5:如何在Struts2框架下使用ajax

    请求一个Action.method() : String 这个字符串可不是指的JSON/XML/TExt/而是

     <reuslt name=”xxx”/>

    解决的方案是:

      1:声明一个公共的页面 json.jsp  里面的代码:${jsonString}

         将这个jsp配置成

         <global-results>

            <result name=”json”>/json.jsp</result>

         ...

         在action中:

          Public String execute(){

              Actioncton.getContext().put(“jsonString”,”{}.....”);

             Return “json”;

      2:可以开发一个Result只从栈顶获取数据转成json串显示

          

    public class JsonResult implements Result {

    @Override

    public void execute(ActionInvocation invocation) throws Exception {

    Object obj =  ActionContext.getContext().getValueStack().peek();

    String json =  JSONArray.toJSONString(obj);

    HttpServletResponse resp =

    ServletActionContext.getResponse();

    resp.setContentType("text/plain;charset=UTF-8");

    resp.getWriter().print(json);

    }

    }

    public String execute() {

    System.err.println("2:执行:execute..." + name);

    name = "Alex" + Math.random();

    User user = new User();

    user.setName("JackMary李四");

    user.setAge(89);

    user.setHobby(Arrays.asList(new String[] { "AAA", "BB" }));

    ActionContext.getContext().getValueStack().push(user);

    return Action.SUCCESS;

    }

  • 相关阅读:
    vue 手动挂载 $amount()
    Redis 主从配置
    DMA分区管理
    C# 构造函数里的base和this的区别
    SQL Server 数据库性能优化
    TCP和UDP的优缺点及区别
    Django框架初步应用简述
    前端vue框架应用雏形
    接口mock之moco
    python进阶(九)~~~协程、进程池、线程/进程/协程对比
  • 原文地址:https://www.cnblogs.com/carsar/p/5595315.html
Copyright © 2020-2023  润新知