struts2入门

[TOC]

struts2

概念:Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。


1、开发环境搭建

1、拷jar包, 在apps包下,blank>WEB-INF>lib

2、拷配置文件, 在apps包下,blank>WEB-INF>src>java>struts.xml

3、拷过滤器配置, 在apps包下, blank>WEB-INF>web.xml

4、将自己新建的action类配置到struts.xml中

public String execute(){
        return "tohello";
    }

 


    
    /hello.jsp
    


2、struts2 核心类:StrutsPrepareAndExecuteFilter


3、struts2 执行顺序

struts2入门_第1张图片
1.jpg

4、配置文件

  • constant 标签:

    • name="struts.devMode" value="true" 设置配置文件更改不会自动重新加载
    • name="struts.i18n.encoding" value="UTF-8" 设置框架的编码格式,默认UTF-8
    • name="struts.action.extension" value="do,," 设置页面访问时后缀名 默认action,, ,,表示加或者不加后缀都能访问
  • package 标签:

    • name:用来区分不同的action
    • extends:必须默认继承 struts-default
  • action 标签: 配置action处理类路径 和映射路径

    • method:指明要调用action中的哪个方法,不写默认执行execute方法
  • result 标签: 配置结果页面

    • name:逻辑视图名,是action类返回的逻辑视图名
    • 文本内容:物理视图名(jsp文件)
  • include 标签:用来引入其他配置文件,适合团队分模块开发


5、action编写方式

1、自定义类,编写execute方法

2、实现Action接口

3、继承ActionSupport类


6、action方法访问方式

1、传统访问,通过method属性指明

2、通配符访问 *



    
    

3、动态方法调用 ! action名!方法名.后缀 放开动态调用的常量是:struts.enable.DynamicMethodInvocation 为true 开启


7、跳转方式

  • result 标签:type 属性来控制页面的跳转方式
    • jsp页面跳转(默认)转发 dispatcher 重定向 redirect
    • Action之间跳转 : 转发 chain 重定向redirectAction
        
        /login.jsp
        /register.jsp
        
        /menu.jsp
        
        user_register

注意不同papackage标签的Action之间的跳转 需要注入
通过两个param标签(放在result标签内) 注入 name="actionName" 和 name="nameSpace"

    
        
        hello
        
        /
    

8、动态结果页面配置

1、在action类中定义一个字符串变量,并提供get方法 在每个方法内设置该字符串来决定物理视图名,指定要跳转的目标页面

public class MyAction {
    private String view;
    public String getView() {
        return view;
    }
    public void setView(String view) {
        this.view = view;
    }
    public String test1(){
        setView("test1.jsp");
        return "ok";
    }
    public String test2(){
        setView("test2.jsp");
        return "ok";
    }
    public String test3(){
        setView("test3.jsp");
        return "ok";
    }
}

2、在result 的文本配置成获取物理视图属性 通过${action中的字符串变量名}


    /${view}


9、Servlet API的操作,也就是获取参数

1、耦合方式 ServletActionContext.getRequest()

//耦合方式
        HttpServletRequest req = ServletActionContext.getRequest();
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username);
        System.out.println(password);
        if ("admin".equals(username) && "123".equals(password)) {
            req.setAttribute("username", username);
            req.setAttribute("password", password);
            setView("success.jsp");
            return "ok";
        }
        setView("login.jsp");
        return "fail";

2、解耦方式 ActionContext.getContext()

        //解耦方式
        ActionContext context = ActionContext.getContext();
        Map map = context.getParameters();
        
        String[] username = (String[]) map.get("username");
        setView("test3.jsp");
        return "ok";

3、ioc注入 实现ServletRequestAware接口在类里声明HttpServletRequest
并重写setServletRequest方法 在里面写this.request=req;(给类中的全局变量赋值)

public class MyAction implements ServletRequestAware {
    private String view;
private HttpServletRequest request;
//ioc注入
public String test2() {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println(username);
        System.out.println(password);
        if ("admin".equals(username) && "123".equals(password)) {
            request.setAttribute("username", username);
            request.setAttribute("password", password);
            setView("success.jsp");
            return "ok";
        }
        setView("login.jsp");
        return "fail";
    }

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

10、数据校验

1、首先继承ActionSupport

2、校验全部方法 重写 validate方法

3、校验指定方法 自定义方法 validate+校验的方法名(注意:方法首字母大写)

4、添加校验错误信息 addFieldError

        //System.out.println("校验test1方法");
        String username = request.getParameter("username");
        if (username.length()==0) {
            addFieldError("username", "用户名不能为空");
        }

5、配置文件中加一个result name为input

/login.jsp

11、配置结果页面

  • 局部结果页面

    /login.jsp

  • 全局结果页面 同package标签内所有action都可以访问
    • 使用global-results标签 注意:
      • 放在package标签内
      • 一定要放在所有Action配置之前
      • 作用范围只有同package标签内的action

    /error.jsp


12、异常处理

  • 局部异常处理 通过exception-mapping 在action标签下来捕获异常
    • result属性: 表示要跳转的逻辑视图名就是下面result标签的name
    • exception属性:指明要捕获的异常类型

    
    /error.jsp

  • 全局异常处理 通过global-exception-mappings 写在全局结果页面下
    • 子标签exception-mapping result属性:表示要跳转的逻辑视图名
    • exception属性:指明要捕获的异常类型


    /error.jsp



    



    /common.jsp


13、参数封装

  • 属性封装
    -在Action中定义与表单中name值相同的全局变量,并提供set方法,会自动帮我们把表单中的数据封装到对应变量中
    private String name;
    private int age;
    private String sex;

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

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

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String execute() throws Exception {
        System.out.println(name + "---------" + age + "--------" + sex);
        return NONE;
    }
  • 对象封装(表达式封装)
    • 新建一个实体类
    • 在Action中 定义一个全局的对象变量 提供get set方法,表单中的name属性值为:对象.属性名
    private User user;
    public void setUser(User user) {
        this.user = user;
    }
    public User getUser() {
        return user;
    }

    @Override
    public String execute() throws Exception {
        System.out.println(user);
        return NONE;
    }
  • 模型驱动封装
    -定义一个全局对象变量并实例化 实现一个ModelDriven接口,并重写其中的抽象方法getModel() 将全局对象变量 return出去
public class UserAction  implements ModelDriven{
private User user =new User();

@Override
public String execute() throws Exception {
        System.out.println(user);
        return NONE;
    }

@Override
    public User getModel() {
        return user;
    }
}

注:封装集合 表单中用list[0(index)].属性


14、如何传递数据到前台界面

通过request域对象的setAttribute方法设置

值栈来存,通过ognl表达式来取 servlet和action区别? servlet是单实例 action是多实例

  • 值栈的位置,位于每个action中且 一次action运行保证唯一 同一个action 两次运行 值栈不同。
  • 值栈结构
    • CompountRoot: root值栈 底层是list集合
    • OgnlContext:map栈 底层map结构
  • 如何向root值栈中存值

1...使用set方法 会向root栈中压入一个map集合对象 然后把值存入map集合中

//通过set方法
stack.set("name", "tom");

2...使用push方法 直接值对象的引用压入root栈中

//通过push方法
stack.push("adsfadfafa");

3...使用属性的get方法 不会压入新对象引用 直接存放在当前action引用的下面 (实际开发中经常使用)


private String msg;
public String getMsg() {
    return msg;
}
private User user;
public User getUser() {
    return user;
}
    
private List list;
public List getList() {
    return list;
}
@Override
public String execute() throws Exception {
    ActionContext context = ActionContext.getContext();
    ValueStack stack = context.getValueStack();

    //通过get方法    定义一个全局变量 并提供get方法  然后在这里赋值
    msg="dfaaadfaf";
        
    //通过get方法 存对象
    user=new User(1,"da","man");
        
    //通过get方法  存集合
    list=new ArrayList();
    list.add(new User(2, "jack", "man"));
    list.add(new User(3, "marry", "woman"));
    return "ok";
    }

页面中查看 值栈的方法:在jsp页面中导入标签库<%@ taglib prefix="s" uri="/struts-tags" %> 并写

 
struts2入门_第2张图片
2.jpg
  • 取出root值栈中的数据 通过struts2标签库加OGNL表达式来取

取出get方法存入的值












    
    



    
    
    


通过jstl和el表达式来取


    ${uu.name}
${uu.sex}

问题: 为什么能取出来?
因为值栈是对域对象的增强,内部会从值栈中取出数据放到域对象中

取出set方法存入的值








取出push方法存入的值



15、OGNL表达式的使用 (对象导航语言)

获取域对象里的值

  • 通过#号+域对象在map栈中的引用.域对象中的key值
//向request域对象中存值
ServletActionContext.getRequest().setAttribute("uid", "我是request域对象");
//向application域对象中取值
ServletActionContext.getServletContext().setAttribute("ap","我是application域对象")

    

标识ognl表达式



$ 主要用于国际化验证的配置文件中取数据(例如:动态结果页面)

投影过滤 {}



16、struts2 拦截器

拦截器与过滤器区别:、过滤器理论上拦截一切资源 、拦截器(struts2中)只能拦截方法
1、自定义类 实现Interceptor接口
2、自定义类 继承AbstractInterceptor
3、自定义类 继承MethidFilterInterceptr 能拦截到具体方法 推荐

配置使用:

(局部拦截器)

1、声明拦截器


    

2、在action标签中使用拦截器


 
 

3、如何放行action中指定方法[只有继承MethidFilterInterceptr的拦截器才能忽略指定方法(放行指定方法)]


 
    忽略的方法名1,忽略的方法名2.....  
 
 

(全局拦截器)

1、声明自定义拦截器

2、定义拦截器栈

3、引入自定义拦截器和 系统默认拦截器栈![注意:必须引入 否则系统自带的拦截器都不能使用]

4、引入自定义拦截器栈


    
    
    
    
        
        
            
            test1
        
        
        
    




额外知识:当编写action时,没有指明class 默认使用ActionSupport类 result必须是success



    /hello.jsp

额外知识:配置默认处理action 启动服务器没输入地址或者输入的地址不存在 会默认调用这个action



    /hello.jsp

17、struts2 常用标签的使用

1、UI标签

(1)表单标签 form

   
         
         
        
        
        
   

(2)非表单标签

2、通用标签 if elseif else iterator debug property

(1)if标签


   

(2)iterator 迭代标签 等等、、、、、

18、文件的上传

  • 编写前端页面,上传数据的表单
请上传文件:
  • 编写action 定义三个全局变量 提供get方法 set也可以加上
    • File src 上传文件的临时目录
    • String srcFileName 文件名
    • String srcContentType 文件类型
private File temp;
private String tempFileName;
private String tempContentType;

public File getTemp() {
    return temp;
}
public void setTemp(File temp) {
    this.temp = temp;
}
public String getTempFileName() {
    return tempFileName;
}
public void setTempFileName(String tempFileName) {
    this.tempFileName = tempFileName;
}
public String getTempContentType() {
    return tempContentType;
}
public void setTempContentType(String tempContentType) {
    this.tempContentType = tempContentType;
}
  • 在Action方法内写、、
//获取路径
String path =ServletActionContext.getServletContext().getRealPath("/");
File destFile=new File(path,tempFileName);
FileUtils.copyFile(temp, destFile);
return "ok";

上传文件到自己指定路径时
1、在web.xml中配置 绝对路径


    path
    D:\Tomcat\webapps\images

2、获取路径通过getInetParameter

String path = ServletActionContext.getServletContext().getInitParameter("path");
File destFile=new File(path,tempFileName);
FileUtils.copyFile(temp, destFile);
return "ok";

19、日期转换器

a、自定义类继承数据转换类 StrutsTypeConverter

b、重写抽象方法

c、在src下 新建并编写配置文件 xwork-conversion.properties

20、json

你可能感兴趣的:(struts2入门)