Agreed, good point.

> On 30 Sep 2015, at 3:34 am, Thiago H de Paula Figueiredo <thiag...@gmail.com> 
> wrote:
> 
> Hi!
> 
> Very nice point. Could you please create a JIRA issue?
> 
> On Tue, 29 Sep 2015 13:55:10 -0300, Cezary Biernacki <cezary...@gmail.com> 
> wrote:
> 
>> Hi,
>> 
>> Some introduction: My users started complaining about error message "Forms
>> require that the request method be POST and that the t:formdata query
>> parameter have values.". I understand why it was raised: Tapestry 5's Form
>> component always used to complain when submit was invoked as GET operations
>> (e.g. somebody typed "http://host/mypage.myform"; URL directly in the
>> address bar) . Pre-5.4 it was not big issue, because it was rather unusual
>> to users to accidentally invoke submit URL as GET operations, as Tapestry
>> always used Redirect-After-POST approach, and submit URLs typically were
>> not saved by browsers in the history. However Tapestry 5.4 does not
>> redirect after POST in case of server-side validation errors on submitted
>> forms (e.g. password checking). IIRC, this change was introduced to avoid
>> unnecessary creation of server side sessions.
>> 
>> Again, I understand that. But now submit URLs are often exposed address bar
>> (e.g. every time a user makes mistake entering password), stored in the
>> browser's history, and - most importantly - suggested by browsers when
>> users start typing the application address. I believe such behaviour leads
>> to bad usability and leaves unpleasant impression of Tapestry's
>> application. As far as I can tell there is no simple work around to avoid
>> the exception (beside totally rewriting Form component).  Only way I found
>> that works reasonably well is to suppress the exception in
>> RequestExceptionHandler and perform some other action - in my case:
>> redirect to the page - see code below.
>> 
>> However detecting this particular exception is tricky as it is just generic
>> RuntimeException (why?) and the message content is localised
>> (see org.apache.tapestry5.corelib.components.Form#executeStoredActions -
>> around line 700
>> https://github.com/apache/tapestry-5/blob/master/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java#L701),
>> so detecting is quite fragile.
>> 
>> My questions:
>> - do you know any better way to deal with this problem?
>> - do you see any potential issues with my solution?
>> 
>> And appeal to Tapestry's creators: please introduce a more specific
>> exception class and/or allow application developers to supply their own
>> strategy dealing with such situation.
>> 
>> Best regards,
>> Cezary
>> 
>> 
>> 
>> // skipped  header (imports etc.)...
>> 
>> public class FormPostProblemWorkaroundExceptionHandler implements
>> RequestExceptionHandler {
>> 
>> private static final Logger LOGGER = LoggerFactory.getLogger
>> (FormPostProblemWorkaroundExceptionHandler.class);
>> 
>> private final RequestExceptionHandler delegate;
>> 
>> private final RequestGlobals requestGlobals;
>> 
>> private final BaseURLSource baseURLSource;
>> 
>> private final PageRenderLinkSource pageRenderLinkSource;
>> 
>> 
>> public FormPostProblemWorkaroundExceptionHandler(
>> final RequestExceptionHandler delegate,
>> final RequestGlobals requestGlobals,
>> final BaseURLSource baseURLSource,
>> final PageRenderLinkSource pageRenderLinkSource
>> ) {
>> this.delegate = delegate;
>> this.requestGlobals = requestGlobals;
>> this.baseURLSource = baseURLSource;
>> this.pageRenderLinkSource = pageRenderLinkSource;
>> }
>> 
>> @Override
>> public void handleRequestException(final Throwable exception) throws
>> IOException
>> {
>> if (isExceptionAboutFormExpectingPostMethod(exception)) {
>> redirect(exception);
>> return;
>> }
>> 
>> delegate.handleRequestException(exception);
>> }
>> 
>> private boolean isExceptionAboutFormExpectingPostMethod(final Throwable
>> exception) {
>> // unfortunately, original exception is just RuntimeException and its
>> message is localised
>> // (see Tapestry message ID core-invalid-form-request), only constant
>> information is reference to t:formdata argument
>> // see org.apache.tapestry5.corelib.components.Form.executeStoredActions()
>> return exception instanceof OperationException
>> && exception.getCause() instanceof ComponentEventException
>> && exception.getMessage().contains(Form.FORM_DATA);
>> }
>> 
>> private void redirect(final Throwable exception) throws IOException {
>> 
>> final Request request = requestGlobals.getRequest();
>> final String failurePage = (request.getAttribute(InternalConstants.
>> ACTIVE_PAGE_LOADED) == null)
>> ? null
>> : requestGlobals.getActivePageName();
>> 
>> final Response response = requestGlobals.getResponse();
>> 
>> if (failurePage == null) {
>> final String rootURL = baseURLSource.getBaseURL(request.isSecure());
>> LOGGER.info("Redirecting to root URL {} after '{}'", rootURL,
>> exception.getMessage());
>> response.sendRedirect(rootURL);
>> return;
>> }
>> 
>> final Link link = pageRenderLinkSource.createPageRenderLink(failurePage);
>> LOGGER.info("Redirecting to page {} after '{}'", link,
>> exception.getMessage());
>> response.sendRedirect(link);
>> 
>> }
>> }
>> 
>> // add this method in your AppModule class
>> 
>> @Decorate(serviceInterface = RequestExceptionHandler.class)
>> public static RequestExceptionHandler installWorkaroundForFormPOSTProblem(
>>        @Nonnull final RequestExceptionHandler delegate,
>>        @Nonnull final RequestGlobals requestGlobals,
>>        @Nonnull final BaseURLSource baseURLSource,
>>        @Nonnull final PageRenderLinkSource pageRenderLinkSource
>> ) {
>>    return new FormPostProblemWorkaroundExceptionHandler(delegate,
>> requestGlobals, baseURLSource, pageRenderLinkSource);
>> }
> 
> 
> -- 
> Thiago H. de Paula Figueiredo
> Tapestry, Java and Hibernate consultant and developer
> http://machina.com.br
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

Reply via email to