JAVAEE框架学习——Struts2——Action API 使用

Action API

通过ActionContext 获取不同域对象 存放值

  • Object get(Object key) 类似于调用HttpServletRequest 的 getAttribute(String name)方法
  • Map getApplication() 返回一个Map对象 该对象模拟了应用ServletContext实例
  • static ActionContext getContext() 静态方法 获取系统的ActionContext实例
  • Map getParameters() 获取所有的请求参数。类似调用HttpServletRequest对象的getParameterMap()方法
  • Map getSession() 返回一个Map对象 该Map对象模拟了HttpSession实例
  • void setApplication(Map application) 直接传入一个Map实例,将该Map实例里的key-value对象转换成application的属性名、属性值
  • void setSession(Map session) 直接传入一个Map实例,将该Map实例里的key-value对转换成session的属性名、属性值

结果跳转方式

Struts2中常用的结果跳转方式有4中:

转发

 
        
            /hello.jsp
        

查看源码分析

Struts2按照struts-default.xml配置文件可以找到 dispathcer对应的类 名为
rg.apache.struts2.dispatcher.ServletDispatcherResult
进入这个类中,我们可以看到如下的代码

 /**
     * Dispatches to the given location. Does its forward via a RequestDispatcher. If the
     * dispatch fails a 404 error will be sent back in the http response.
     *
     * @param finalLocation the location to dispatch to.
     * @param invocation    the execution state of the action
     * @throws Exception if an error occurs. If the dispatch fails the error will go back via the
     *                   HTTP request.
     */
    public void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Forwarding to location " + finalLocation);
        }

        PageContext pageContext = ServletActionContext.getPageContext();

        if (pageContext != null) {
            pageContext.include(finalLocation);
        } else {
            HttpServletRequest request = ServletActionContext.getRequest();
            HttpServletResponse response = ServletActionContext.getResponse();
            RequestDispatcher dispatcher = request.getRequestDispatcher(finalLocation);

            //add parameters passed on the location to #parameters
            // see WW-2120
            if (StringUtils.isNotEmpty(finalLocation) && finalLocation.indexOf("?") > 0) {
                String queryString = finalLocation.substring(finalLocation.indexOf("?") + 1);
                Map parameters = getParameters(invocation);
                Map queryParams = urlHelper.parseQueryString(queryString, true);
                if (queryParams != null && !queryParams.isEmpty())
                    parameters.putAll(queryParams);
            }

            // if the view doesn't exist, let's do a 404
            if (dispatcher == null) {
                response.sendError(404, "result '" + finalLocation + "' not found");
                return;
            }

            //if we are inside an action tag, we always need to do an include
            Boolean insideActionTag = (Boolean) ObjectUtils.defaultIfNull(request.getAttribute(StrutsStatics.STRUTS_ACTION_TAG_INVOCATION), Boolean.FALSE);

            // If we're included, then include the view
            // Otherwise do forward
            // This allow the page to, for example, set content type
            if (!insideActionTag && !response.isCommitted() && (request.getAttribute("javax.servlet.include.servlet_path") == null)) {
                request.setAttribute("struts.view_uri", finalLocation);
                request.setAttribute("struts.request_uri", request.getRequestURI());

                dispatcher.forward(request, response);
            } else {
                dispatcher.include(request, response);
            }
        }
    }

由源码可以看到

  • 先通过ServletActionContext.getRequest() 获取到了HttpServletRequest 这就是请求对象
  • 通过ServletActionContext.getResponse()获取到了HttpServletResponse() 响应对象
  • 通过请求和响应对象来进行结果的操作,其中
    * 请求对象 request.getRequestDispatcher() 获得转发器,在最后dispathcer.forward(req,res)
    可以看出 Struts2的转发 就是封装的Servlet的转发,加入了一些逻辑

重定向


     
            /hello.jsp
        
    

查看源码分析

HttpServletResponse response = (HttpServletResponse) ctx.get(ServletActionContext.HTTP_RESPONSE);
sendRedirect(response, finalLocation);

同样 封装的Servlet重定向

转发到Action

   
            
                
                Demo1Action
                /
            
        

重定向到Action

 
            
                Demo1Action
                /
            
        

获得Servlet API

Struts2的Action没有与任何Servlet API耦合,这是Struts2的一个改良之处

原理

原理

通过ActionContext

Struts2提供了ActionContext来访问Servlet API ActionContext是Action执行的上下文对象。在ActionContext中保存了Action执行所需要的所有对象。包括parameters,request,session,application等

 ActionContext context = ActionContext.getContext();
        //获得request域 struts不推荐使用request域
        Map requestScope = (Map) context.get("request");
        //推荐 ActionContext
        ActionContext.getContext().put("name", "requestTom");

        //获得session域
        Map session = context.getSession();
        session.put("name", "sessionTom");
        //获得application域
        Map application = context.getApplication();
        application.put("name", "applicationTom");
        return SUCCESS;

获得session域

  • Map session = context.getSession();

获得Application域

  • Map application = context.getApplication();

通过ServletActionContext

为了直接访问Servlet API Struts2框架还提供了ServletActionContext类

public String execute(){
        //原生request
        HttpServletRequest request = ServletActionContext.getRequest();
        //原生session
        HttpSession session = request.getSession();
        //原生response
        HttpServletResponse response = ServletActionContext.getResponse();
        //原生servletContext
        ServletContext servletContext = ServletActionContext.getServletContext();
        return SUCCESS;
    }

通过实现接口方式

Struts2接口
public class Demo7Action extends ActionSupport implements ServletRequestAware, ServletResponseAware, ServletContextAware {
    private ServletContext context;
    private HttpServletRequest request;
    private HttpServletResponse resp;

    @Override
    public void setServletRequest(HttpServletRequest request) {
        this.request = request;
    }

    @Override
    public void setServletResponse(HttpServletResponse response) {
        this.resp = response;
    }

    @Override
    public void setServletContext(ServletContext context) {
        this.context = context;
    }

    public String execute() throws Exception {
        System.out.println("原生request" + request);
        return SUCCESS;
    }

由拦截器完成

Action中获得参数

第一种:通过与参数键名称相同的属性

 private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String execute() throws Exception {
        System.out.println(this.name);
        return SUCCESS;
    }

属性驱动获得参数

 private String name;
    private Integer age;
    private Date birthday;

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String execute() throws Exception {
        System.out.println(this.name);
        System.out.println(this.age);
        System.out.println(this.birthday);
        return SUCCESS;
    }
用户名:
年龄:
生日:

第二种 对象驱动

  • 创建对象
public class User {
    private String name;
    private Integer age;
    private Date birthday;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}
  • 页面指定提交到对象的对应属性
用户名:
年龄:
生日:
  • Action 中声名对象属性
  private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String execute() throws Exception {
        System.out.printf(this.user.toString());
        return SUCCESS;
    }

其实某种意义上 对象驱动和属性驱动没有什么区别,只是将属性换成了对象

第三种 模型驱动

  • Action实现ModelDriven<模型>接口
public class Demo10Action extends ActionSupport implements ModelDriven {

    private User user = new User();


    @Override
    public String execute() throws Exception {
        System.out.printf(this.user.toString());
        return SUCCESS;
    }

    /**
     * @return 返回需要封装的对象
     */
    @Override
    public User getModel() {
        return user;
    }
}
  • 页面正常提交
用户名:
年龄:
生日:

缺点:封装的模型单一

原理(正在学习 日后补)

集合类型参数封装

封装list

  • Action类
 private List list;

    public List getList() {
        return list;
    }

    public void setList(List list) {
        this.list = list;
    }

    @Override
    public String execute() throws Exception {
        System.out.println("list" + list);
        return SUCCESS;
    }
  • 页面page
    list:
    list:
    

前端表单指定name="list" Struts2直接将参数封装到list集合中

指定添加索引

   list:

封装Map

  • Action类
 public void setMap(Map map) {
        this.map = map;
    }

    public List getList() {
        return list;
    }
@Override
    public String execute() throws Exception {
        System.out.println("list" + list);
        System.out.println("map" + map);
        return SUCCESS;
    }
  • 页面page
    list:

扩展知识

StrutsMVC

StrutsMVC

Action 生命周期

  • 每次接收请求到来时,都会创建一个新的Action实例
  • Action是线程安全的,可以使用成员变量接收参数

你可能感兴趣的:(JAVAEE框架学习——Struts2——Action API 使用)