I'm trying to approach spring. There are other questions and answers about getting-started with spring. I don't want "something" to start, but the things that i must have.
The goal is very similar to a CRUD application.Here's the list of my needs:
1) some "html" widget to manage tabular data and forms the seamless integrated in spring as possible, yet capable of doing table pagination 2) the session management is not a concern since is covered in the spring reference 3) a basic authorization system. I find the container-managed security poorly integrated with form-based authentication. Spring states to have a simplified yet powerful security, and I just need to manage users and "power users" accounts. May I go the spring way? 4) i learned JPA2. I have very basic database access needs. Should I stay with JPA or hibernate is preferable? 5) what I don't need to start. web flow is quite a big item to learn. do I need it? AOP the same. do I need it?however, to put something on th开发者_C百科e screen, my major concern is point 1.
A small-to-medium application, for example a little "address book application" yet will have a paginator. I need to know that I will be able to do that and that I won't need another switch in architecture.*
thanks in advance* architecture switch example "well for that you'll need JSF that is better integrated with seam, and jsf does not handle file uploads that actually everyone use, so you have to put also ICEFaces that actually are better managed by maven that you currenty are not using..." neverending story
Take a look at Spring Roo. Issuing a command and seeing what it did is a great way to explore what a typical java-stack application does. For instance, tell it to set up persistence with hibernate, and take a look at the config files that are created. Tell it to create an MVC controller and take a look at the files created. It's really handy to at least give you some pointers as to what are the big building blocks. Also, if you learn Roo, it'll write 80% of your code for you!
There are two different ways to have pageination with spring:
- use additional JSP components like Display Tag libary - This can be very easy, because in the the JSP library can (but not must) handle the pagination completely by itself (drawback: you need to load all items for each request or need to store the items somewhere (for example in the session))
- Implement it by your own in the controller: this for example how I did it in one of my applications, it is based on the Roo structure (see joeslice's answer). The DAO layer is realized with Hades, but you can do it without. At least it is only to illustrate how the controller works (I guess that is what you asked for).
Controller:
@RequestMapping("/users")
@Controller
public class UserController {
@RequestMapping(method = RequestMethod.GET)
public ModelAndView list(
@RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "size", required = false) Integer size) {
if (page != null || size != null) {
Page<User> userPage = this.userDao.readAll(buildPageAble(page, size));
ModelMap uiModel = pagingProperties(userPage);
uiModel.addAttribute("users", userPage.asList());
return new ModelAndView("users/list", uiModel);
} else {
return new ModelAndView("users/list", "users", this.userDao.readAll());
}
}
private PageRequest buildPageAble(Integer pageOrNull, Integer sizeOrNull) {
int page = (pageOrNull != null) ? pageOrNull : 1;
int size = (sizeOrNull != null) ? sizeOrNull : DEFAULT_PAGE_SIZE;
return new PageRequest(page - 1, size);
}
private ModelMap pagingProperties(Page<?> pagedResult) {
ModelMap uiModel = new ModelMap();
uiModel.addAttribute("page", pagedResult.getNumber());
uiModel.addAttribute("size",pagedResult.getSize());
uiModel.addAttribute("maxPages", pagedResult.getTotalPages());
return uiModel;
}
}
A Page
and PageRequest
are objects provides by Hades. If you do not use Hades, you can easily replace it by your own stuff. The page-1
in buildPageAble
is because the frontend bases on Roo uses 1 for the first Page, but Hades uses 0 for the first one.
The JSP is bases on Spring Roo, but you can copy it and use it without Roo.
user list jspx:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:page="urn:jsptagdir:/WEB-INF/tags/form" xmlns:table="urn:jsptagdir:/WEB-INF/tags/form/fields" version="2.0">
<jsp:directive.page contentType="text/html;charset=UTF-8"/>
<jsp:output omit-xml-declaration="yes"/>
<page:list id="pl_com_queomedia_cfmt_core_domain_User" items="${users}">
<table:table data="${users}" id="l_com_queomedia_cfmt_core_domain_User" path="/users" typeIdFieldName="businessId">
<table:column id="c_com_queomedia_cfmt_core_domain_User_firstName" property="firstName"/>
<table:column id="c_com_queomedia_cfmt_core_domain_User_lastName" property="lastName"/>
<table:column id="c_com_queomedia_cfmt_core_domain_User_login" property="login"/>
<table:column id="c_com_queomedia_cfmt_core_domain_User_emailAddress" property="emailAddress" maxLength="25"/>
</table:table>
</page:list>
</div>
This uses the Roo Tags, the important is util:pagination used by fields:table, because it add the paging stuff to the output:
fields:table.tagx
...
<c:if test="${not empty param.page}">
<input name="page" type="hidden" value="1" />
</c:if>
<c:if test="${not empty param.size}">
<input name="size" type="hidden" value="${fn:escapeXml(param.size)}" />
</c:if>
...
<c:if test="${not empty maxPages}">
<util:pagination maxPages="${maxPages}" page="${param.page}" size="${param.size}" />
</c:if>
...
util:pagination.tagx
<jsp:root xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:fn="http://java.sun.com/jsp/jstl/functions" xmlns:spring="http://www.springframework.org/tags" xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
<jsp:output omit-xml-declaration="yes" />
<jsp:directive.attribute name="maxPages" type="java.lang.Integer" required="true" rtexprvalue="true" description="The maximum number of pages available (ie tableRecordCount / size)" />
<jsp:directive.attribute name="page" type="java.lang.Integer" required="false" rtexprvalue="true" description="The current page (not required, defaults to 1)" />
<jsp:directive.attribute name="size" type="java.lang.Integer" required="false" rtexprvalue="true" description="The number of records per page (not required, defaults to 10)" />
<jsp:directive.attribute name="render" type="java.lang.Boolean" required="false" rtexprvalue="true" description="Indicate if the contents of this tag and all enclosed tags should be rendered (default 'true')" />
<c:if test="${empty render or render}">
<c:if test="${empty page || page lt 1}">
<c:set var="page" value="1" />
</c:if>
<c:if test="${empty size || size lt 1}">
<c:set var="size" value="10" />
</c:if>
<spring:message code="list_size" var="list_size" htmlEscape="false" />
<c:out value="${list_size} " />
<c:forEach var="i" begin="5" end="25" step="5">
<c:choose>
<c:when test="${size == i}">
<c:out value="${i}" />
</c:when>
<c:otherwise>
<spring:url value="" var="sizeUrl">
<spring:param name="page" value="1" />
<spring:param name="size" value="${i}" />
</spring:url>
<a href="${sizeUrl}">${i}</a>
</c:otherwise>
</c:choose>
<c:out value=" " />
</c:forEach>
<c:out value="| " />
<c:if test="${page ne 1}">
<spring:url value="" var="first">
<spring:param name="page" value="1" />
<spring:param name="size" value="${size}" />
</spring:url>
<spring:url value="/resources/images/resultset_first.png" var="first_image_url" />
<spring:message code="list_first" var="first_label" htmlEscape="false" />
<a class="image" href="${first}" title="${fn:escapeXml(first_label)}">
<img alt="${fn:escapeXml(first_label)}" src="${first_image_url}" />
</a>
</c:if>
<c:if test="${page gt 1}">
<spring:url value="" var="previous">
<spring:param name="page" value="${page - 1}" />
<spring:param name="size" value="${size}" />
</spring:url>
<spring:url value="/resources/images/resultset_previous.png" var="previous_image_url" />
<spring:message code="list_previous" var="previous_label" htmlEscape="false" />
<a class="image" href="${previous}" title="${fn:escapeXml(previous_label)}">
<img alt="${fn:escapeXml(previous_label)}" src="${previous_image_url}" />
</a>
</c:if>
<c:out value=" " />
<spring:message code="list_page" arguments="${page},${maxPages}" argumentSeparator="," />
<c:out value=" " />
<c:if test="${page lt maxPages}">
<spring:url value="" var="next">
<spring:param name="page" value="${page + 1}" />
<spring:param name="size" value="${size}" />
</spring:url>
<spring:url value="/resources/images/resultset_next.png" var="next_image_url" />
<spring:message code="list_next" var="next_label" htmlEscape="false" />
<a class="image" href="${next}" title="${fn:escapeXml(next_label)}">
<img alt="${fn:escapeXml(next_label)}" src="${next_image_url}" />
</a>
</c:if>
<c:if test="${page ne maxPages}">
<spring:url value="" var="last">
<spring:param name="page" value="${maxPages}" />
<spring:param name="size" value="${size}" />
</spring:url>
<spring:url value="/resources/images/resultset_last.png" var="last_image_url" />
<spring:message code="list_last" var="last_label" htmlEscape="false" />
<a class="image" href="${last}" title="${fn:escapeXml(last_label)}">
<img alt="${fn:escapeXml(last_label)}" src="${last_image_url}" />
</a>
</c:if>
</c:if>
</jsp:root>
精彩评论