当前位置: 首页 > 面试题库 >

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

林铭
2023-03-14
问题内容

主要问题

工作流程应如下:如果输入的字符串不是数字,则首先应通过异常拦截器,当通过参数拦截器时,转换为int类型时,将无法使用Integer.parseInt和来完成此操作。将会发生异常;难道不应该将该异常(即NumberFormatException)推入Value Stack吗?为什么NumberFormatException即使不打印结果也不能显示结果呢?

附带问题

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

index.jsp

<%@ taglib uri="/struts-tags" prefix="s"%>
<s:form action="divide">
    <s:textfield name="number1" label="number1"/>
    <s:textfield name="number2" label="number2"/>
    <s:submit value="divide"/>
</s:form>

除法

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" %>
<b>
    the result of division is
    <s:property value="result"/>
</b>
<jsp:include page="index.jsp"></jsp:include>

处理程序jsp

<%@taglib uri="/struts-tags" prefix="s"%>
<b>
    following exception occured during the processing
    <s:property value="exception"/>
</b>
<jsp:include page="index.jsp"/>

struts.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC 
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
    <struts>
        <package name="yo" extends="struts-default">
            <action name="divide" class="actions.divide">
                <exception-mapping result="error" exception="Exception"/>
                <result name="success">/result.jsp</result>
                <result name="error">/handler.jsp</result>
            </action>
        </package>
    </struts>

问题答案:

主要问题:

工作流程应该是这样的,如果输入的字符串不是数字,则首先应通过异常拦截器,然后在通过参数拦截器转换为int类型时将无法使用Integer进行操作。 parseInt并发生异常,该异常(即数字格式异常)应被推入值堆栈?为什么即使不打印结果,它也不显示numberformatexception并显示结果?

概念

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

详细的工作流程

  1. 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);
            }
        }
    }
}
  1. 在Conversion Errors Interceptor为每一个找到,它增加了一个:如果任何转换误差发生的检查Field Error; 它还保存原始值,以便对该值的任何后续请求都返回原始值,而不是操作中的值。从文档中:

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

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

  1. 该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 -->

附带问题:
每当我在表格中添加一个字母时,它就会变为零…?为什么这样?

最初的答案是:在将请求发布到服务器时,框架无法将a设置String为int字段,并且在结果页中检索值时,框架将调用该变量的Getter。由于您定义了anint和not Integer,并且anint不能为null,因此它将返回an的默认值int:0。

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

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

在类型转换期间发生的任何错误可能会或可能不会希望被报告。例如,报告输入的“ abc”无法转换为数字可能很重要。另一方面,报告一个空字符串“”不能转换为数字可能并不重要-尤其是在网络环境中,很难区分用户没有输入值还是输入空白值。

相反,我很好地记住了您的问题中描述的行为。所以这个案子已经处理了……为什么不起作用呢?在我(可能是您)的情况下,罪魁祸首是以下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属性,以使其以正确的方式工作,然后开始查找错误。



 类似资料:
  • 我正试图决定如何处理猫鼬中的验证错误。 我使用节点验证器定义了自己的验证规则,例如: 这将产生如下错误: 然而,节点验证器提供了自己的错误消息。如果我使用mongoose validator节点模块将节点验证器直接插入到我的模式中,那么我可以直接使用这些错误消息: 这将生成一条错误消息,如下所示: 我也可以在此处提供自定义错误消息: Mongoose允许您根据需要定义字段: 这将生成一条错误消息,

  • 因此,应用程序流程如下: Spring应用程序接收请求- 这是我正在使用的网络客户端(副本): 现在我不想通过控制器将此Mono对象直接返回到客户端(如Angular应用程序),因为这是一个中间步骤。我想对从 WebClient 收到的响应运行一些验证。 我已经试过<代码>。block()方法来检索函数,但是按照反应式编程,这似乎是一种不好的做法。(阻塞操作)此外,我无法理解如何使用<代码>。su

  • 问题内容: 我有一个mysqli查询,我需要将其格式化为移动应用程序的JSON。 我已经设法为查询结果生成一个XML文档,但是我正在寻找更轻量的东西。(有关我当前的XML代码,请参见下文) 问题答案: 这样的输出: 如果您想要其他样式,可以尝试以下方法: 输出将是这样的:

  • 问题内容: 我在节点上使用npm 驱动程序。 我有 问题是说我没有任何结果,仍然是我是否找到结果。我怎么知道查询没有找到结果? 我也尝试过 但这仅仅是(它看起来是异步的,所以我不认为这是要走的路。) 问题答案: 未找到任何记录都不是错误情况,因此您要查找的是中缺少值。由于任何匹配的文档将始终是“真实的”,因此您只需使用简单的检查即可。例如,

  • 我正试图将我的列表写到抽象模型中的jtable,然后它返回给我这个错误。在我看来,这可能是由列表格式引起的?名称和金额在错误的地方。这是我的完整错误消息:线程“awt-eventqueue-0”java.lang.ClassCastException:类com.google.gson.internal.LinkedTreemap不能强制转换为类model.medicine(com.google.g

  • 问题内容: 由于使用JDBC连接器进行MySQL查询,因此我有一个结果集。所以我的工作是将结果集转换为JSON格式。这样我就可以将其作为AJAX响应发送到客户端。有人可以解释一下如何转换为JSON格式,因为我对Java和JSON都是新手 问题答案: 许多人正确地回答了这个问题。但是,我认为我可以使用以下几小段代码为该帖子添加更多价值。它使用Apache-DBUtils和Gson库。