使用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 {
    @Bean
    public 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);
    }

    @Override
    public 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);

    @Autowired
    public 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 {

    @Autowired
    private 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值