Issue 1:
Jon Harper opened SPR-6796 and commented

There needs to be a way to issue a redirect using the String type and to specify that there should be no exposing of the model to the view.

One use case:

HandlerInterceptors are commonly used to add data to the model. If the controller supports POST request and does a redirect (which is the most common case) then the data added by the handler interceptor gets appended to the redirect url. This is undesirable. See http://forum.springsource.org/showthread.php?t=84140.

Another use case:

The controller uses a session attribute. The GET inserts into the model (session). The POST accepts a SessionStatus and calls status.setComplete() and then does a redirect using "redirect:view". The model data is still appended to the end of the redirected URL. The programmer now has to accept the ModelMap and call clear() on it. This should really not be required. See http://forum.springsource.org/showthread.php?p=275392.

Therefore there needs to be a very simple way (i.e. view String prefix ) to do a redirect without exposing the model to the view. I see this as the default use case and the case of exposing the model as a less common use case.

Jon

Affects: 3.0 GA

Reference URL: http://forum.springsource.org/showthread.php?t=84140

Issue Links:

#5995 Allow specifying which request attributes are included in RedirectView ("duplicates")

#13278 When a controller method redirect to any url, the framework automatically appends all the model attributes in url query string even if those attributes are stored in session. ("is duplicated by")

#10625 When doing a redirect anything that is not org.springframework.beans.BeanUtils.isSimpleValueType silently gets left off of the redirect query string

3 votes, 4 watchers

Issue 2:
Mark Kettner opened SPR-2646 and commented

We have the following source:

<td style="width: 185px;" valign="top">

1: <spring:bind path="searchCriteria.fase">

<select name="<c:out value="${status.expression}"/>">
<option value="" /><c:forEach items="${fasen}"
var="fase" varStatus="loopStatus">

<c:if test="${searchCriteria.fase == fase}">
<c:set var="selected" value="true" />
</c:if>

2:	<spring:bind path="searchCriteria.fasen[${loopStatus.index}]">
<option value="<c:out value="${status.value}"/>"
<c:if test="${selected}">selected="selected"</c:if>><c:out
value="${status.value}" /></option>
</spring:bind>
<c:remove var="selected" />
</c:forEach>
</select>
</spring:bind></td>

When we deploy this in the tomcat apache-tomcat-5.5.17 the aplpication works, but when we deploy it on websphere 5.1.10 we getting the next error when the page opgavelist.jsp is being called:

Error 500: ServletException in '/pages/opgaveList.jsp': Unable to compile class for JSP An error occurred at line: 58 in the jsp file: /pages/opgaveList.jsp Generated servlet error: C:\java\ibm\WebSphere\AppServer\temp\PP94H199\server1\vvk-product-oo-ear-1.0.1.0\vvk-product-oo-web-1.0.1.0.war\pages_opgaveList.java:543: status is already defined in _jspService(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) org.springframework.web.servlet.support.BindStatus status = null; ^ 1 error

After an investigation we found that the websphere has a problem when we nest the tag : spring:bind. In the generated servlet we see that the variable status = null; has been declared twice.

Websphere 5.1.10 generated java:

{ // begin scope of tag variables

try {

int _jspx_eval_spring_bind_2 = _jspx_th_spring_bind_2

.doStartTag();

if (_jspx_eval_spring_bind_2 != javax.servlet.jsp.tagext.Tag.SKIP_BODY) {

do {

1.

org.springframework.web.servlet.support.BindStatus status = null;
status = (org.springframework.web.servlet.support.BindStatus) pageContext
.findAttribute("status");
// end
// HTML // begin
// [file="/pages/opgaveList.jsp";from=(50,42);to=(52,17)]
out.write("\r\n\r\n\t\t\t<select name=\"");
// end
// ##DEBUG## ##TAGLIB## "/pages/opgaveList.jsp"
// 53,17-"/pages/opgaveList.jsp" 53,54
// LineMapIndex:43
/* ------ c:out ------ */
org.apache.taglibs.standard.tag.el.core.OutTag _jspx_th_c_out_6 = new org.apache.taglibs.standard.tag.el.core.OutTag();
_jspx_th_c_out_6.setPageContext(pageContext);
_jspx_th_c_out_6.setParent(_jspx_th_spring_bind_2);
_jspx_th_c_out_6.setValue("${status.expression}");
_jspxTagObjects.push(_jspx_th_c_out_6);
int _jspx_eval_c_out_6 = _jspx_th_c_out_6
.doStartTag();
// end
// ##DEBUG## "/pages/opgaveList.jsp"
// 53,17-"/pages/opgaveList.jsp" 53,54
// LineMapIndex:44
if (_jspx_th_c_out_6.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE)
return;
((javax.servlet.jsp.tagext.Tag) _jspxTagObjects
.pop()).release();
// end
// HTML // begin
// [file="/pages/opgaveList.jsp";from=(52,54);to=(53,23)]
out.write("\">\r\n\t\t\t\t<option value=\"\" />");
// end
// ##DEBUG## ##TAGLIB## "/pages/opgaveList.jsp"
// 54,23-"/pages/opgaveList.jsp" 55,39
// LineMapIndex:45
/* ------ c:forEach ------ */
org.apache.taglibs.standard.tag.el.core.ForEachTag _jspx_th_c_forEach_2 = new org.apache.taglibs.standard.tag.el.core.ForEachTag();
_jspx_th_c_forEach_2.setPageContext(pageContext);
_jspx_th_c_forEach_2
.setParent(_jspx_th_spring_bind_2);
_jspx_th_c_forEach_2.setItems("${fasen}");
_jspx_th_c_forEach_2.setVar("fase");
_jspx_th_c_forEach_2.setVarStatus("loopStatus");
try {
int _jspx_eval_c_forEach_2 = _jspx_th_c_forEach_2
.doStartTag();
if (_jspx_eval_c_forEach_2 != javax.servlet.jsp.tagext.Tag.SKIP_BODY) {
do {
// end
// HTML // begin
// [file="/pages/opgaveList.jsp";from=(54,39);to=(57,5)]
out.write("\r\n\r\n\r\n\t\t\t\t\t");
// end
// ##DEBUG## ##TAGLIB##
// "/pages/opgaveList.jsp"
// 58,5-"/pages/opgaveList.jsp" 58,67
// LineMapIndex:47
/* ------ spring:bind ------ */
org.springframework.web.servlet.tags.BindTag _jspx_th_spring_bind_3 = new org.springframework.web.servlet.tags.BindTag();
_jspx_th_spring_bind_3
.setPageContext(pageContext);
_jspx_th_spring_bind_3
.setParent(_jspx_th_c_forEach_2);
_jspx_th_spring_bind_3
.setPath("searchCriteria.fasen[${loopStatus.index}]");
{ // begin scope of tag variables
try {
int _jspx_eval_spring_bind_3 = _jspx_th_spring_bind_3
.doStartTag();
if (_jspx_eval_spring_bind_3 != javax.servlet.jsp.tagext.Tag.SKIP_BODY) {
do {

org.springframework.web.servlet.support.BindStatus status = null;
status = (org.springframework.web.servlet.support.BindStatus) pageContext
.findAttribute("status");
// end
// HTML // begin
// [file="/pages/opgaveList.jsp";from=(57,67);to=(58,21)]
out
.write("\r\n\t\t\t\t\t\t<option value=\"");

// end
// ##DEBUG## ##TAGLIB##
// "/pages/opgaveList.jsp"
// 59,21-"/pages/opgaveList.jsp"
// 59,53 LineMapIndex:48
/* ------ c:out ------ */
org.apache.taglibs.standard.tag.el.core.OutTag _jspx_th_c_out_7 = new org.apache.taglibs.standard.tag.el.core.OutTag();
_jspx_th_c_out_7
.setPageContext(pageContext);
_jspx_th_c_out_7
.setParent(_jspx_th_spring_bind_3);
_jspx_th_c_out_7
.setValue("${status.value}");
_jspxTagObjects
.push(_jspx_th_c_out_7);
int _jspx_eval_c_out_7 = _jspx_th_c_out_7
.doStartTag();
// end
// ##DEBUG##
// "/pages/opgaveList.jsp"
// 59,21-"/pages/opgaveList.jsp"
// 59,53 LineMapIndex:49
if (_jspx_th_c_out_7
.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE)
return;
((javax.servlet.jsp.tagext.Tag) _jspxTagObjects
.pop())
.release();
// end
// HTML // begin
// [file="/pages/opgaveList.jsp";from=(58,53);to=(59,7)]
out
.write("\"\r\n\t\t\t\t\t\t\t");

// end
// ##DEBUG## ##TAGLIB##
// "/pages/opgaveList.jsp"
// 60,7-"/pages/opgaveList.jsp"
// 60,51 LineMapIndex:50
/* ------ c:if ------ */
org.apache.taglibs.standard.tag.el.core.IfTag _jspx_th_c_if_1 = new org.apache.taglibs.standard.tag.el.core.IfTag();
_jspx_th_c_if_1
.setPageContext(pageContext);
_jspx_th_c_if_1
.setParent(_jspx_th_spring_bind_3);
_jspx_th_c_if_1
.setTest("${searchCriteria.fase == fase}");
_jspxTagObjects
.push(_jspx_th_c_if_1);
int _jspx_eval_c_if_1 = _jspx_th_c_if_1
.doStartTag();
if (_jspx_eval_c_if_1 != javax.servlet.jsp.tagext.Tag.SKIP_BODY) {
do {
// end
// HTML // begin
// [file="/pages/opgaveList.jsp";from=(59,51);to=(59,70)]
out
.write("selected=\"selected\"");

// end
// ##DEBUG##
// "/pages/opgaveList.jsp"
// 60,70-"/pages/opgaveList.jsp"
// 60,77
// LineMapIndex:51
} while (_jspx_th_c_if_1
.doAfterBody() == javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_AGAIN);
}
-------
} while (_jspx_th_spring_bind_3
.doAfterBody() == javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_AGAIN);
}
if (_jspx_th_spring_bind_3
.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE)
return;
} catch (Throwable _jspx_exception) {
_jspx_th_spring_bind_3
.doCatch(_jspx_exception);
} finally {
_jspx_th_spring_bind_3
.doFinally();
_jspx_th_spring_bind_3
.release();
}
} // end scope of tag variables
// end
// HTML // begin
// [file="/pages/opgaveList.jsp";from=(61,19);to=(62,5)]
out.write("\r\n\t\t\t\t\t");

// end
// ##DEBUG## ##TAGLIB##
// "/pages/opgaveList.jsp"
// 63,5-"/pages/opgaveList.jsp" 63,32
// LineMapIndex:57
/* ------ c:remove ------ */
org.apache.taglibs.standard.tag.common.core.RemoveTag _jspx_th_c_remove_1 = new org.apache.taglibs.standard.tag.common.core.RemoveTag();
_jspx_th_c_remove_1
.setPageContext(pageContext);
_jspx_th_c_remove_1
.setParent(_jspx_th_c_forEach_2);
_jspx_th_c_remove_1.setVar("selected");
_jspxTagObjects
.push(_jspx_th_c_remove_1);
int _jspx_eval_c_remove_1 = _jspx_th_c_remove_1
.doStartTag();
// end
// ##DEBUG## "/pages/opgaveList.jsp"
// 63,5-"/pages/opgaveList.jsp" 63,32
// LineMapIndex:58
if (_jspx_th_c_remove_1.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE)
return;
((javax.servlet.jsp.tagext.Tag) _jspxTagObjects
.pop()).release();
// end
// HTML // begin
// [file="/pages/opgaveList.jsp";from=(62,32);to=(63,4)]
out.write("\r\n\t\t\t\t");

// end
// ##DEBUG## "/pages/opgaveList.jsp"
// 64,4-"/pages/opgaveList.jsp" 64,16
// LineMapIndex:59
} while (_jspx_th_c_forEach_2.doAfterBody() == javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_AGAIN);
}
if (_jspx_th_c_forEach_2.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE)
return;
} catch (Throwable _jspx_exception) {
_jspx_th_c_forEach_2.doCatch(_jspx_exception);
} finally {
_jspx_th_c_forEach_2.doFinally();
_jspx_th_c_forEach_2.release();
}
// end
// HTML // begin
// [file="/pages/opgaveList.jsp";from=(63,16);to=(65,2)]
out.write("\r\n\t\t\t</select>\r\n\t\t");

// end
// ##DEBUG## "/pages/opgaveList.jsp"
// 66,2-"/pages/opgaveList.jsp" 66,16
// LineMapIndex:60
} while (_jspx_th_spring_bind_2.doAfterBody() == javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_AGAIN);
}
if (_jspx_th_spring_bind_2.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE)
return;
} catch (Throwable _jspx_exception) {
_jspx_th_spring_bind_2.doCatch(_jspx_exception);
} finally {
_jspx_th_spring_bind_2.doFinally();
_jspx_th_spring_bind_2.release();
}
} /---

_jspx_th_spring_message_5.doFinally();
_jspx_th_spring_message_5.release();
}
// end
// HTML // begin

Tomcat generate .java:

try {

int _jspx_eval_spring_bind_1 = _jspx_th_spring_bind_1.doStartTag();

if (_jspx_eval_spring_bind_1 != javax.servlet.jsp.tagext.Tag.SKIP_BODY) {

1.

org.springframework.web.servlet.support.BindStatus status = null;
status = (org.springframework.web.servlet.support.BindStatus) _jspx_page_context.findAttribute("status");
do {
out.write("\r\n");
out.write("\t\t\t<select name=\"");
if (_jspx_meth_c_out_3(_jspx_th_spring_bind_1, _jspx_page_context, _jspx_push_body_count_spring_bind_1))
return;
out.write("\">\r\n");
out.write("\t\t\t\t<option value=\"\" />");
if (_jspx_meth_c_forEach_1(_jspx_th_spring_bind_1, _jspx_page_context, _jspx_push_body_count_spring_bind_1))
return;
out.write("\r\n");
out.write("\t\t\t</select>\r\n");
out.write("\t\t");
int evalDoAfterBody = _jspx_th_spring_bind_1.doAfterBody();
status = (org.springframework.web.servlet.support.BindStatus) _jspx_page_context.findAttribute("status");
if (evalDoAfterBody != javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_AGAIN)
break;
} while (true);
}
if (_jspx_th_spring_bind_1.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE) {
return;
}

} catch (Throwable _jspx_exception) {

while (_jspx_push_body_count_spring_bind_1[0] - > 0)

out = _jspx_page_context.popBody();

_jspx_th_spring_bind_1.doCatch(_jspx_exception);

} finally {

_jspx_th_spring_bind_1.doFinally();

_jspx_tagPool_spring_bind_path.reuse(_jspx_th_spring_bind_1);

}

out.write("</td>\r\n");

out.write("\r\n");

out.write("\t\t<td style="width: 185px;" valign="top">");

if (_jspx_meth_spring_message_4(_jspx_page_context))

return;

out.write("</td>\r\n");

out.write("\t\t<td style="width: 185px;" valign="top">\r\n");

out.write("\t\t\r\n");

out.write("\t\t");

// spring:bind

org.springframework.web.servlet.tags.BindTag _jspx_th_spring_bind_2 = (org.springframework.web.servlet.tags.BindTag) _jspx_tagPool_spring_bind_path.get(org.springframework.web.servlet.tags.BindTag.class);

_jspx_th_spring_bind_2.setPageContext(_jspx_page_context);

_jspx_th_spring_bind_2.setParent(null);

_jspx_th_spring_bind_2.setPath("searchCriteria.fase");

int[] _jspx_push_body_count_spring_bind_2 = new int[] { 0 };

try {

int _jspx_eval_spring_bind_2 = _jspx_th_spring_bind_2.doStartTag();

if (_jspx_eval_spring_bind_2 != javax.servlet.jsp.tagext.Tag.SKIP_BODY) {

org.springframework.web.servlet.support.BindStatus status = null;
status = (org.springframework.web.servlet.support.BindStatus) _jspx_page_context.findAttribute("status");

----------------

-------------

if (_jspx_th_spring_bind_2.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE) {
return;
}

} catch (Throwable _jspx_exception) {

while (_jspx_push_body_count_spring_bind_2[0] - > 0)

out = _jspx_page_context.popBody();

_jspx_th_spring_bind_2.doCatch(_jspx_exception);

} finally {

_jspx_th_spring_bind_2.doFinally();

_jspx_tagPool_spring_bind_path.reuse(_jspx_th_spring_bind_2);

}

Affects: 1.2.8, 2.0 RC4

Attachments:

_opgaveList.java (275.19 kB)

opgaveList_jsp.java (123.08 kB)

opgaveList.jsp (6.60 kB)