使用JSTL视图探索Spring Controller

让我们通过对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有多灵活。

我知道今天有很多代码要发布到博客文章中,但是我想完整些,并尝试显示带有教程笔记的有效演示。 我选择将其包含在文件内容中,而不是将项目下载到其他地方。 它使我的注释和解释更易于与代码匹配。

到此为止,我们今天的教程结束了。 如果您觉得有帮助,请留下笔记。

参考: A程序员杂志博客上的JCG合作伙伴 Zemian Deng从JSTL视图探索Spring Controller 。

翻译自: https://www.javacodegeeks.com/2013/10/exploring-spring-controller-with-jstl-view.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366243.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSS 小结笔记之em

1、为什么使用em em也是css中的一种单位&#xff0c;和px类似。很多人会疑惑为什么有了px之后还要使用em&#xff0c;而且em使用起来相对于px来讲比较麻烦。 em主要是应用于弹性布局&#xff0c;下面给出一个小栗子说明em的强大之处 <!DOCTYPE html> <html lang&quo…

java 向父类_Java基础——面向对象(Object父类)

原标题&#xff1a;Java基础——面向对象(Object父类)声明&#xff1a;本栏目所使用的素材都是凯哥学堂VIP学员所写&#xff0c;学员有权匿名&#xff0c;对文章有最终解释权&#xff1b;凯哥学堂旨在促进VIP学员互相学习的基础上公开笔记。Object 父类&#xff1a;Object的方法…

fedora 不在sudoers文件中_COPR 仓库中 4 个很酷的新软件(2019.4) | Linux 中国

COPR 是个人软件仓库集合&#xff0c;它不在 Fedora 中。这是因为某些软件不符合轻松打包的标准。或者它可能不符合其他 Fedora 标准&#xff0c;尽管它是自由而开源的。-- Dominik TurecekCOPR 是个人软件仓库集合[1]&#xff0c;它不在 Fedora 中。这是因为某些软件不符合轻松…

解决小程序里面的图片之间有空隙的问题???

1、将图片转换为块级对象 即&#xff0c;设置image为display:block; image {display:block;}2、设置图片的垂直对齐方式 即&#xff0c;设置图片的vertical-align属性为"top,text-top,bottom,text-bottom" image {vertical-align: top;vertical-align: text-top;…

使用Cassandra和Nutch爬网

因此&#xff0c;您想从互联网上收集大量数据吗&#xff1f; 有什么比Cassandra更好的存储机制&#xff1f; 使用Nutch可以轻松做到这一点。 人们经常在Nutch后面使用Hbase。 这可行&#xff0c;但是如果您是&#xff08;或想成为&#xff09;Cassandra商店&#xff0c;则可能…

弹性盒布局实例

今天给大家搞一个弹性盒布局的实例&#xff0c;最近一直在复习一些基础的东西&#xff0c;所以一直会跟大家分享一些基础的东西 说实话&#xff0c;最近感觉被掏空了&#xff0c;别问我为什么&#xff0c;谁去保健谁知道&#xff0c;哈哈&#xff0c;注意安全&#xff0c;好了步…

win7插了耳机还是外放_安卓手机用耳机听歌音量太大怎么办

大部分安卓手机控制音量不是线性调节的&#xff0c;很难随心调节音量大小&#xff0c;这导致用耳机插手机听歌的时候即使开了最低音量&#xff0c;很多人觉音量还是太大&#xff0c;尤其是在夜深人静的时候。怎么解决呢&#xff1f;个人整理了一些方法。一无需root&#xff0c;…

skype for business 无法共享桌面、无法传输图片

以管理员身份运行如下PowerShell命令&#xff0c;清除Skype for Business缓存记录 #以管理员身份运行如下PowerShell命令&#xff0c;清除Skype for Business缓存记录 Stop-Process -Name "lync*" Stop-Process -Name "outlook*" Stop-Process -Name "…

骨牌

DP,em.......&#xff0c;代码&#xff1a; #include<iostream> #include<algorithm> #include<cstring> using namespace std; int a[1100],b[1100]; int dp[1100][12005]; int n; int main() {cin>>n;for(int i1;i<n;i){cin>>a[i]>>b…

java 读取ppt文件_java使用poi读取ppt文件和poi读取excel、word示例

Apache的POI项目可以用来处理MS Office文档&#xff0c;codeplex上还有一个它的.net版本。POI项目可创建和维护操作各种基于OOXML和OLE2文件格式的Java API。大多数MS Office都是OLE2格式的。POI通HSMF子项目来支持Outlook&#xff0c;通过HDGF子项目来支持Visio&#xff0c;通…

vue lang_新疆人的“lang”是“浪”吗?

小编&#xff1a;“老王&#xff0c;天气这么热&#xff0c;过几天我们几个人约上要到巩乃斯lang起呢也享受一下避暑生活么&#xff0c;你去不去&#xff1f;“老王&#xff1a;”这个礼拜六礼拜天都有事呢礼拜六我乌什塔拉的姨娘家出嫁丫头呢礼拜天五号渠的阿哥家给娃娃娶媳妇…

js将canvas保存成图片并下载

<canvas id"canvas" width"400" height"400"></canvas> <div><button id"save">保存</button> </div>var arr [{locations:[[0,0],[200,200],[0,400]],color:"red"},{locations:[[0,0…

如果Java快死了,那么它肯定看起来非常健康

Java快要死了的奇怪但流行的断言只能在没有证据的情况下提出&#xff0c;而不是因为它。 在酷孩子闲逛的论坛&#xff08;Hacker News&#xff0c;Reddit等&#xff09;中反复出现的偏见与Java语言背道而驰。 人们常常反复感叹 Java冗长而流行。 虽然我接受第一个描述符&#…

java 图片去除黑边_根据 Map 上的变量绘制彩色和形状的点时,保持符号的黑色边框(geom_point)...

我的问题与this thread有些相关&#xff0c;但我想为每个符号实际上都有黑色边框&#xff0c;因为我有符号重叠的实例&#xff0c;我认为有边框会有所帮助 . 但是&#xff0c;我的颜色和形状基于geom_point中美学内部的变量&#xff0c;因此使用shape 21和color NA的解决方案…

使用GreenDao 添加字段,删除表,新增表操作

GreenDao 给我个人感觉 比一般的ORM框架要好很多&#xff0c;虽然说上手和其他的比起来&#xff0c;较复杂&#xff0c;但是如果使用熟练以后&#xff0c;你会爱上这个框架的 用这些ORM 框架给我的感觉都是&#xff0c;当升级时&#xff0c;都需要进行数据库所有表的删除&#…

linux下log日志乱码_如何用 Linux 技巧大大提高工作效率?

作者 | 守望先生责编 | 屠敏前言Linux中的一些小技巧可以大大提高你的工作效率&#xff0c;本文就细数那些提高效率或者简单却有效的Linux技巧。命令编辑及光标移动这里有很多快捷键可以帮我们修正自己的命令。接下来使用光标二字代替光标的位置。删除从开头到光标处的命令文本…

安卓java桌面图标程序_android如何定制默认桌面上应用程序和shortcut图标 | 学步园...

可以在res/xml/default_workspace.xml文件中增加或删除tag标记块如果想删除默认browser图标&#xff1a;launcher:packageName"com.android.browser"launcher:className"com.android.browser.BrowserActivity"launcher:screen"2"launcher:x"…

Go语言基础之15--文件基本操作

一、文件读写 1.1 os.File os.File封装所有文件相关操作&#xff0c; 是一个自定义的struct。 a. 打开一个文件进行读操作&#xff1a; os.Open(name string) (*File, error) Open是以读的方式打开文件&#xff08;底层调用的是Openfile函数&#xff09;。 b. 关闭一个文件&…

Event flow

考虑这么个例子&#xff1a; <div><button id"btn">Click Me!</button> </div> 哪怕一个web开发的初学者都会知道&#xff0c;当我们鼠标在button上点击时&#xff0c;会在button上触发一个click事件。但是&#xff1a; button是div的一个子…

使用vux组件库常见报错($t)处理

错误一&#xff1a; [Vue warn]: Property or method "$t" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.…