jstl视图
让我们通过对Spring MVC的Controller开发的更多探索来改进我们以前的Spring JDBC应用程序 。 我将展示另一种编写新的Controller的练习,该Controller处理HTML表单并在JSP视图页面中使用JSTL标签。
要在Spring MVC应用程序中启用JSTL,您需要将以下内容添加到WebAppConfig
配置类中。 让我们将其WebApp.java
之外,并移至src/main/java/springweb/WebAppConfig.java
它自己的顶级类文件中。
package springweb;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;@Configuration
@EnableWebMvc
@ComponentScan("springweb.controller")
public class WebAppConfig {@Beanpublic InternalResourceViewResolver viewResolver() {InternalResourceViewResolver result = new InternalResourceViewResolver();result.setPrefix("/");result.setSuffix(".jsp");return result;}
}
在InternalResourceViewResolver
bean内,您定义在哪里可以找到其中包含JSTL标记的JSP页面。 prefix
设置器是相对于您的src/webapp
位置的路径。 如果需要,这可以让您完全隐藏JSP文件。 例如,通过将其设置为"/WEB-INF/jsp"
您可以将所有JSP文件移动并存储到src/webapp/WEB-INF/jsp
,该文件在Web应用程序中是私有的。 suffix
只是文件扩展名。 这两个值使您可以使用JSP文件的基本名称返回控制器内的视图名称,该名称可以缩写为“ / myform”或“ / index”等。
如果要将Tomcat用作Web容器,则还需要添加JSTL jar依赖项,因为Tomcat服务器不附带标准标记库! 因此,现在将其添加到pom.xml
文件中。
<dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency>
当您使用pom.xml
文件时,可能需要添加Tomcat maven插件,以便在运行Web应用程序时可以在命令行中键入更少的内容。
<project>
...<build><plugins><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.1</version></plugin></plugins></build>
...
</project>
这样,您应该可以在项目的根目录下运行mvn tomcat7:run
,而无需插件前缀。
那么JSTL给您的应用带来了什么? 好吧,实际上很多。 它使您可以使用在编写JSP视图时经常使用的一些标准JSP标记。 我将通过一组Controller和视图来演示这一点,以捕获来自应用程序的用户评论。 请注意,我将尝试仅以最基本的方式向您展示如何使用Spring Controller。 Spring实际上带有一个自定义form
JSP标记,该标记使用起来功能强大得多。 我将在其他时间将其保留为另一篇文章。 今天,让我们集中精力学习更多有关基本Spring Controller和JSTL的知识,以及有关Spring JDBC数据服务的更多知识。
我们想要捕获用户评论,所以让我们添加一个数据库表来存储该信息。 将以下DDL添加到src/main/resources/schema.sql
文件中。 同样,这是针对上一篇文章项目设置的H2数据库。
CREATE TABLE COMMENT (ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT,TEXT VARCHAR(10240) NOT NULL,FROM_USER VARCHAR(15) NULL,FROM_USER_IP VARCHAR(15) NULL,FROM_URL VARCHAR(1024) NULL,TAG VARCHAR(1024) NULL,TS DATETIME NOT NULL
);
这次,我们将编写一个数据模型类来匹配该表。 让我们添加src/main/java/springweb/data/Comment.java
package springweb.data;import java.util.Date;public class Comment {Long id;String text;String fromUrl;String fromUser;String fromUserIp;String tag;Date ts;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getText() {return text;}public void setText(String text) {this.text = text;}public String getFromUrl() {return fromUrl;}public void setFromUrl(String fromUrl) {this.fromUrl = fromUrl;}public String getFromUser() {return fromUser;}public void setFromUser(String fromUser) {this.fromUser = fromUser;}public String getFromUserIp() {return fromUserIp;}public void setFromUserIp(String fromUserIp) {this.fromUserIp = fromUserIp;}public String getTag() {return tag;}public void setTag(String tag) {this.tag = tag;}public Date getTs() {return ts;}public void setTs(Date ts) {this.ts = ts;}private String getTrimedComment(int maxLen) {if (text == null)return null;if (text.length() <= maxLen)return text;return text.substring(0, maxLen);}@Overridepublic String toString() {return "Comment{" +"id=" + id +", ts=" + ts +", text='" + getTrimedComment(12) + '\'' +'}';}public static Comment create(String commentText) {Comment result = new Comment();result.setText(commentText);result.setTs(new Date());return result;}
}
就像以前的文章一样,我们将编写一个数据服务来处理数据模型的插入和检索。 我们添加一个新的src/main/java/springweb/data/CommentService.java
文件
package springweb.data;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.stereotype.Repository;import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;@Repository
public class CommentService {public static Log LOG = LogFactory.getLog(CommentService.class);private JdbcTemplate jdbcTemplate;private SimpleJdbcInsert insertActor;private RowMapper<Comment> commentBeanRowMapper = new BeanPropertyRowMapper<Comment>(Comment.class);@Autowiredpublic void setDataSource(DataSource dataSource) {this.jdbcTemplate = new JdbcTemplate(dataSource);this.insertActor = new SimpleJdbcInsert(dataSource).withTableName("COMMENT").usingGeneratedKeyColumns("ID");}public void insert(Comment comment) {LOG.info("Inserting Comment + " + comment);Map<String, Object> parameters = new HashMap<String, Object>(2);parameters.put("TEXT", comment.getText());parameters.put("FROM_USER", comment.getFromUser());parameters.put("FROM_USER_IP", comment.getFromUserIp());parameters.put("FROM_URL", comment.getFromUrl());parameters.put("TAG", comment.getTag());parameters.put("TS", comment.getTs());Number newId = insertActor.executeAndReturnKey(parameters);comment.setId(newId.longValue());LOG.info("New Comment inserted. Id=" + comment.getId());}public List<Comment> findComments() {String sql = "SELECT " +"ID as id, " +"TEXT as text, " +"TAG as tag, " +"TS as ts, " +"FROM_USER as fromUser, " +"FROM_USER_IP as fromUserIp, " +"FROM_URL as fromUrl " +"FROM COMMENT ORDER BY TS";List<Comment> result = jdbcTemplate.query(sql, commentBeanRowMapper);LOG.info("Found " + result.size() + " Comment records.");return result;}
}
由于我们没有使用任何花哨的ORM,而只是使用普通的JDBC,因此我们将不得不在数据服务中编写SQL。 但是要感谢Spring的好东西,它使诸如SimpleJdbcInsert
助手使工作变得更加轻松,该助手处理数据库的插入和自动生成键的检索等。另外还要注意,在查询中,我们使用Spring的BeanPropertyRowMapper
自动将JDBC结果集转换为Java bean Comment
对象! 简单,直接,快速。
现在我们在src/main/java/springweb/controller/CommentController.java
添加Spring控制器来处理Web请求。
package springweb.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import springweb.data.Comment;
import springweb.data.CommentService;import javax.servlet.http.HttpServletRequest;
import java.util.List;@Controller
public class CommentController {@Autowiredprivate CommentService commentService;@RequestMapping(value="/comments")public ModelAndView comments() {List<Comment> comments = commentService.findComments();ModelAndView result = new ModelAndView("/comments");result.addObject("comments", comments);return result;}@RequestMapping(value="/comment")public String comment() {return "comment";}@RequestMapping(value="/comment", method = RequestMethod.POST)public ModelAndView postComment(HttpServletRequest req, @RequestParam String commentText) {String fromUrl = req.getRequestURI();String user = req.getRemoteUser();String userIp = req.getRemoteAddr();Comment comment = Comment.create(commentText);comment.setFromUserIp(userIp);comment.setFromUser(user);comment.setFromUrl(fromUrl);commentService.insert(comment);ModelAndView result = new ModelAndView("comment-posted");result.addObject("comment", comment);return result;}
}
在此控制器中,我们映射/comment
URL来处理HTML表单的显示,该表单返回comment.jsp
视图。 该方法默认处理HTTP GET
。 请注意,我们在单独的postComment()
方法上重新映射了相同的/comment
URL来处理HTTP POST
! 在此演示中了解Spring Controller可以处理HTTP请求的程度。 非常注意postComment()
方法中声明的参数。 Spring会根据声明的类型自动处理HTTP请求对象并映射到您的方法! 在某些情况下,您需要借助@RequestParam
之类的注释来使其明确,但是Spring会为您解析HTTP请求和提取! 如果我们要编写直接的Servlet代码,则可以节省大量重复的样板代码。
现在让我们看一下视图以及如何使用JSTL。 /comments
URL映射到src/main/webapp/comments.jsp
视图文件,该文件将列出所有Comment
模型对象。
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:choose>
<c:when test="${empty comments}"><p>There are no comments in system yet.</p>
</c:when>
<c:otherwise><table border="1"><tr><td>INDEX</td><td>TIME</td><td>FROM</td><td>COMMENT</td></tr><c:forEach items="${comments}" var="comment" varStatus="status"><tr valign="top"><td>${status.index}</td><td>${comment.ts}</td><td>${comment.fromUserIp}</td><%-- The c:out will escape html/xml characters. --%><td><pre><c:out value="${comment.text}"/></pre></td></tr></c:forEach></table>
</c:otherwise>
</c:choose>
JSTL上的相当标准的东西。 接下来是HTML表单,用于在src/main/webapp/comment.jsp
文件中发布评论。
<form action="comment" method="POST">
<textarea name="commentText" rows="20" cols="80"></textarea>
<br/>
<input type="submit" value="Post"/>
</form>
成功发布和处理表单后,我们只需返回src/main/webapp/comment-posted.jsp
文件中的新页面作为输出。
<p>Your comment has been posted. Comment ID=${comment.id}</p>
如果您已正确完成这些操作,则应该可以运行mvn tomcat7:run
并浏览http://localhost:8080/spring-web-annotation/comment
以查看表单。 转到/comments
URL以验证所有已发布的评论。
请注意,尽管我使用Spring Controller作为后端,但所有视图都在基本的JSTL中,甚至表单也只是基本HTML元素! 我这样做是为了让您看到Spring Controller有多灵活。
我知道今天有很多代码要发布到博客文章中,但是我想完整一些,并尝试显示带有教程笔记的有效演示。 我选择将其包含在文件内容中,而不是将项目下载到其他地方。 它使我的注释和解释更易于与代码匹配。
到此为止,我们今天的教程将结束。 如果您觉得有帮助,请留下笔记。
翻译自: https://www.javacodegeeks.com/2013/10/exploring-spring-controller-with-jstl-view.html
jstl视图