继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

从零打造在线网盘系统之Struts2框架核心功能全解析

蝴蝶刀刀
关注TA
已关注
手记 368
粉丝 37
获赞 183

接收参数 示例源码下载

Struts2接收参数有三种方式,

  1. Servlet API

  2. getter和Setter方法

  3. 模型驱动

Servlet API

    @Action(value = "register")    public void register() {
        ActionContext context = ActionContext.getContext();
        HttpServletRequest httpServletRequest = (HttpServletRequest) context.get(StrutsStatics.HTTP_REQUEST);
        String username = httpServletRequest.getParameter("username");
        String password = httpServletRequest.getParameter("password");
        System.out.println("username:" + username + "    password:" + password);
    }

getter和Setter方法

    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;
    }

    @Action(value = "register")    public void register() {
        System.out.println("username:" + username + "    password:" + password);
    }

当然你也可以使用JavaBean进行接收参数,类似下面这样,前端传递的name属性需要有些变动,name属性需要改成xxxx.xxx与属性名一致

<form action="register.action" method="get">
    <input name="user.username" type="text">
    <input name="user.password" type="text">
    <input type="submit">
</form>
    private User user;    public User getUser() {        return user;
    }    public void setUser(User user) {        this.user = user;
    }

    @Action(value = "register")    public void register() {
        System.out.println("username:" + user.getUsername() + "    password:" + user.getPassword());
    }

模型驱动

@ParentPackage("default")public class RegisterAction implements ModelDriven<User> {    private User user = new User();    @Override
    public User getModel() {        return user;
    }    
    @Action(value = "register")    public void register() {
        System.out.println("username:" + user.getUsername() + "    password:" + user.getPassword());
    }


}
![1](7623C3566DA045869126C1B9D546A934)

参数校验 示例源码下载

对于前端传递的参数来讲,存在太多不稳定性,所以对于参数的校验是必不可少的,对于校验来说大体上分为两种,一种是前端校验,一种是后端校验,前端校验的方法在这里就不再累述,这里仅仅讲述Struts2如何使用Validation校验框架

获取参数

  private String username;  private String password;
  getter and setter......

在Action同级目录增加

<!DOCTYPE validators PUBLIC
        "-//Apache Struts//XWork Validator 1.0.2//EN"
        "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd"><validators>
    <!-- 要对哪个属性进行验证 -->
    <field name="username">
        <!-- 验证规则 -->
        <field-validator type="requiredstring">
            <!-- 违反规则的提示 -->
            <message>用户名不能为null!</message>
        </field-validator>
    </field>
    <field name="password">
        <field-validator type="requiredstring">
            <message>密码不能为null</message>
        </field-validator>
    </field></validators>

核心Action(这里可以看到如果校验正确跳转 "/success.jsp",如果校验失败错误信息输出在"/form.jsp")

    @Override
    @Action(value = "register", results = {            @Result(name = SUCCESS, location = "/success.jsp"),            @Result(name = INPUT,location = "/form.jsp")
    })
    public String execute() throws Exception {        System.out.println("username"+username+"password:"+password);        return SUCCESS;
    }

下载本小节源码访问http://localhost:8080/form.jsp

5bf013f700010aab02890172.jpg

数据转换 示例源码下载

WEB系统都是基于网页形式的,接收到的信息都是字符串,Java又是强类型的语言,所以必须需要一个转换的过程.而Struts2的类型转换是基于OGNL表达式的,只需要将表单中的name属性根据OGNL规则命名就能转换成相应的Java类型,通常情况下哦我们无需建立自己的类型转换器,Struts2的内建转换器完全能帮助我们完成任务
5bf013f8000143c414910428.jpg

例如我们有下面一个需求(包含Integer,Date,数组的转换)
5bf013f900011c0613870657.jpg

我们该怎么办呢?不不不~~~~我们什么都不用做正常编写Action就行了,Struts2会自动帮我们进行转换

public class RegisterAction extends ActionSupport implements ModelDriven<User> {    private User user = new User();    @Override
    public User getModel() {        return user;
    }    @Override
    @Action(value = "register", results = {            @Result(name = SUCCESS, location = "/success.jsp")
    })
    public String execute() throws Exception {        System.out.println(user.toString());        return SUCCESS;
    }
}

5bf013f900014c4111480032.jpg

好吧,真的没什么挑战力,下面我们要自己实现转换器了

例如:我们需要将字符串"自行车,1033,100"转换为Java的Product对象

自定义转换器

public class StringToProductTypeConverter extends DefaultTypeConverter {    
    @Override
    public Object convertValue(Map context, Object value, Class toType) {        if (toType == Product.class) {            String[] params = (String[]) value;            Product product = new Product();            String[] productValues = params[0].split(",");
            product.setProductName(productValues[0].trim());
            product.setPrice(Float.parseFloat(productValues[1].trim()));
            product.setCount(Integer.parseInt(productValues[2].trim()));            return product;
        } else if (toType == String.class) {            Product product = (Product) value;            return product.toString();
        }        return null;
    }

}

配置全局转换器(在WEB-INF\classes目录新建xwork-conversion.properties)

com.jimisun.action.Product=com.jimisun.action.StringToProductTypeConverter

在Action中接收(不要使用模型驱动方式接收参数,接收不到)

public class ProductAction extends ActionSupport {    private Product product;

    public Product getProduct() {        return product;
    }

    public void setProduct(Product product) {        this.product = product;
    }    @Override
    @Action(value = "register", results = {            @Result(name = SUCCESS, location = "/success.jsp")
    })
    public String execute() throws Exception {        System.out.println(product.toString());        return SUCCESS;
    }
}

5bf013f900019cc610820237.jpg

响应数据 示例源码下载

我们一直都没有探讨一个问题,那就是Struts2的结果的响应.对于任何一个程序而言,最重要的莫过于输入和输出,当我们了解了Struts2接收参数后,现在我们一起来看一看Struts2如何响应参数吧

  • Servlet API存取值

  • 属性值存取值

  • 值栈Set方法存取值

  • 值栈Push方法存取值

Servlet API存取值

    ActionContext context = ActionContext.getContext();
    HttpServletRequest request  = (HttpServletRequest) context.get(StrutsStatics.HTTP_REQUEST);    request.setAttribute("requestValue","requestValue");
<%--从Servlet API的Request域对象中取值--%>
Request取值:<s:property value="#request.requestValue"/>

属性值存取值

private User user = new User("jimisun", "jimisun");
<%--获取属性值--%>
简单属性取值:<s:property value="user.username"/>

那么对于复杂的属性存取值我们可以这样,例如List

private List<User> list = new ArrayList<>();
  User user1 = new User("list1","list1");
  User user2 = new User("list2","list2");  list.add(user1);  list.add(user2);
<%--获取属性List值--%>list属性取值:<br><s:iterator value="list" var="user">

    <s:property value="#user.username"/>
    <s:property value="#user.password"/>
    <br/></s:iterator>

值栈Set方法存取值

 ActionContext context = ActionContext.getContext();
 ValueStack valueStack = context.getValueStack();
 valueStack.set("valueStackDemo", "valueStackDemoSet");
<%--值栈Set方法取值--%>
值栈set取值:<s:property value="valueStackDemo"/>

值栈Push方法存取值

 ActionContext context = ActionContext.getContext();
 ValueStack valueStack = context.getValueStack();
 valueStack.push("valueStackPush");
<%--值栈Push方法取值--%>
值栈push取值:<s:property value="[0].top"/>

OK,现在对于Struts2的几种数据的响应方式我们大概已经知道了,现在我们来看一看这几种存储数据方式在值栈中的结构,在本小节源码中运行项目直接访问http://localhost:8080/outputdate.action即可
5bf013fa0001d02918700874.jpg

注意点:使用OGNL表达式访问"根"对象中的对象及属性时,不需要前面加"#"号

文件上传 示例源码下载

对于文件上传功能Struts2并没有提出自己的解决方案,但是Struts2为文件上传提供了统一的接口,开发人员在使用上传文件的组件时,并不需要知道太多的细节就可以轻松使用他们,Struts2目前支持三种上传文件组件Commons-FileUpload,cos,pell,例如我们使用Commons-FileUpload为例来快速学习文件上传功能

commons-fileupload依赖(已经内置,无须再次添加)

5bf013fb0001a37105090203.jpg

struts.properties相关配置

struts.multipart.parser=jakarta
struts.multipart.maxSize=2097152

核心上传代码

    @Action(value = "UploadAction", params = {"uploadPath", "D:/"}, results = {            @Result(name = "success", location = "/result.jsp")
    })    public String execute() throws Exception {
        String fn = "";        if (filename.equals("")) {
            fn = uploadPath + uploadFileName;
        } else {
            fn = uploadPath + filename;
        }        if (new File(fn).exists()) {
            result = "该文件已经存在!";
        } else {
            FileOutputStream fileOutputStream = new FileOutputStream(fn);
            InputStream inputStream = new FileInputStream(upload);            byte[] buffer = new byte[8192];            int count = 0;            while ((count = inputStream.read(buffer)) > 0) {
                fileOutputStream.write(buffer, 0, count);
            }
            fileOutputStream.close();
            inputStream.close();
            result = "文件上传成功!";
        }        return "success";
    }

5bf013fc000160d203600129.jpg

下面我们再进行展示同时上传多个文件的示例,对于同时上传多个文件,我们仅仅需要做一点改变即可,即接收值的属性改成数组或者List集合

    private File[] upload;    private String[] uploadFileName;
    @Action(value = "UploadAction", params = {"uploadPath", "D:/"}, results = {            @Result(name = "success", location = "/result.jsp")
    })    public String execute() throws Exception {        for (int i = 0; i < uploadFileName.length; i++) {
            String fn = uploadPath + uploadFileName[i];
            FileOutputStream fileOutputStream = new FileOutputStream(fn);
            InputStream inputStream = new FileInputStream(upload[i]);            byte[] buffer = new byte[8192];            int count = 0;            while ((count = inputStream.read(buffer)) > 0) {
                fileOutputStream.write(buffer, 0, count);
            }
            fileOutputStream.close();
            inputStream.close();
        }
        result = "文件上传成功!";        return "success";
    }

5bf013fc00011a2c02540148.jpg

我们了解了文件上传那么现在我们再来一起看一下文件的下载,再Struts2中提供了一种使用Stream下载文件的方式,类似于文件和浏览器的一个"代理",通过这个"代理"我们就能控制某某下载文件,如下是一个Download的Action

public InputStream getFileInputStream() {        // 以及文件的mime类型以及创建流
        ServletContext context = ServletActionContext.getServletContext();
        contentType = context.getMimeType(context.getRealPath(filePath + "/" + fileName));
        setContentType(contentType);        return context.getResourceAsStream(filePath + "/" + fileName);
    }    @Override
    @Action(value = "download", params = {"filePath", "/file"}, results = {            @Result(name = SUCCESS, type = "stream",
                    params = {"contentType", "${contentType}", "inputName", "fileInputStream", "contentDisposition", "attachment;filename=\"${fileName}\""})
    })    public String execute() throws Exception {        return SUCCESS;
    }

5bf013fc00013c5305790062.jpg

异常处理 示例源码下载

异常处理是任何成熟的MVC框架必备的功能,在Struts2中提供了异常的拦截器,我们可以在struts.xml文件中进行配置异常,以灵活的方式处理异常

配置全局异常

    <package name="default" extends="struts-default" namespace="/">
        <global-results>
            <result name="exception">/error.jsp</result>
        </global-results>
        
        <global-exception-mappings>
            <exception-mapping exception="java.sql.SQLException" result="exception"></exception-mapping>
        </global-exception-mappings>
        
        ...    </package>

模拟异常

@ParentPackage("default")
public class ExceptionAction extends ActionSupport {    @Override
    @Action(value = "testerror", results = {            @Result(name = SUCCESS, location = "/success.jsp")
    })
    public String execute() throws Exception {        if ("a".equals("a")) {            throw new SQLException("SQL错误!!!");
        }        return SUCCESS;
    }
}

当发生异常后就会跳转到所配置的error.jsp页面
5bf013fe0001336a18390871.jpg

国际化支持 示例源码下载

Struts2的国际化支持是建立在Java对国际化的支持之上的,对Java的国际化支持进行了封装,下面我们来针对一段优美的诗,我们我们将会展示中文和英文两种页面给访问者

我那美丽的女孩
我的挚爱
无论梦里梦外
去去来来

抬头眺望云端
高不可攀
低头忆你容颜
温柔绚烂

配置Struts2全局资源文件(使用下面两种方式都可以)

在struts.properties中配置
struts.custom.i18n.resources=Resource
在struts.xml中配置<constant name="struts.custom.i18n.resources" value="Resource"/>

创建两个资源文件(中文和英文)

Resource_en_US.properties

welcome = hello,{0}content = My beautiful girl, my love, my dream, my dream, my dream, my dream, my dream

Resource_zh_CN.properties

welcome = 你好,{0}content = 我那美丽的女孩 我的挚爱 无论梦里梦外 去去来来 抬头眺望云端 高不可攀 低头忆你容颜 温柔绚烂

在Action中使用

public class BeautifulGirlAction extends ActionSupport {    private String username;    private String content;    private String welcome;    @Override
    @Action(value = "girl", results = {            @Result(name = SUCCESS, location = "/success.jsp")
    })
    public String execute() throws Exception {
        welcome = getText("welcome", new String[]{username});
        content = getText("content");        return SUCCESS;
    }
    ...
}

通过下载本小节示例源码访问http://localhost:8080/form.jsp
5bf014000001fdee15190504.jpg

本章总结

在WEB应用中常见的功能是很多的,很多场景下Struts2都为我们提供了响应的解决方案,本章叙述中在下主要讲述了Struts2的常见的功能的基本使用,即只有广度而没有深度,更为深度的学习还希望小伙伴们查阅相关资料,例如OGNL表达式等...

原文出处:https://www.cnblogs.com/jimisun/p/9969406.html  

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP