Struts2 INPUT结果:它是如何工作的?如何处理转换/验证错误?

 青锋寒万岁 发布于 2023-01-17 10:02

主要问题

工作流应该是这样的:如果输入的字符串不是数字,首先它应该通过异常拦截器,并且当通过param拦截器时,在转换为int类型时,它将无法使用Integer.parseInt和异常会发生; 不应该将那个异常(即NumberFormatException)推入Value Stack吗?为什么NumberFormatException即使不打印结果也不显示和显示结果?

边问题

每当我在表单中添加一个字母表时,它就会变为零......?为什么这样 ?

的index.jsp

<%@ taglib uri="/struts-tags" prefix="s"%>

    
    
    

divide.java

package actions;

public class divide {
    int number1,number2,result;
    public String execute() throws Exception
    {
        result=number1/number2;
        return "success";
    }
    public int getNumber1() {
        return number1;
    }
    public void setNumber1(int number1) {
        this.number1 = number1;
    }
    public int getNumber2() {
        return number2;
    }
    public void setNumber2(int number2) {
        this.number2 = number2;
    }
    public int getResult() {
        return result;
    }


}

result.jsp中

<%@taglib uri="/struts-tags" prefix="s" %>

    the result of division is
    


处理程序jsp

<%@taglib uri="/struts-tags" prefix="s"%>

    following exception occured during the processing
    


在struts.xml




    
        
            
                
                /result.jsp
                /handler.jsp
            
        
    

Andrea Ligio.. 10

主要问题:

工作流应该是这样的,如果输入的字符串不是数字,首先它应该通过异常拦截器,并且当通过param拦截器时,在转换为int类型时,它将无法使用Integer来完成. parseInt和异常会发生,数字格式异常的异常应该被推入值栈吗?那么为什么它不显示numberformatexception并显示结果,即使结果不应该打印?

概念

Struts 2自动处理转换错误验证错误:它不会引发异常,因为它们不会阻止错误,而是输入错误,因此最好的方法是通知用户提交的输入是错误的,问他获得新的有效输入.为此,返回INPUT结果,同时忽略Exception.

详细的worflow

    Parameters Interceptor试图设置的参数.如果RuntimeException(类似NumberFormatException)被捕获并且devModetrue,则向其添加错误消息Action Errors,否则简单地吞下该异常.从源代码:

    for (Map.Entry entry : acceptableParameters.entrySet()) {
        String name = entry.getKey();
        Object value = entry.getValue();
        try {
            newStack.setParameter(name, value);
        } catch (RuntimeException e) {
            if (devMode) {
                String developerNotification = LocalizedTextUtil.findText(ParametersInterceptor.class, "devmode.notification", ActionContext.getContext().getLocale(), "Developer Notification:\n{0}", new Object[]{
                         "Unexpected Exception caught setting '" + name + "' on '" + action.getClass() + ": " + e.getMessage()
                });
                LOG.error(developerNotification);
                if (action instanceof ValidationAware) {
                    ((ValidationAware) action).addActionMessage(developerNotification);
                }
            }
        }
    }
    

    Conversion Errors Interceptor为每一个发现,它增加了一个:如果任何转换误差发生的检查Field Error; 它还保存原始值,以便对该值的任何后续请求返回原始值而不是操作中的值.从文档:

    此拦截器将ActionContext的conversionErrors映射中发现的任何错误添加为字段错误(假设该操作实现了ValidationAware).此外,包含验证错误的任何字段都会保存其原始值,以便对该值的任何后续请求都返回原始值而不是操作中的值.这很重要,因为如果提交值"abc"并且无法转换为int,我们想再次显示原始字符串("abc")而不是int值(可能为0,这很有意义)给用户).

    Validation Interceptor所有的验证请求的执行(在XML,注解或通过定义的validate()validateXXX()行动的方法),将一个或多个错误消息到Field Errors每个字段不通过一个或多个验证标准.

    Workflow Interceptor检查是否存在Field Errors(无论是从转换错误或验证错误来).如果没有找到错误,它会继续链接到下一个拦截器.如果找到一个或多个错误,则返回INPUT结果.

要确保此机制有效,您需要在自定义堆栈中以正确的顺序定义这四个拦截器,如果您没有使用默认拦截器堆栈(否则您不需要执行任何操作).来自struts-default.xml:



    ^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.*



    input,back,cancel,browse


    input,back,cancel,browse


问题:

每当我在表单中添加一个字母表时,它就会变为零......?为什么这样?

最初的答案是:框架在将请求发布到服务器时无法设置Stringint字段,并且在结果页面中检索值时,它会调用该变量的Getter; 既然你定义了一个int而不是一个Integer,并且一个int不能为null,它将返回一个默认值int:0.

但我不记得转化拦截器声称(读取点n.2)保存原始值,以便在随后的未来请求中提供它们,而不是Action值(将为null或0).类型转换错误处理中也提到了这一点:

类型转换错误处理提供了一种区分输入验证问题和输入类型转换问题的简单方法.

在类型转换期间发生的任何错误可能希望报告,也可能不希望报告.例如,报告输入"abc"无法转换为数字可能很重要.另一方面,报告空字符串""无法转换为数字可能并不重要 - 尤其是在难以区分未输入值的用户与输入空白值的Web环境中.

...

相反,我很清楚你的问题中描述的行为.所以这个案子已经处理好了......为什么它不起作用呢?罪魁祸首,在我的情况下(可能是你的),是value属性:

这将0在发布时给你abc:


因为会出现进一步的转换错误.

这两种情况相反如上所述,abc在发布时给你abc:




结论

确保正确配置拦截器堆栈,并且

仔细检查你的代码(很可能不是这里发布的代码),看看你对你的value属性做了什么.

出于测试目的,首先尝试删除value属性,以正确的方式查看它,然后开始查找错误.

1 个回答
  • 主要问题:

    工作流应该是这样的,如果输入的字符串不是数字,首先它应该通过异常拦截器,并且当通过param拦截器时,在转换为int类型时,它将无法使用Integer来完成. parseInt和异常会发生,数字格式异常的异常应该被推入值栈吗?那么为什么它不显示numberformatexception并显示结果,即使结果不应该打印?

    概念

    Struts 2自动处理转换错误验证错误:它不会引发异常,因为它们不会阻止错误,而是输入错误,因此最好的方法是通知用户提交的输入是错误的,问他获得新的有效输入.为此,返回INPUT结果,同时忽略Exception.

    详细的worflow

      Parameters Interceptor试图设置的参数.如果RuntimeException(类似NumberFormatException)被捕获并且devModetrue,则向其添加错误消息Action Errors,否则简单地吞下该异常.从源代码:

      for (Map.Entry<String, Object> entry : acceptableParameters.entrySet()) {
          String name = entry.getKey();
          Object value = entry.getValue();
          try {
              newStack.setParameter(name, value);
          } catch (RuntimeException e) {
              if (devMode) {
                  String developerNotification = LocalizedTextUtil.findText(ParametersInterceptor.class, "devmode.notification", ActionContext.getContext().getLocale(), "Developer Notification:\n{0}", new Object[]{
                           "Unexpected Exception caught setting '" + name + "' on '" + action.getClass() + ": " + e.getMessage()
                  });
                  LOG.error(developerNotification);
                  if (action instanceof ValidationAware) {
                      ((ValidationAware) action).addActionMessage(developerNotification);
                  }
              }
          }
      }
      

      Conversion Errors Interceptor为每一个发现,它增加了一个:如果任何转换误差发生的检查Field Error; 它还保存原始值,以便对该值的任何后续请求返回原始值而不是操作中的值.从文档:

      此拦截器将ActionContext的conversionErrors映射中发现的任何错误添加为字段错误(假设该操作实现了ValidationAware).此外,包含验证错误的任何字段都会保存其原始值,以便对该值的任何后续请求都返回原始值而不是操作中的值.这很重要,因为如果提交值"abc"并且无法转换为int,我们想再次显示原始字符串("abc")而不是int值(可能为0,这很有意义)给用户).

      Validation Interceptor所有的验证请求的执行(在XML,注解或通过定义的validate()validateXXX()行动的方法),将一个或多个错误消息到Field Errors每个字段不通过一个或多个验证标准.

      Workflow Interceptor检查是否存在Field Errors(无论是从转换错误或验证错误来).如果没有找到错误,它会继续链接到下一个拦截器.如果找到一个或多个错误,则返回INPUT结果.

    要确保此机制有效,您需要在自定义堆栈中以正确的顺序定义这四个拦截器,如果您没有使用默认拦截器堆栈(否则您不需要执行任何操作).来自struts-default.xml:

    <!-- others interceptors here... -->
    <interceptor-ref name="params">
        <param name="excludeParams">^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.*</param>
    </interceptor-ref>
    <interceptor-ref name="conversionError"/>
    <interceptor-ref name="validation">
        <param name="excludeMethods">input,back,cancel,browse</param>
    </interceptor-ref>
    <interceptor-ref name="workflow">
        <param name="excludeMethods">input,back,cancel,browse</param>
    </interceptor-ref>
    <!-- ... others interceptors here -->
    

    问题:

    每当我在表单中添加一个字母表时,它就会变为零......?为什么这样?

    最初的答案是:框架在将请求发布到服务器时无法设置Stringint字段,并且在结果页面中检索值时,它会调用该变量的Getter; 既然你定义了一个int而不是一个Integer,并且一个int不能为null,它将返回一个默认值int:0.

    但我不记得转化拦截器声称(读取点n.2)保存原始值,以便在随后的未来请求中提供它们,而不是Action值(将为null或0).类型转换错误处理中也提到了这一点:

    类型转换错误处理提供了一种区分输入验证问题和输入类型转换问题的简单方法.

    在类型转换期间发生的任何错误可能希望报告,也可能不希望报告.例如,报告输入"abc"无法转换为数字可能很重要.另一方面,报告空字符串""无法转换为数字可能并不重要 - 尤其是在难以区分未输入值的用户与输入空白值的Web环境中.

    ...

    相反,我很清楚你的问题中描述的行为.所以这个案子已经处理好了......为什么它不起作用呢?罪魁祸首,在我的情况下(可能是你的),是value属性:

    这将0在发布时给你abc:

    <s:textfield name = "myIntField" 
                value = "%{getText('format.number',{myIntField})}" />
    

    因为会出现进一步的转换错误.

    这两种情况相反如上所述,abc在发布时给你abc:

    <s:textfield name = "myIntField" />
    
    <s:textfield name = "myIntField" 
                value = "%{myIntField}" />
    

    结论

    确保正确配置拦截器堆栈,并且

    仔细检查你的代码(很可能不是这里发布的代码),看看你对你的value属性做了什么.

    出于测试目的,首先尝试删除value属性,以正确的方式查看它,然后开始查找错误.

    2023-01-17 10:05 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有