3

I'm making a project with the Spring Framework and I use the Spring MVC Framework for building my views.

Now everything works fine and runs smooth except for this simple GET page that takes 2 seconds and sometimes more to load on localhost.

As you can see in the logs (link) there is this very slow GenericConversionService trying to find converters to bind properties.

Help would really be appreciated!

Thanks in advance (appologies for my spelling errors) :)

UPDATE:

Apperantly the conversion service runs for every (binded with Path attribute) form tag in the "http://www.springframework.org/tags/form" namespace. The more form tags I Use the slower my page loads. Should I be using normal html form tags to increase performance or is there a way to stop it from looking for the "right" converter?

Additional information:

Logs: Link (Scroll about 1/3 there you will see a massive chunk of GenericConversionService logs

Spring insight profiling information: Profile information

Controller (Sloppy) Code:

@RequestMapping(value = "/route/create", method = RequestMethod.GET)
public ModelAndView getCreateRoute(){
    RouteCreateUpdateViewModel result = new RouteCreateUpdateViewModel();
    User u = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    u = us.get(u.getId());

    ModelAndView mav = new ModelAndView("route/create", "routeCreateUpdateModel", result);
    mav.addObject("favLocations", u.getLocations());
    mav.addObject("cars", u.getCars());

    result.setDateDay(Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + 1); // January = 0
    result.setDateMonth(Calendar.getInstance().get(Calendar.MONTH));
    result.setDateYear(Calendar.getInstance().get(Calendar.YEAR));

    mav.addObject("nextYear", result.getDateYear() + 1);

    return mav;
}

View Code:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>


<!-- //TODO I18N -->

<style type="text/css">
    li:focus {
        background-color:green;
    }
</style>

<script>
    var highlightedElement = null;
    $(document).ready(function(){
        $("input,select").click(function() {
            if(highlightedElement != null)
            {
                $(highlightedElement).removeClass("curFocus");
                if(highlightedElement.hasClass("location"))
                {
                    checkLocation(highlightedElement);
                }
            }
            var newHighlightedElement = $(this).parent().parent();
            $(newHighlightedElement).addClass("curFocus");
            highlightedElement = newHighlightedElement;
        });
    });

    function checkLocation(highlightedElement)
    {
        var parameters = {
        zipcode: $(highlightedElement).find(".zipcode").val(),
        street: $(highlightedElement).find(".street").val(),
        streetNr: $(highlightedElement).find(".streetNr").val()
        };

        $.getJSON('/location/validate.php', parameters, function(data) {
            if(data.result != null)
            {
                $(highlightedElement).removeClass("badData");
                $(highlightedElement).addClass("goodData");
            }
            else {
                $(highlightedElement).removeClass("goodData")
                $(highlightedElement).addClass("badData");
            }
        });
    }

</script>

<div>
    <h1><fmt:message key="route.create.header"/></h1>
    <div class="form-container">
        <c:url value="/route/create.php" var="actUrl"/>
        <form:form method="POST" action="${actUrl}" modelAttribute="routeCreateUpdateModel">
            <ul>
                <li class="location">
                    <form:label path="fromZipcode" cssClass="title">Van<span class="required">*</span></form:label>
                <span>
                    <form:input path="fromZipcode" cssClass="zipcode"/>
                    <form:label path="fromZipcode" cssClass="desc">Gemeente</form:label>
                </span>
                <span>
                    <form:input path="fromStreet" cssClass="street"/>
                    <form:label path="fromStreet" cssClass="desc">Straat</form:label>
                </span>
                <span>
                    <form:input path="fromStreetNr" cssClass="streetNr"/>
                    <form:label path="fromStreetNr" cssClass="desc">Nr</form:label>
                </span>
                </li>
                <li class="location">
                    <form:label path="toZipcode" cssClass="title">Naar<span class="required">*</span></form:label>
                <span>
                    <form:input path="toZipcode" cssClass="zipcode"/>
                    <form:label path="toZipcode" cssClass="desc">Gemeente</form:label>
                </span>
                <span>
                    <form:input path="toStreet" cssClass="street"/>
                    <form:label path="toStreet" cssClass="desc">Straat</form:label>
                </span>
                <span>
                    <form:input path="toStreetNr" cssClass="streetNr"/>
                    <form:label path="toStreetNr" cssClass="desc">Nr</form:label>
                </span>
                </li>
                <li>
                    <form:label path="dateDay" cssClass="title">Datum<span class="required">*</span></form:label>
                <span>
                   <tags:showDayPicker path="dateDay" currentDay="${routeCreateUpdateModel.dateDay}"/>
                    <form:label path="dateDay" cssClass="desc">dd</form:label>
                </span>
                <span>
                   <tags:showMonthPicker path="dateMonth" currentMonth="${routeCreateUpdateModel.dateMonth}"/>
                    <form:label path="dateMonth" cssClass="desc">mm</form:label>
                </span>
                <span>
                   <tags:showYearPicker path="dateYear" startYear="${routeCreateUpdateModel.dateYear}"
                                        stopYear="${nextYear}"/>
                    <form:label path="dateYear" cssClass="desc">yyyy</form:label>
                </span>
                </li>
                <li>
                     <form:label path="days" cssClass="title">Dagen<span class="required">*</span></form:label>
                    <span>
                        <form:checkbox path="days" value="1"/>
                        <form:label path="days" cssClass="desc">Ma</form:label>
                    </span>
                    <span>
                        <form:checkbox path="days" value="2"/>
                        <form:label path="days" cssClass="desc">Di</form:label>
                    </span>
                    <span>
                        <form:checkbox path="days" value="3"/>
                        <form:label path="days" cssClass="desc">Wo</form:label>
                    </span>
                    <span>
                        <form:checkbox path="days" value="4"/>
                        <form:label path="days" cssClass="desc">Do</form:label>
                    </span>
                    <span>
                        <form:checkbox path="days" value="5"/>
                        <form:label path="days" cssClass="desc">Vrij</form:label>
                    </span>
                    <span>
                        <form:checkbox path="days" value="6"/>
                        <form:label path="days" cssClass="desc">Za</form:label>
                    </span>
                    <span>
                        <form:checkbox path="days" value="7"/>
                        <form:label path="days" cssClass="desc">Zo</form:label>
                    </span>
                </li>
                <li>
                    <form:label path="stopDateDay" cssClass="title">Herhalen tot<span class="required">*</span></form:label>
                <span>
                   <tags:showDayPicker path="stopDateDay" currentDay="${routeCreateUpdateModel.dateDay}"/>
                    <form:label path="stopDateDay" cssClass="desc">dd</form:label>
                </span>
                <span>
                   <tags:showMonthPicker path="stopDateMonth" currentMonth="${routeCreateUpdateModel.dateMonth}"/>
                    <form:label path="stopDateMonth" cssClass="desc">mm</form:label>
                </span>
                <span>
                   <tags:showYearPicker path="stopDateYear" startYear="${routeCreateUpdateModel.dateYear}"
                                        stopYear="${nextYear}"/>
                    <form:label path="stopDateYear" cssClass="desc">yyyy</form:label>
                </span>
                </li>
                <li>
                    <form:label path="departureTime" cssClass="title">Vertrek uur<span class="required">*</span></form:label>
                    <span>
                        <tags:showHourPicker path="departureTime"/>
                        <form:label path="departureTime" cssClass="desc">uu</form:label>
                    </span>
                    <span>
                        <tags:showMinutePicker path="departureTime"/>
                        <form:label path="departureTime" cssClass="desc">mm</form:label>
                    </span>
                </li>
                <li>
                    <form:label path="arrivalTime" cssClass="title">Aankomst uur<span class="required">*</span></form:label>
                    <span>
                        <tags:showHourPicker path="arrivalTime"/>
                        <form:label path="arrivalTime" cssClass="desc">uu</form:label>
                    </span>
                    <span>
                        <tags:showMinutePicker path="arrivalTime"/>
                        <form:label path="arrivalTime" cssClass="desc">mm</form:label>
                    </span>
                </li>
                <li>
                    <form:label path="car" cssClass="title">Auto</form:label>
                    <span>
                        <form:select path="car">
                            <form:options items="${cars}" itemLabel="carName" itemValue="Id" />
                        </form:select>
                    </span>
                </li>
            </ul>
            <input type="submit" value="Route toevoegen"/>
        </form:form>
    </div>
</div>

If you need any more information just ask and I will provide it right away.

Thanks again :)

3
  • Updated thanks for quick response! :) Commented Mar 9, 2011 at 13:57
  • How do you custom tags (tags:showMinutePicker, etc) look like? Commented Mar 9, 2011 at 14:24
  • Like this: paste2.org/p/1292448 Commented Mar 9, 2011 at 14:27

2 Answers 2

1

Perhaps problem is caused by excessive number of type conversions in <form:option> tags.

For simple values that don't require type conversion you can use HTML <option> tag as is:

<form:select path="${path}">
    <c:forEach var="i" begin="0" end="59" step="${interval}">
      <option value="${i}"><fmt:formatNumber value="${i}" minIntegerDigits="2" /></option>
    </c:forEach>
</form:select>

As a more aggressive optimization you can get rid of <c:forEach> and <fmt:formatNumber> and fill the body of <form:select> with pregenerated HTML.

Sign up to request clarification or add additional context in comments.

2 Comments

Removing all the form:option tags and replacing all form:label tags with normal label tags indeed Improved performance. I wonder why the form tags are so Ridiculously slow and why it tries to convert String to Strings lol "Looking for Converter to convert from TypeDescriptor java.lang.String to TypeDescriptor java.lang.String" Hmm? Maybe the Spring MVC Framework was a bad choice. Thanks alot for your help :)
String->String conversions could still result in post-processing such as trimming and string-based formatting (e.g. applying a mask, for example). In the event no such string processing is needed, the conversion service should execute a quick no-op operation.
1

I'm on of the Spring MVC developers... would you mind sharing what version of Spring Framework you are using? A number of conversion service optimizations have been introduced in the recent maintenance revisions.

Also, have you tried disabling DEBUG logging for org.springframework.core.convert and see if that improves things?

Thanks, Keith

2 Comments

Sorry for the late response Keith, I'm running on 3.0.0.RELEASE
Yes would recommend at least upgrading to the latest 3.0.x revision to get the performance improvements.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.