What might be causing this IllegalStateException discrepancy in JSP/Spring? - spring

I had a JSP file with a c:redirect tag that would forward along a user to another page.
<!-- Yes, I know this loop is probably unnecessary, but I'm not fluent in jsp and have determined it is not the problem. :) -->
<c:if test="${cmd.numberOfResults == 1}">
<c:forEach items="${cmd.matches}" var="someVar">
<c:redirect url="/loadThatResultInfo.html"/>
</c:forEach>
</c:if>
The old implementation of the command object is needs updating (where I come in). The way I'm doing so is by creating a generic "search result" object which contains an instance of that old object (for now). I get that instance through a property in that generic class, so my code is now this:
<c:if test="${cmd.genericSearchObject.numberOfResults == 1}">
<c:forEach items="${cmd.genericSearchObject.matches}" var="acct">
<jsp:forward page="/loadThatResultInfo.html"/> <!-- new try! -->
<c:redirect url="/loadThatResultInfo.html"/> <!-- old try... -->
<% response.sendRedirect("/loadThatResultInfo.html"); %> <! new try! -->
</c:forEach>
</c:if>
Each of those three tries all result in IllegalStateExceptions of some sort. Why does this change cause the exception, especially considering that the lines involved -- the redirect, not the changed/bound class instances -- are causing the problem?
Back-end changes were made accordingly, referencing the property within my new encompassing "generic" class to satisfy the old functionality. I know this works because all related functionality, beside what I'm writing about, works.
Research online indicates:
- I can't redirect/forward after a submission has already been submitted. Then how was I able to do it before?
- Attempt to flush an already-cleared buffer causes this. What changed that makes it cleared now as opposed to the older (first) implementation?
- The size of the page's buffer needs to be bigger. THIS is one I don't understand and would really love for the stackoverflow community to address; I can see my new class causing size changes that would need changes to be dealt with.
------- ANOTHER ANSWER! -------
First and foremost, ALWAYS SET UP THE SITUATION IN THE CODE as described by the marked answer. However... if you're stuck and don't want to do that, here's a quick fix: javascript!
<script type="text/javascript">
location='./yourPageToGoTo.html'
</script>

JSP is part of the response. You're attempting to change the response destination in a JSP instead of in a controller. If you do this halfway in a JSP, then it's too late, because the HTTP response headers may already have been sent (the response is then in committed state). This is a point of no return and an illegal state for changing the response. It's too late then. Any attempt will result in the servletcontainer to throw IllegalStateException: response already committed.
To fix this, you need to put this piece code in the very top of JSP file and pray that the response hasn't already been committed at that point (which will usually happen after writing about 2KB of data to the response, depending on the servletcontainer config). However, JSP is still the wrong place for the job, you should rather do this in the controller, before forwarding the response to the JSP (or to instruct from within the model the controller somehow to do the job, when you're using a MVC framework).

Related

Use of spring security jstl tag <sec:authority access="hasPermission(#domain, 'permission')> inside a jstl core loop

I'm using facelets (JSF2.1) and I'm trying to do something like:
<c:forEach var="domainObject" items="#{MB.listOfDomainObjects}">
<sec:authorize access="hasPermission(#domainObject,'PERMISSION_X')">
hello world
</sec:authorize>
</c:forEach>
I've tried changing #domainObject by #domainObject, #{domainObject}, $domainObject and a lot of other combinations with the same result: domainObject is not processed correctly. Sometimes I get an error saying the page cannot be constructed, others domainObject is null.
It's like the scope where the tag c:forEach puts the variable domainObject is not scanned by sec:authorize to find it.
I've tried also to force the use of a scope using the tag <c:set ... scope="view"/>. I've also tried to use <ui:repeat> with the same results, but considering the tag sec:authorize is a jstl one, I suppose is executed in build time (like c:forEach) and not in render time (like ui:repeat), so I think I must use c:foreach and not ui:repeat.
Any chance to solve my problem?

Coldfusion 11 Ajax CFC binding impossible

I know a lot of people have had issues with Ajax and older versions of Coldfusion, but I'm using Coldfusion 11 Developer on my local machine and am finding it impossible to bind - under all circumstances - using Coldfusion functions, to a CFC, although it's not always the same error that gets returned.
I can't use autosuggest for a cfdiv when that binds to a CFC - but I can bind to autosuggest data on the same page, including from a database. When I bind to a CFC, invariably, the error message in CFDebug comes up as
"error:widget: Bind failed for autosuggest lastname, bind value is not a 1D array of strings.
info:http: CFC invocation response: ["Barken","Barnes"] ...
... by which you can see, that the bind IS a 1D array of strings and the CFC produced them, but wouldn't return them to the calling page!
I've also tried making the CFC much simpler, removing the database element and manually creating a straightforward 1D array of strings, but the same error comes up as when fed from my database.
So I made a test even simpler, avoiding databases and arrays to test ordinary, simple binding, not involving autosuggest - just an ordinary bind to a CFC (I always can successfully bind to data on the same page, or a URL.)
Here's the simplest test code, which still doesn't work:
<body>
<cfform id="myForm" name="myForm">
Enter your name into the box:<br />
<cfinput type="text" name="myText">
</cfform>
<hr />
Below is a cfdiv container, with a bind to a CFC:<br />
<cfdiv bind="cfc:bindsource.getDivContent({myText})"></cfdiv>
</body>
This is the CFC, named bindsource.cfc, in the same folder as the form page:
<cfcomponent output="false">
<cffunction name="getDivContent" returntype="string" access="remote" >
<cfargument name="edit">
<cfreturn "Your entered content was: #arguments.edit#">
</cffunction>
</cfcomponent>
In this case, the error I get is:
window:global: Uncaught exception: TypeError: Cannot convert '_289[i]' to object (http://localhost:8500/CFIDE/scripts/ajax/package/cfajax.js, line 872)
info:http: CFC invocation response: "Your entered content was: William"
(William is the text I entered into the box on the main page. line 872 in the cfajax.js is "872 throw new SyntaxError("parseJSON")"
In this simple test, on my main page, both before and after I enter something into the text input, in the area of what would be the cfdiv, the word "undefined" appears.
Sometimes, if I don't get the 1D array of strings error on some of the test pages, I get this can't convert to object error.
All the examples I've tried - not just my own stuff but all the samples I can find - run, up to the point where the Ajax error kicks in, so there are no other syntax errors. In all cases, the form page loads and runs, the CFC seems to get called, processes as appropriate - CFDebug shows me correct output of the CFC in the debug window - but then nothing ever comes back to the calling page. If I use a url bind, or a same page bind, it does - with a CFC, it doesn't. Ever.
When I test the CFC independently in a direct URL with method and argument passed, it works - I get the same result as the CFC invocation response.
Has anybody EVER got a CFC bind to work in Coldfusion? What am I missing or is CF11 just flawed? The whole things seems a bit unstable. I also get "cannot find CFC" errors, but if I do nothing, switch off, start up again - that particular error doesn't happen again for the same files until sometime later in the session, after repeated attempts to get one of the tests to work.
Wow - that was an obscure one, but I now know what's causing it.
Thanks for the suggestions, especially the one from #Dan Bracuk mentioning conflicts with javascript in the Application.cfc file, which led me to it, but it also helped to know the basic code should and did actually work, as others suggested, so the issue obviously had to do with something else.
Firstly, I removed my Application.cfc file completely - and for the first time, I could bind to a cfc. So then it was a question of finding what, in the Application.cfc, might be doing it.
Well, as it's my development set up, I'm dumping some variables to the page in the onRequestEnd function of Application.cfc. By removing them - it works. Put any of them back (dumps of server, cgi, session, application variables etc.) and again the cfc bind will not work.
I'm not using onRequestEnd for anything other than the variable dumps, but I thought to test what might happen if I were, still while removing the variable dumps. So I just added a simple cfinclude in the onRequestEnd function (the included cfm file does nothing at all - it's an empty cfm framework page with doctype and empty head/body tags that do or output nothing) and again, the cfc bind does not work.
It seems like it (onRequestEnd) will accept basic operations like cfset a=2+1 directly in onRequestEnd (but not in an included file) and the cfc will bind, but that's all (obviously not done exhaustive testing on what you can still do - basically, onRequestEnd is pretty unusable if you want to bind to your CFC.)
So that's it, the onRequestEnd function basically can't be relied upon if the bind to a CFC is to work. If you want it just to perform maths or maybe other things - perhaps you can get away with using it.
Hope this helps somebody else. It's been driving me nuts for weeks.
For what it's worth, so people can compare to their own setup and in case it doesn't apply in every development circumstance, I've been using the CF11 Developer Edition and I'm using the built-in Tomcat server on port 8500.
Thanks again everyone.

jsf execution order of f:events

What is the execution order of those?
Here is a question about possible f:event event names: List of JSF 2 events?
preRenderComponent
preRenderView
postAddToView
preValidate
postValidate
I want to check if a User is saved in a session bean is logged in and if not redirect to the login site, which needs to occur before view-param conversion phase since the used converter depends on the logged in User. 'preValidate' seems to take place after conversion and so I need an earlier event.
<f:event type="preRenderView" listener="#{beanA.checkLoggedIn()}"/>
<f:viewParam name="param" value="#{beanB.param}" converter="#{beanB.converter}" required="true"/>
I could have put 'checkLoggedIn()' in 'beanB' too, but tried to use a separate request scoped bean just for the check so that I could reuse it easily.
What is the execution order of those?
postAddToView runs right after the component is added to view during view build time (which is usually during restore view phase, but can also be during render response phase, e.g. navigation).
preValidate runs right before the component is to be validated (which is usually during validations phase, but can also be apply request values phase if immediate="true").
postValidate runs right after the component is been validated (which is usually during validations phase, but can also be apply request values phase if immediate="true").
preRenderView runs right before the view is rendered during render response phase.
preRenderComponent runs right before the component is rendered during render response phase.
Click the links to see detailed description in javadoc introduction.
I want to check if a User is saved in a session bean is logged in and if not redirect to the login site, which needs to occur before view-param conversion phase since the used converter depends on the logged in User. 'preValidate' seems to take place after conversion and so I need an earlier event.
You should use a simple servlet filter for this, not a JSF event. I've posted several examples before:
Is there any easy way to preprocess and redirect GET requests?
Are there some issue at inserting some check into template?

How to force Wicket "onchange" AJAX events to be triggered if fields fail validation conditions

The specific case I've got in mind is as follows: an AjaxFormComponentUpdatingBehavior("onchange") is added to a TextField in a form. The behavior verifies the text for certain conditions (either the model object or the form component model, doesn't matter), based on which it might display a message (or hide it, if it has already been shown).
The problem is, there are also validators added to the TextField. One of the possible (and likely) scenarios consists of the user typing in, first, a value that causes the message to be displayed by the AJAX request. If, then, he/she types in a value that doesn't pass validation, the message should disappear, but it does not.
Apparently, either the onUpdate() method for the AJAX behavior is not called at all, or I am failing in my attempts to insert a check for non-validated entries (I have tried to test for both null values and empty strings, to no avail; I have no idea what exactly Wicket's validators do to models when data is invalid).
I am wondering if someone who actually understands validators (or AJAX, actually) has any ideas on where the problem could be.
I can post edit and post code if someone tells me this is not a general issue tying validators and AJAX, but most likely a programming mistake. I still believe the former and thus I'll refrain from posting code sections, in order to keep the discussion on an API/theoretical frame.
Thanks.
When using an AjaxFormComponentUpdatingBehavior, if any of the IValidators fail their validation, onError() will be called instead of onUpdate(). Wicket will effectively prevent invalid user input from reaching the IModels in your components, so the component's ModelObject will not be changed at all. The invalid input will probably remain available by means of getInput()/getConvertedInput() (not sure if it will in an AJAX scenario, it sure is in a traditional form submission).
However, take into account that IFormValidators are not executed when using this mechanism. If you've got any, you might be interested in overriding getUpdateModel() so that AjaxFormComponentUpdatingBehavior will not bring maybe-invalid user input into your IModels, and set modelobjects manually when you're certain user input is valid.
Regarding your specific case, you could perform all the required logic in onError() (or rely on Models that will grab data from somewhere else), and just add the components that need refreshing to the AjaxRequestTarget. This is probably what's missing in your scenario.

how spring mvc tag works?

I am trying to write some kind of raw html to mimic what spring mvc tag produces after page rendering(and I do make them look exactly the same if you open them with a html element inspector). as I want to create dynamic input form using javascript. but it didn't work. it seems I had to use only what it offers: e.g. <form:input path="firstName" />.
to get the data binding working.
I thought the tag lib only help you to produce a html block that spring knows how to handle them in backend (action). from a web http perspective. what else it can send beyond a bunch of form data, and they should send the same thing. so I am really curious to learn what magic thing the tag lib dose beyond producing a html block.
the other thing I would like to know is where the model object is being hold when the form is being submit to a matched action. you know, you can get the model attribute by using #modelAttribute as the input parameter. is it in the original request object? or in the ActionRequest to which the dispatcherServlet build and put it. or even somewhere else?
thanks in advance.
I got it figured out. the raw html just works as spring tag does. as long as you are in the form tag block. you are okay to use raw html such as
<input type="text" id="abc" name="abc"/> just make sure name reflect your bean attribute path.
id is not mandatory and is just helping you to identify the very element. I guess I missed something when I work with the raw html by the time I ask the question. hope this helps for guys working with raw html approach, especially in case of dynamic input creation.

Resources