Problem with POST requests

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Problem with POST requests

rapidtransit440
I'm using Elasticsearch, my first implementation involved processing a user request (verifying that there facet filters are valid) in the request chain and then sending a redirect short circuiting the request pipeline. Now here's the problem. I moved the processing into a component to make it more modular and way less fragile. The problem is the actual search/facet filter happens during the GET request and it is injected into the EventContext and when they hit the page the request result is assigned in the onActivate event. The problem is on the POST request the page components are still looking for those values  as if it was trying to render the template. I just did a workaround and made a NullSearchRequest value but it just seems like a hacky workaround and I keep having to check if a value is null for properties that are never called on  that are never used in a POST request. Anyone know a good work around?

Sent from AOL Mobile Mail
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Problem with POST requests

Thiago H. de Paula Figueiredo
Hi!

Could you please post the code of your component and the page? I'm having a
hard time understanding your scenario from your description.
Are you using a component or page as code that will upload something
to ElasticSearch when it is requested but not sending any response
back to the browser?

On Sun, 25 Sep 2016 09:56:24 -0300, <[hidden email]> wrote:

> I'm using Elasticsearch, my first implementation involved processing a  
> user request (verifying that there facet filters are valid) in the  
> request chain and then sending a redirect short circuiting the request  
> pipeline. Now here's the problem. I moved the processing into a  
> component to make it more modular and way less fragile. The problem is  
> the actual search/facet filter happens during the GET request and it is  
> injected into the EventContext and when they hit the page the request  
> result is assigned in the onActivate event. The problem is on the POST  
> request the page components are still looking for those values  as if it  
> was trying to render the template. I just did a workaround and made a  
> NullSearchRequest value but it just seems like a hacky workaround and I  
> keep having to check if a value is null for properties that are never  
> called on  that are never used in a POST request. Anyone know a good  
> work around?
>
> Sent from AOL Mobile Mail


--
Thiago H. de Paula Figueiredo
Tapestry, Java and Hibernate consultant and developer
http://machina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Problem with POST requests

Lance Java
onActivate() will be invoked for GET and POST and even during link
generation (I think). You shouldn't do any "work" in this method. Better
yet, remove the method all together and use @PageActivationContext.

If you have "work" needed for render only you should use @SetupRender

On 27 Sep 2016 2:12 p.m., "Thiago H de Paula Figueiredo" <[hidden email]>
wrote:

> Hi!
>
> Could you please post the code of your component and the page? I'm having a
> hard time understanding your scenario from your description.
> Are you using a component or page as code that will upload something
> to ElasticSearch when it is requested but not sending any response
> back to the browser?
>
> On Sun, 25 Sep 2016 09:56:24 -0300, <[hidden email]> wrote:
>
> I'm using Elasticsearch, my first implementation involved processing a
>> user request (verifying that there facet filters are valid) in the request
>> chain and then sending a redirect short circuiting the request pipeline.
>> Now here's the problem. I moved the processing into a component to make it
>> more modular and way less fragile. The problem is the actual search/facet
>> filter happens during the GET request and it is injected into the
>> EventContext and when they hit the page the request result is assigned in
>> the onActivate event. The problem is on the POST request the page
>> components are still looking for those values  as if it was trying to
>> render the template. I just did a workaround and made a NullSearchRequest
>> value but it just seems like a hacky workaround and I keep having to check
>> if a value is null for properties that are never called on  that are never
>> used in a POST request. Anyone know a good work around?
>>
>> Sent from AOL Mobile Mail
>>
>
>
> --
> Thiago H. de Paula Figueiredo
> Tapestry, Java and Hibernate consultant and developer
> http://machina.com.br
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Problem with POST requests

rapidtransit440
In reply to this post by Thiago H. de Paula Figueiredo

public class EntityLinkTransformer implements PageRenderLinkTransformer{
 @Override
    public PageRenderRequestParameters decodePageRenderRequest(Request request) {
       
        if(StringUtils.isNotEmpty(request.getPath())) {
            CachedCategory category;
            Product product;
            if ((category = cache.getCategory(request.getPath())) != null) {
                if(StringUtil.isNotEmpty(category.getTemplate())){
                    return new PageRenderRequestParameters(category.getTemplate(), new EmptyEventContext(), false);
                }
                return new PageRenderRequestParameters("CategoryPage", new CategoryEvent(category, elasticSearchService.search(category, request)), false);
            } else if ((product = catalogService.findProductByURI(request.getPath())) != null) {
                return new PageRenderRequestParameters("ProductPage", new ProductEvent(product), false);
            } else if("/search".equals(request.getPath())){
                String q = request.getParameter("q");
                return new PageRenderRequestParameters("SearchPage", new SearchEvent(q, elasticSearchService.search(q, request)), false);
            }
        }
        return null;
    }






public class CategoryPage extends BaseCatalogPage {
   
    private CachedCategory category;
   
    @Inject
    private Request request;
   


    Object onActivate(EventContext eventContext) {
        if(eventContext instanceof CategoryEvent) {
            CategoryEvent event = (CategoryEvent) eventContext;
            category = event.getCachedCategory();
            setSearchRequestFuture(event.getSearchRequest());
        }
        return null;
    }



public abstract class BaseCatalogPage {
    private static final SearchRequest NULL_REQUEST = new SearchRequest(){
        @Override
        public Map<String, String> getSortModel() {
            return Collections.emptyMap();
        }
    };
    protected static final Future<SearchRequest> NULL_FUTURE_REQUEST = new Future<SearchRequest>() {


        @Override
        public boolean cancel(boolean mayInterruptIfRunning) {
            return false;
        }


        @Override
        public boolean isCancelled() {
            return false;
        }


        @Override
        public boolean isDone() {
            return true;
        }


        @Override
        public SearchRequest get() throws InterruptedException, ExecutionException {
            return NULL_REQUEST;
        }


        @Override
        public SearchRequest get(long timeout, @NotNull TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
            return NULL_REQUEST;
        }
    };
    @ActivationRequestParameter
    private int page;
   
    @ActivationRequestParameter
    private String direction;


    @ActivationRequestParameter
    private String sort;
   
    private CachedProduct[] products;
   
    private Future<SearchRequest> searchRequestFuture = NULL_FUTURE_REQUEST;





public class FacetFilter {


public void onFilter(@RequestParameter(value = "direction", allowBlank = true) String direction,
                         @RequestParameter(value = "sort", allowBlank = true) String sort,
                         @RequestParameter(value = "q", allowBlank = true) String q,
                         @RequestParameter("uri") String uri) throws IOException {
        Request request = this.request;
        if (StringUtils.isNotEmpty(uri)) {
            StringBuilder sb = new StringBuilder(uri).append('?');
            SortOrder order = SortOrder.ASC.name().equals(direction) ? SortOrder.ASC : SortOrder.DESC;
            MutableBoolean addSort = new MutableBoolean(false);
            Category category;
            if("/search".equals(uri)) {
                sb.append("q").append('=').append(q).append('&');
                for(SearchFacet searchFacet : searchFacetDao.readAllSearchFacets()){
                    build(request, sb, sort, addSort, searchFacet);
                }
                redirect(request, response, sb, sort, order, addSort);
               
            } else if ((category = catalogService.findCategoryByURI(uri)) != null) {
                for(CategorySearchFacet categorySearchFacet : category.getSearchFacets()){
                    build(request, sb, sort, addSort, categorySearchFacet.getSearchFacet());
                }
                redirect(request, response, sb, sort, order, addSort);
            }
        }
    }



private void redirect(Request request, Response response, StringBuilder sb, String sort, SortOrder order, MutableBoolean addSort) throws IOException {
        String page;
        if((page = request.getParameter("page")) != null){
            sb.append("page").append('=').append(page).append('&');
        }
        if(addSort.getValue() || "fullName".equals(sort)){
            sb.append("sort").append('=').append(sort).append('&').append("direction").append('=').append(order.name());
        } else {
            sb.deleteCharAt(sb.length() - 1);
        }


        response.sendRedirect(sb.toString());
    }



When the the Request is Posted it is looking for properties on the FacetFilter that are only relevant if it were to render an html result
-----Original Message-----
From: Thiago H de Paula Figueiredo <[hidden email]>
To: Tapestry users <[hidden email]>
Sent: Tue, Sep 27, 2016 9:12 am
Subject: Re: Problem with POST requests

Hi!

Could you please post the code of your component and the page? I'm having a
hard time understanding your scenario from your description.
Are you using a component or page as code that will upload something
to ElasticSearch when it is requested but not sending any response
back to the browser?

On Sun, 25 Sep 2016 09:56:24 -0300, <[hidden email]> wrote:

> I'm using Elasticsearch, my first implementation involved processing a  
> user request (verifying that there facet filters are valid) in the  
> request chain and then sending a redirect short circuiting the request  
> pipeline. Now here's the problem. I moved the processing into a  
> component to make it more modular and way less fragile. The problem is  
> the actual search/facet filter happens during the GET request and it is  
> injected into the EventContext and when they hit the page the request  
> result is assigned in the onActivate event. The problem is on the POST  
> request the page components are still looking for those values  as if it  
> was trying to render the template. I just did a workaround and made a  
> NullSearchRequest value but it just seems like a hacky workaround and I  
> keep having to check if a value is null for properties that are never  
> called on  that are never used in a POST request. Anyone know a good  
> work around?
>
> Sent from AOL Mobile Mail


--
Thiago H. de Paula Figueiredo
Tapestry, Java and Hibernate consultant and developer
http://machina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Problem with POST requests

Thiago H. de Paula Figueiredo
On Tue, 27 Sep 2016 10:50:29 -0300, <[hidden email]> wrote:

>     Object onActivate(EventContext eventContext) {
>         if(eventContext instanceof CategoryEvent) {
>             CategoryEvent event = (CategoryEvent) eventContext;
>             category = event.getCachedCategory();
>             setSearchRequestFuture(event.getSearchRequest());
>         }
>         return null;
>     }

I believe that's the issue: if you return null in onActivate(), you're  
telling Tapestry to render the template, as you didn't provide any other  
answer to the request by returning an object. If you really don't need to  
provide any answer to the request, just return new  
TextStreamResponse("text/plain, "") instead.

Also, calling Response.sendRedirect() in an event handler method, like you  
did in onFilter(), is asking for trouble. You should return some object  
(java.net.URL, page instance, page class, etc) telling Tapestry where to  
redirect instead.

>
>
>
> public abstract class BaseCatalogPage {
>     private static final SearchRequest NULL_REQUEST = new  
> SearchRequest(){
>         @Override
>         public Map<String, String> getSortModel() {
>             return Collections.emptyMap();
>         }
>     };
>     protected static final Future<SearchRequest> NULL_FUTURE_REQUEST =  
> new Future<SearchRequest>() {
>
>
>         @Override
>         public boolean cancel(boolean mayInterruptIfRunning) {
>             return false;
>         }
>
>
>         @Override
>         public boolean isCancelled() {
>             return false;
>         }
>
>
>         @Override
>         public boolean isDone() {
>             return true;
>         }
>
>
>         @Override
>         public SearchRequest get() throws InterruptedException,  
> ExecutionException {
>             return NULL_REQUEST;
>         }
>
>
>         @Override
>         public SearchRequest get(long timeout, @NotNull TimeUnit unit)  
> throws InterruptedException, ExecutionException, TimeoutException {
>             return NULL_REQUEST;
>         }
>     };
>     @ActivationRequestParameter
>     private int page;
>    @ActivationRequestParameter
>     private String direction;
>
>
>     @ActivationRequestParameter
>     private String sort;
>    private CachedProduct[] products;
>    private Future<SearchRequest> searchRequestFuture =  
> NULL_FUTURE_REQUEST;
>
>
>
>
>
> public class FacetFilter {
>
>
> public void onFilter(@RequestParameter(value = "direction", allowBlank =  
> true) String direction,
>                          @RequestParameter(value = "sort", allowBlank =  
> true) String sort,
>                          @RequestParameter(value = "q", allowBlank =  
> true) String q,
>                          @RequestParameter("uri") String uri) throws  
> IOException {
>         Request request = this.request;
>         if (StringUtils.isNotEmpty(uri)) {
>             StringBuilder sb = new StringBuilder(uri).append('?');
>             SortOrder order = SortOrder.ASC.name().equals(direction) ?  
> SortOrder.ASC : SortOrder.DESC;
>             MutableBoolean addSort = new MutableBoolean(false);
>             Category category;
>             if("/search".equals(uri)) {
>                 sb.append("q").append('=').append(q).append('&');
>                 for(SearchFacet searchFacet :  
> searchFacetDao.readAllSearchFacets()){
>                     build(request, sb, sort, addSort, searchFacet);
>                 }
>                 redirect(request, response, sb, sort, order, addSort);
>            } else if ((category = catalogService.findCategoryByURI(uri))  
> != null) {
>                 for(CategorySearchFacet categorySearchFacet :  
> category.getSearchFacets()){
>                     build(request, sb, sort, addSort,  
> categorySearchFacet.getSearchFacet());
>                 }
>                 redirect(request, response, sb, sort, order, addSort);
>             }
>         }
>     }
>
>
>
> private void redirect(Request request, Response response, StringBuilder  
> sb, String sort, SortOrder order, MutableBoolean addSort) throws  
> IOException {
>         String page;
>         if((page = request.getParameter("page")) != null){
>             sb.append("page").append('=').append(page).append('&');
>         }
>         if(addSort.getValue() || "fullName".equals(sort)){
>             sb.append("sort").append('=').append(sort).append('&').append("direction").append('=').append(order.name());
>         } else {
>             sb.deleteCharAt(sb.length() - 1);
>         }
>
>
>         response.sendRedirect(sb.toString());
>     }
>
>
>
> When the the Request is Posted it is looking for properties on the  
> FacetFilter that are only relevant if it were to render an html result
> -----Original Message-----
> From: Thiago H de Paula Figueiredo <[hidden email]>
> To: Tapestry users <[hidden email]>
> Sent: Tue, Sep 27, 2016 9:12 am
> Subject: Re: Problem with POST requests
>
> Hi!
>
> Could you please post the code of your component and the page? I'm  
> having a
> hard time understanding your scenario from your description.
> Are you using a component or page as code that will upload something
> to ElasticSearch when it is requested but not sending any response
> back to the browser?
>
> On Sun, 25 Sep 2016 09:56:24 -0300, <[hidden email]> wrote:
>
>> I'm using Elasticsearch, my first implementation involved processing a
>> user request (verifying that there facet filters are valid) in the
>> request chain and then sending a redirect short circuiting the request
>> pipeline. Now here's the problem. I moved the processing into a
>> component to make it more modular and way less fragile. The problem is
>> the actual search/facet filter happens during the GET request and it is
>> injected into the EventContext and when they hit the page the request
>> result is assigned in the onActivate event. The problem is on the POST
>> request the page components are still looking for those values  as if it
>> was trying to render the template. I just did a workaround and made a
>> NullSearchRequest value but it just seems like a hacky workaround and I
>> keep having to check if a value is null for properties that are never
>> called on  that are never used in a POST request. Anyone know a good
>> work around?
>>
>> Sent from AOL Mobile Mail
>
>


--
Thiago H. de Paula Figueiredo
Tapestry, Java and Hibernate consultant and developer
http://machina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Problem with POST requests

rapidtransit440
I will try that, thanks. I'll look into the redirect more, I can see why it is a bad idea.



-----Original Message-----
From: Thiago H de Paula Figueiredo <[hidden email]>
To: Tapestry users <[hidden email]>
Sent: Tue, Sep 27, 2016 10:12 am
Subject: Re: Problem with POST requests

On Tue, 27 Sep 2016 10:50:29 -0300, <[hidden email]> wrote:

>     Object onActivate(EventContext eventContext) {
>         if(eventContext instanceof CategoryEvent) {
>             CategoryEvent event = (CategoryEvent) eventContext;
>             category = event.getCachedCategory();
>            setSearchRequestFuture(event.getSearchRequest());
>         }
>         return null;
>     }

I believe that's the issue: if you return null in onActivate(), you're  
telling Tapestry to render the template, as you didn't provide any other  
answer to the request by returning an object. If you really don't need to  
provide any answer to the request, just return new  
TextStreamResponse("text/plain, "") instead.

Also, calling Response.sendRedirect() in an event handler method, like you  
did in onFilter(), is asking for trouble. You should return some object  
(java.net.URL, page instance, page class, etc) telling Tapestry where to  
redirect instead.

>
>
>
> public abstract class BaseCatalogPage {
>     private static final SearchRequest NULL_REQUEST = new  
> SearchRequest(){
>   @Override
>         public Map<String, String> getSortModel() {
>             return Collections.emptyMap();
>         }
>     };
>     protected static final Future<SearchRequest> NULL_FUTURE_REQUEST =  
> new Future<SearchRequest>() {
>
>
>         @Override
>         public boolean cancel(boolean mayInterruptIfRunning) {
>             return false;
>         }
>
>
>         @Override
>         public boolean isCancelled() {
>        return false;
>         }
>
>
>         @Override
>         public boolean isDone() {
>             return true;
>         }
>
>
>         @Override
>         public SearchRequest get() throws InterruptedException,  
> ExecutionException {
>             return NULL_REQUEST;
>         }
>
>
>         @Override
>         public SearchRequest get(long timeout, @NotNull TimeUnit unit)  
> throws InterruptedException, ExecutionException, TimeoutException {
>             return NULL_REQUEST;
>         }
>     };
> @ActivationRequestParameter
>     private int page;
>    @ActivationRequestParameter
>     private String direction;
>
>
>     @ActivationRequestParameter
>     private String sort;
>    private CachedProduct[] products;
>    private Future<SearchRequest> searchRequestFuture =  
> NULL_FUTURE_REQUEST;
>
>
>
>
>
> public class FacetFilter {
>
>
> public void onFilter(@RequestParameter(value = "direction", allowBlank =  
> true) String direction,
>                        @RequestParameter(value = "sort", allowBlank =  
> true) String sort,
>        @RequestParameter(value = "q", allowBlank =  
> true) String q,
>              @RequestParameter("uri") String uri) throws  
> IOException {
>         Request request = this.request;
>         if (StringUtils.isNotEmpty(uri)) {
> StringBuilder sb = new StringBuilder(uri).append('?');
>             SortOrder order = SortOrder.ASC.name().equals(direction) ?  
> SortOrder.ASC : SortOrder.DESC;
>             MutableBoolean addSort = new MutableBoolean(false);
>             Category category;
>             if("/search".equals(uri)) {
>                 sb.append("q").append('=').append(q).append('&');
>                 for(SearchFacet searchFacet :  
> searchFacetDao.readAllSearchFacets()){
>     build(request, sb, sort, addSort, searchFacet);
>                 }
>          redirect(request, response, sb, sort, order, addSort);
>            } else if ((category = catalogService.findCategoryByURI(uri))  
> != null) {
>           for(CategorySearchFacet categorySearchFacet :  
> category.getSearchFacets()){
>                     build(request, sb, sort, addSort,  
> categorySearchFacet.getSearchFacet());
>                 }
>     redirect(request, response, sb, sort, order, addSort);
>             }
>       }
>     }
>
>
>
> private void redirect(Request request, Response response, StringBuilder  
> sb, String sort, SortOrder order, MutableBoolean addSort) throws  
> IOException {
>         String page;
>         if((page = request.getParameter("page")) != null){
>             sb.append("page").append('=').append(page).append('&');
>         }
>         if(addSort.getValue() || "fullName".equals(sort)){
>             sb.append("sort").append('=').append(sort).append('&').append("direction").append('=').append(order.name());
> } else {
>             sb.deleteCharAt(sb.length() - 1);
>         }
>
>
>  response.sendRedirect(sb.toString());
>     }
>
>
>
> When the the Request is Posted it is looking for properties on the  
> FacetFilter that are only relevant if it were to render an html result
> -----Original Message-----
> From: Thiago H de Paula Figueiredo <[hidden email]>
> To: Tapestry users <[hidden email]>
> Sent: Tue, Sep 27, 2016 9:12 am
> Subject: Re: Problem with POST requests
>
> Hi!
>
> Could you please post the code of your component and the page? I'm  
> having a
> hard time understanding your scenario from your description.
> Are you using a component or page as code that will upload something
> to ElasticSearch when it is requested but not sending any response
> back to the browser?
>
> On Sun, 25 Sep 2016 09:56:24 -0300, <[hidden email]> wrote:
>
>> I'm using Elasticsearch, my first implementation involved processing a
>> user request (verifying that there facet filters are valid) in the
>> request chain and then sending a redirect short circuiting the request
>> pipeline. Now here's the problem. I moved the processing into a
>> component to make it more modular and way less fragile. The problem is
>> the actual search/facet filter happens during the GET request and it is
>> injected into the EventContext and when they hit the page the request
>> result is assigned in the onActivate event. The problem is on the POST
>> request the page components are still looking for those values  as if it
>> was trying to render the template. I just did a workaround and made a
>> NullSearchRequest value but it just seems like a hacky workaround and I
>> keep having to check if a value is null for properties that are never
>> called on  that are never used in a POST request. Anyone know a good
>> work around?
>>
>> Sent from AOL Mobile Mail
>
>


--
Thiago H. de Paula Figueiredo
Tapestry, Java and Hibernate consultant and developer
http://machina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]


Loading...