`

Analyze ValidationErrors in ActionBeanContext

阅读更多


package net.sourceforge.stripes.action;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sourceforge.stripes.controller.FlashScope;
import net.sourceforge.stripes.controller.StripesConstants;
import net.sourceforge.stripes.controller.StripesFilter;
import net.sourceforge.stripes.tag.ErrorsTag;
import net.sourceforge.stripes.util.CryptoUtil;
import net.sourceforge.stripes.util.Log;
import net.sourceforge.stripes.validation.ValidationError;
import net.sourceforge.stripes.validation.ValidationErrors;


public class ActionBeanContext {
    private HttpServletRequest request;
    private HttpServletResponse response;
    private ServletContext servletContext;
    private String eventName;
    private ValidationErrors validationErrors;

    /**
     * Retrieves the HttpServletRequest object that is associated with the current request.
     * @return HttpServletRequest the current request
     */
    public HttpServletRequest getRequest() {
        return request;
    }

    /**
     * Used by the DispatcherServlet to set the HttpServletRequest for the current request
     * @param request the current request
     */
    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }

    /**
     * Retrieves the HttpServletResponse that is associated with the current request.
     * @return HttpServletResponse the current response
     */
    public HttpServletResponse getResponse() {
        return response;
    }

    /**
     * Used by the DispatcherServlet to set the HttpServletResponse that is associated with
     * the current request.
     * @param response the current response
     */
    public void setResponse(HttpServletResponse response) {
        this.response = response;
    }

    /**
     * Retrieves the ServletContext object that is associated with the context in which the
     * current request is being processed.
     * @return ServletContext the current ServletContext
     */
    public ServletContext getServletContext() {
        return servletContext;
    }

    /**
     * Sets the ServletContext object that is associated with the context in which the
     * current request is being processed.
     * @param servletContext the current ServletContext
     */
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    /**
     * Supplies the name of the event being handled.  While a specific method is usually invoked on
     * an ActionBean, through the use of default handlers ambiguity can arise.  This allows
     * ActionBeans to definitively know the name of the event that was fired.
     *
     * @return String the name of the event being handled
     */
    public String getEventName() {
        return eventName;
    }

    /**
     * Used by the DispatcherServlet to set the name of the even being handled.
     * @param eventName the name of the event being handled
     */
    public void setEventName(String eventName) {
        this.eventName = eventName;
    }

    /**
     * Returns the set of validation errors associated with the current form. Lazily
     * initialized the set of errors, and will never return null.
     *
     * @return a Collection of validation errors
     */
    public ValidationErrors getValidationErrors() {
        if (this.validationErrors == null) {
            this.validationErrors = new ValidationErrors();
        }

        return validationErrors;
    }

    /**
     * Replaces the current set of validation errors.
     * @param validationErrors a collect of validation errors
     */
    public void setValidationErrors(ValidationErrors validationErrors) {
        this.validationErrors = validationErrors;
    }

    /**
     * <p>Returns the default set of non-error messages associated with the current request.
     * Guaranteed to always return a List, though the list may be empty. It is envisaged that
     * messages will normally be added to the request as follows:</p>
     *
     *<pre>
     *getContext().getMessages().add( ... );
     *</pre>
     *
     * <p>To remove messages from the current request fetch the list of messages and invoke
     * remove() or clear().  Messages will be made available to JSPs during the current
     * request and in the subsequent request if a redirect is issued.</p>
     *
     * @return a List of Message objects associated with the current request, never null.
     * @see ActionBeanContext#getMessages(String)
     */
    public List<Message> getMessages() {
        return getMessages(StripesConstants.REQ_ATTR_MESSAGES);
    }

    /**
     * <p>Returns the set of non-error messages associated with the current request under the
     * specified key. Can be used to manage multiple lists of messages, for different purposes.
     * Guaranteed to always return a List, though the list may be empty. It is envisaged that
     * messages will normally be added to the request as follows:</p>
     *
     *<pre>
     *getContext().getMessages(key).add( ... );
     *</pre>
     *
     * <p>To remove messages from the current request fetch the list of messages and invoke
     * remove() or clear().</p>
     *
     * <p>Messages are stored in a {@link net.sourceforge.stripes.controller.FlashScope} for
     * the current request. This means that they are available in request scope using the
     * supplied key during both this request, and the subsequent request if it is the result
     * of a redirect.</p>
     *
     * @return a List of Message objects associated with the current request, never null.
     */
    @SuppressWarnings("unchecked")
    public List<Message> getMessages(String key) {
        FlashScope scope = FlashScope.getCurrent(getRequest(), true);
        List<Message> messages = (List<Message>) scope.get(key);

        if (messages == null) {
            messages = new ArrayList<Message>();
            scope.put(key, messages);
        }

        return messages;
    }

    /**
     * Gets the Locale that is being used to service the current request. This is *not* the value
     * that was submitted in the request, but the value picked by the configured LocalePicker
     * which takes into consideration the locales preferred in the request.
     *
     * @return Locale the locale being used for the current request
     * @see net.sourceforge.stripes.localization.LocalePicker
     */
    public Locale getLocale() {
        return this.request.getLocale();
    }

    /**
     * <p>Returns a resolution that can be used to return the user to the page from which they
     * submitted they current request.  Most useful in situations where a user-correctable error
     * has occurred that was too difficult or expensive to check at validation time. In that case
     * an ActionBean can call setValidationErrors() and then return the resolution provided by
     * this method.</p>
     *
     * @return Resolution a resolution that will forward the user to the page they came from
     * @throws IllegalStateException if the information required to construct a source page
     *         resolution cannot be found in the request.
     * @see #getSourcePage()
     */
    public Resolution getSourcePageResolution() {
        String sourcePage = getSourcePage();
        if (sourcePage == null) {
            return new ValidationErrorReportResolution(getValidationErrors());
        }
        else {
            return new ForwardResolution(sourcePage);
        }
    }

    /**
     * <p>
     * Returns the context-relative path to the page from which the user submitted they current
     * request.
     * </p>
     *
     * @return Resolution a resolution that will forward the user to the page they came from
     * @throws IllegalStateException if the information required to construct a source page
     *             resolution cannot be found in the request.
     * @see #getSourcePageResolution()
     */
    public String getSourcePage() {
        String sourcePage = request.getParameter(StripesConstants.URL_KEY_SOURCE_PAGE);
        if (sourcePage != null) {
            sourcePage = CryptoUtil.decrypt(sourcePage);
        }
        return sourcePage;
    }

    /**
     * Returns a String with the name of the event for which the instance holds context, and
     * the set of validation errors, if any.
     */
    @Override
    public String toString() {
        return "ActionBeanContext{" +
            "eventName='" + eventName + "'" +
            ", validationErrors=" + validationErrors +
            "}";
    }
}

class ValidationErrorReportResolution implements Resolution {
    private static final Log log = Log.getInstance(ValidationErrorReportResolution.class);
    private ValidationErrors errors;

    protected ValidationErrorReportResolution(ValidationErrors errors) {
        this.errors = errors;
    }

    public void execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // log an exception for the stack trace
        Exception exception = new IllegalStateException(
                "Here's how it is. Someone (quite possibly the Stripes Dispatcher) needed " +
                "to get the source page resolution. But no source page was supplied in the " +
                "request, and unless you override ActionBeanContext.getSourcePageResolution() " +
                "you're going to need that value. When you use a <stripes:form> tag a hidden " +
                "field called '" + StripesConstants.URL_KEY_SOURCE_PAGE + "' is included. " +
                "If you write your own forms or links that could generate validation errors, " +
                "you must include a value  for this parameter. This can be done by calling " +
                "request.getServletPath().");
        log.error(exception);
       
        // start the HTML error report
        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();
        writer.println("<html>");
        writer.println("<head><title>Stripes validation error report</title></head>");
        writer.println("<body style=\"font-family: Arial, sans-serif; font-size: 10pt;\">");
        writer.println("<h1>Stripes validation error report</h1><p>");
        writer.println(exception.getMessage());
        writer.println("</p><h2>Validation errors</h2><p>");
        sendErrors(request, response);
        writer.println("</p></body></html>");
    }
   
    protected void sendErrors(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        // Output all errors in a standard format
        Locale locale = request.getLocale();
        ResourceBundle bundle = null;

        try {
            bundle = StripesFilter.getConfiguration().getLocalizationBundleFactory()
                    .getErrorMessageBundle(locale);
        }
        catch (MissingResourceException mre) {
            log.warn(getClass().getName(), " could not find the error messages resource bundle. ",
                    "As a result default headers/footers etc. will be used. Check that ",
                    "you have a StripesResources.properties in your classpath (unless ",
                    "of course you have configured a different bundle).");
        }

        // Fetch the header and footer
        String header = getResource(bundle, "header", ErrorsTag.DEFAULT_HEADER);
        String footer = getResource(bundle, "footer", ErrorsTag.DEFAULT_FOOTER);
        String openElement = getResource(bundle, "beforeError", "<li>");
        String closeElement = getResource(bundle, "afterError", "</li>");

        // Write out the error messages
        PrintWriter writer = response.getWriter();
        writer.write(header);

        for (List<ValidationError> list : errors.values()) {
            for (ValidationError fieldError : list) {
                writer.write(openElement);
                writer.write(fieldError.getMessage(locale));
                writer.write(closeElement);
            }
        }

        writer.write(footer);
    }

    /**
     * Utility method that is used to lookup the resources used for the errors header,
     * footer, and the strings that go before and after each error.
     *
     * @param bundle the bundle to look up the resource from
     * @param name the name of the resource to lookup (prefixes will be added)
     * @param fallback a value to return if no resource can be found
     * @return the value to use for the named resource
     */
    protected String getResource(ResourceBundle bundle, String name, String fallback) {
        if (bundle == null) {
            return fallback;
        }

        String resource;
        try { resource = bundle.getString("stripes.errors." + name); }
        catch (MissingResourceException mre) { resource = fallback; }

        return resource;
    }
}

 

 

 

在alidate property in form, 我们要把错误信息存到validationErrors。

分享到:
评论

相关推荐

    How to Analyze IoT Data in ThingSpeak.zip

    标题 "How to Analyze IoT Data in ThingSpeak" 指的是一个教程,它教导用户如何在ThingSpeak平台上分析物联网(IoT)数据。ThingSpeak是一个开源的物联网平台,允许用户收集、存储、可视化和分析来自各种IoT设备的...

    Analyze Me Open Learner Model in an Adaptive Web Testing SystemPDF

    Analyze Me Open Learner Model in an Adaptive Web Testing SystemAnalyze Me Open Learner Model in an Adaptive Web Testing System

    wireshark analyze

    In order to analyze ping commond, usually select wlan use filter : icmp(Internet Control Message Protocol), because ICMP is one of TCP/TP protocol. It always be used to pass control data between...

    Analyze_Oracle_Table.rar_Table_analyze orac_analyze orac_oracle

    "Analyze_Oracle_Table.rar"这个压缩包文件的主题聚焦于Oracle表的分析,目的是提升查询和执行操作的效率。Oracle的性能可能会因为各种因素而下降,例如索引未被有效利用、数据分布不均匀或者统计信息过时等。因此,...

    A numerical method to analyze thermoacoustics in an IC engine by coupling wave equation with KIVA

    在KIVA程序中采用波动方程计算内燃机热声耦合性质的研究,舒歌群,韦静思,分析国内外对热声耦合领域的现状,比较内燃机燃烧中热声耦合过程与其他热声机械的异同,结合具体燃烧软件kiva理论,将声学模型于ki

    ANALYZE FORMAT 文档资料~

    ### Analyze Format:一种用于MRI图像存储的专用格式 #### 一、概述 Analyze Format是一种专门用于存储医学影像数据的文件格式,特别是在磁共振成像(MRI)领域有着广泛的应用。该格式由美国梅奥诊所(Mayo Clinic...

    convert_matlab下dicom转analyze_GUIHIMTconvert_dicomanalyze_

    在医疗成像领域,DICOM(Digital Imaging and Communications in Medicine)是一种广泛使用的图像文件格式,用于存储、传输和打印医学图像。而ANALYZE是另一种常用的医学图像格式,尤其在研究领域应用广泛。MATLAB是...

    Python for Finance Analyze Big Financial Data in Python 3

    I am really excited that Python has established itself as an important technology in the financial industry. I am also sure that it will play an even more important role there in the future, in fields...

    vss批量analyze,很好用的!

    ### VSS 批量 Analyze 实用技巧 在软件开发过程中,版本控制系统是不可或缺的工具之一,它能够帮助团队管理代码的变化、追踪历史版本并协同工作。Visual SourceSafe(简称 VSS)作为早期广泛使用的版本控制工具之一...

    前端开源库-analyze-css

    《analyze-css:深入理解前端CSS分析与优化》 在当今的Web开发中,前端性能是决定用户体验的关键因素之一,而CSS作为构建网页样式的核心技术,其优化显得尤为重要。"analyze-css"是一个强大的开源库,专为前端...

    Synthesize & Power Analyze

    Synthesize & Power Analyze

    Analyze6.exe

    在VC盘安装analyze6.exe,可解决link问题

    前端开源库-analyze-deps

    "analyze-deps" 是一个专为前端开发者设计的开源工具,旨在帮助用户分析并管理他们的 `package.json` 文件中的依赖项,确保它们与最新的可用版本相匹配。这个工具能够自动化这个过程,提升项目的维护效率。 首先,...

    QGroundControl Analyze 模块 源码

    《QGroundControl Analyze模块源码解析:洞察无人机传感器数据的奥秘》 QGroundControl Analyze模块是地面控制站软件QGroundControl的核心组件之一,它专注于处理和分析来自无人机的传感器原始数据。这个模块的源码...

    SIEMENS西门子Analyze MyWorkpiece-Monitor操作手册.pdf

    【标题】:“SIEMENS西门子Analyze MyWorkpiece-Monitor操作手册”涉及的知识点 【描述】:这份操作手册是针对SIEMENS西门子品牌的,主要讲解如何使用“Analyze MyWorkpiece / Monitor”工具,适用于SINUMERIK ONE ...

    Python Social Media Analytics: Analyze and visualize data from Twitter, YouTube

    Analyze and extract actionable insights from your social data using various Python tools A highly practical guide to conducting efficient social media analytics at scale Who This Book Is For If you ...

    Analyze Me: Open Learner Model in an Adaptive Web Testing System

    本文介绍了一种自适应网络测试系统中开放学习者模型(Open Learner Model, OLM)的功能。在自适应学习环境中,OLM允许系统根据学习者特征定制复合规则,这些规则决定了系统的适应性决策。这些学习者特征被以图形和...

    3D-Analyze

    《3D-Analyze:探索3D程序外挂软件的奥秘》 3D-Analyze,这个名字或许对一些电脑游戏爱好者来说并不陌生。它并非我们通常理解的显卡优化软件,而是一款独特的3D程序外挂工具,专为提升游戏性能和体验而设计。在本文...

    前端开源库-analyze-desumasu-dearu

    "analyze-desumasu-dearu"是一个专注于前端开发的开源库,其主要目标是对德马苏·迪鲁(Desumasu Dearu)进行分析,同时也涉及到了文敬体和常体的解析。下面我们将详细探讨这个开源库以及相关的前端知识点。 首先,...

Global site tag (gtag.js) - Google Analytics