JSTL+EL表达式+JSP自定义框架案例
不会框架不要紧,我带你自定义框架
前言:这标题说的有点大了,当一回标题党,之前在学JSP的时候提到了JSTL和EL表达式,由于一直钟情于Servlet,迟迟没有更新别的,这回算是跳出来了。这回放个大招,用Spring+SpringMVC+Spring Jdbc Template,实现一个增删改查加分页,但重点不在这,我的重心在于JSTL和EL表达式,标题虽然有点大,但话糙理不糙,我真的是要自定义框架,当然,这个框架可大可小,大的我不敢说,用JSTL自定义标签封装个分页还是可以的,也算补上JSTL和EL表达式的学习吧。对于那些一直跟着我跟新博客脚步的朋友,我提醒你们不要着急,你要是好奇就可以先试着跟着我的案例试试手,不要看到SSM框架就说还没学,不会啥的,哈哈,开玩笑,都没学怎么可能会呢,我说了,这篇的重点在于JSTL和EL表达式,重要的话说了不下三遍了,至于附加的SSM,我会持续跟新,会手把手带你理解的,别急,别急,就当先认识一下SSM吧。
环境准备
我用的开发工具是IDEA,如果有不会用IDEA的朋友可以看之前写过的博客《IDEA新手使用教程》,我建的这是一个Maven项目,如果有朋友不知道Maven,可以先看一下我之前写的介绍Maven的博客《Maven》,不知道如何配置Maven环境的可以看《Maven的安装与配置》https://www.cnblogs.com/zyx110/p/10801666.html不知道如何在IDEA中建Maven项目的朋友可以看《IDEA为新手专业打造》,此案例还会用到Tomcat,同样,不会在IDEA中配置Tomcat的朋友可以看《IDEA为新手专业打造》,好,完成这些,就可以开始敲代码了。
用JSTL封装框架
写之前先简单介绍一下JSTL和EL表达式:
JSTL简介及环境搭建
什么是JSTL
JSTL是Java中的一个定制标记库集
为什么要使用JSTL
实现了JSP页面中的代码复用,基于标签库原理,重复率较高的代码块支持复用,提高效率
书写JSP页面时可读性更强,长得很像XML,方便前端查看和参与开发
举例:
不同角色用户登录时显示不同提示信息
需要导入的JSTL模块
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency>
EL表达式配合使用JSTL
第一个JSTL小程序
在JSP页面中导入JSTL标签库
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
使用out标签输出
<c:out value="Hello JSTL"></c:out>
JSTL标签的四大分类:核心标签、格式化标签、SQL标签、XML标签EL表达式
- EL表达式全名为Expression Language,经常与JSTL配合使用,使得JSP页面更直观,写法更简单。
普通表达式的写法: <%=session.getValue("name") %>
EL表达式写法: <c:out value="${sessionScope.name}" />
- EL表达式的格式
用美元符号“$”定界,内容包括在花括号“{ }”中;
- "."与"[ ]"运算符
² 通常情况是通用的${user.sex}或${user["sex"]}
² "[ ]"还可以用来进行集合元素中的定位${booklist[0].price}
² 当包含特殊字符时,必须使用"[ ]",例如:${user["first-name"]}
² 通过变量动态取值:${user[param]},例如:param可以是name/sex/others
EL变量
EL自动类型转换
EL隐式对象
EL运算符
JSP自定义标签
什么是自定义标签
在实际开发过程中不能出现大量的html+java代码相混合的jsp页面,但是有时候jsp标签和第三方标签满足不了正常的开发工作,这就需要开发人员将业务逻辑封装到符合jsp规范的类或接口中,来自己定义标签从而满足不同的开发需求。这样做的缺点是会加重开发的工作量,但在开发过程中简化了前后端的沟通,便于后期的维护,这点工作量也是微不足道的。我们可以自己定义一套标签机制,让完全不懂写代码的人开发一套网站出来。
开发第一个自定义标签
案例场景:
在页面中显示当前时间,格式:“当前时间为:2017年8月1日 10:30:50”
- 如果使用传统的jsp脚本开发,代码如下:
<% SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String date = sdf.format(new Date()); %> 当前时间为:<%=date %>
显示结果:
- 下面使用自定义标签库来实现这个案例
第一步:编写自定义标签的业务逻辑处理类
DateTag
package utils; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.TagSupport; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; public class DateTag extends TagSupport { private String format="yyyy-MM-dd HH:mm:ss"; private String color="blue"; private String fontSize="12px"; public void setFormat(String format) { this.format = format; } public void setColor(String color) { this.color = color; } public void setFontSize(String fontSize) { this.fontSize = fontSize; } public int doStartTag() throws JspException { //自定义业务 SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format); String date = simpleDateFormat.format(new Date()); String htmlshow = "<p class='' style='font-size:"+fontSize+";color:"+color+"'>"+date+"</p>"; try { pageContext.getOut().print(htmlshow); } catch (IOException e) { e.printStackTrace(); } return super.doStartTag(); } }
第二步:在WEB-INF目录下编写*.tld文件注册标签
格式模板
datetag.tld
<?xml version="1.0" encoding="utf-8"?> <taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1"> <tlib-version>1.0</tlib-version> <short-name>myshortname</short-name> <uri>http://mycompany.com</uri> <tag> <name>date</name> <tag-class>utils.DateTag</tag-class> <body-content>empty</body-content> <attribute> <name>format</name> <required>false</required> </attribute> <attribute> <name>color</name> <required>false</required> </attribute> <attribute> <name>fontSize</name> <required>false</required> </attribute> </tag> </taglib>
JSP显示
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <%@ taglib prefix="z" uri="http://mycompany.com" %> <%@ taglib prefix="c" uri="http://mycompany.com" %> <html> <head> <title>显示时间</title> </head> <body> <h1>index.jsp</h1> <c:date/> </body> </html>
Spring+SpringMVC+Spring Jdbc Template
数据库结构
项目结构
Pom.xml
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!--Spring核心基础依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!--日志相关--> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> </dependencies>
Web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!--处理中文乱码--> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--设置访问静态资源--> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.css</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.js</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.jpg</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.png</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.gif</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.mp3</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.mp4</url-pattern> </servlet-mapping> </web-app>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd "> <!--配置注解要扫描的包--> <context:component-scan base-package="controller"></context:component-scan> <context:component-scan base-package="dao"></context:component-scan> <context:component-scan base-package="Service"></context:component-scan> <context:component-scan base-package="pojo"></context:component-scan> <context:component-scan base-package="utils"></context:component-scan> <context:component-scan base-package="test"></context:component-scan> <mvc:annotation-driven></mvc:annotation-driven> <!--配置spring-jdbcTemplate--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/bbb?useUnicode=true&characterEncoding=UTF-8"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!--配置事务--> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!--注册事务注解驱动--> <tx:annotation-driven transaction-manager="txManager"></tx:annotation-driven> <!--配置访问静态资源--> <mvc:resources mapping="/js/**" location="/js/"></mvc:resources> <mvc:resources mapping="/css/**" location="/css/"></mvc:resources> <mvc:resources mapping="/img/**" location="/img/"></mvc:resources> <!--配置视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--配置前缀--> <property name="prefix" value="/"></property> <!--配置后缀--> <property name="suffix" value=".jsp"></property> </bean> <!--创建文件上传组件对象--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean> </beans>
Book
package pojo; public class Book { @Override public String toString() { return "Book{" + "id=" + id + ", bookname='" + bookname + '\'' + ", price=" + price + '}'; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getBookname() { return bookname; } public void setBookname(String bookname) { this.bookname = bookname; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } private int id; private String bookname; private int price; }
PageBean
package pojo; import java.util.List; public class PageBean<T> { private int pageCode;//当前页码 private int totalPage;//总页数 private int count;//总记录数 private int pageSize;//每页记录数 private List<T> pageList;//每页的数据 public PageBean(int pageCode, int pageSize, int count, List<T> pageList) { this.pageCode = pageCode; this.count = count; this.pageSize = pageSize; this.pageList = pageList; } public PageBean() { } public int getPageCode() { return pageCode; } public void setPageCode(int pageCode) { this.pageCode = pageCode; } public int getTotalPage() { int tp = count/pageSize; return count%pageSize==0 ? tp : tp+1; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public List<T> getPageList() { return pageList; } public void setPageList(List<T> pageList) { this.pageList = pageList; } }
BookDao
package dao; import pojo.Book; import java.util.List; public interface BookDao { public List<Book> findByPage(int pageCode,int pageSize); public int count(); }
BookDaoImpl
package dao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import pojo.Book; import java.util.List; @Repository public class BookDaoImpl implements BookDao { @Autowired private JdbcTemplate jdbcTemplate; @Override public List<Book> findByPage(int pageCode, int pageSize) { String sql = "select * from book limit ?,?"; Object[] param = {(pageCode-1)*pageSize,pageSize}; return jdbcTemplate.query(sql,new BeanPropertyRowMapper<Book>(Book.class),param); } @Override public int count() { String sql = "select count(*) from book"; return jdbcTemplate.queryForObject(sql,Integer.class); } }
BookService
package Service; import pojo.Book; import pojo.PageBean; public interface BookService { public PageBean<Book> findByPage(int pageCode,int pageSize); }
BookServiceImpl
package Service; import dao.BookDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import pojo.Book; import pojo.PageBean; @Service public class BookServiceImpl implements BookService { @Autowired private BookDao bookDao; @Override public PageBean<Book> findByPage(int pageCode, int pageSize) { return new PageBean<Book>(pageCode,pageSize,bookDao.count(),bookDao.findByPage(pageCode,pageSize)); } }
BookController
package controller; import Service.BookService; import com.sun.org.apache.xml.internal.resolver.readers.XCatalogReader; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import pojo.Book; import pojo.PageBean; import utils.RequestPage; @Controller @RequestMapping("/book") public class BookController { @Autowired private BookService bookService; @RequestMapping("/query") public String findByPage(Integer page, Model model){ page = RequestPage.getPage(page);//判断是否为空 PageBean<Book> pageBean = bookService.findByPage(page,RequestPage.PAGE_SIZE); model.addAttribute("pageBean",pageBean); return "book"; } }
DateTag
package utils; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.TagSupport; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; public class DateTag extends TagSupport { private String format="yyyy-MM-dd HH:mm:ss"; private String color="blue"; private String fontSize="12px"; public void setFormat(String format) { this.format = format; } public void setColor(String color) { this.color = color; } public void setFontSize(String fontSize) { this.fontSize = fontSize; } public int doStartTag() throws JspException { //自定义业务 SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format); String date = simpleDateFormat.format(new Date()); String htmlshow = "<p class='' style='font-size:"+fontSize+";color:"+color+"'>"+date+"</p>"; try { pageContext.getOut().print(htmlshow); } catch (IOException e) { e.printStackTrace(); } return super.doStartTag(); } }
PageTag
package utils; import pojo.PageBean; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.TagSupport; import java.io.IOException; public class PageTag extends TagSupport { private PageBean pageBean; private String url; public void setUrl(String url) { this.url = url; } public void setPageBean(PageBean pageBean) { this.pageBean = pageBean; } @Override public int doStartTag() throws JspException { try { StringBuffer sb = new StringBuffer(); //首页 sb.append("<a href=\"" + url + "?page=1\">首页</a> "); //上一页 if (pageBean.getPageCode() <= 1) { sb.append("<span style=\"color: #555;\">上一页</span> "); } else { sb.append("<a href=\"" + url + "?page=" + (pageBean.getPageCode() - 1) + "\">上一页</a> "); } //显示页码 int begin, end; if (pageBean.getTotalPage() <= 10) { begin = 1; end = pageBean.getTotalPage(); } else { begin = pageBean.getPageCode() - 5; end = pageBean.getPageCode() + 4; if (begin < 1) { begin = 1; end = 10; } else if (end > pageBean.getTotalPage()) { begin = pageBean.getTotalPage() - 9; end = pageBean.getTotalPage(); } } for (int i = begin; i <= end; i++) { if (i == pageBean.getPageCode()) { sb.append("<span style=\"color:red;\">" + i + "</span> "); } else { sb.append("<a href=\"" + url + "?page=" + i + "\">[" + i + "]</a> "); } } //下一页 if (pageBean.getPageCode() >= pageBean.getTotalPage()) { sb.append("<span style=\"color: #555;\">下一页</span>"); } else { sb.append("<a href=\"" + url + "?page=" + (pageBean.getPageCode() + 1) + "\">下一页</a> "); } //尾页 sb.append("<a href=\"" + url + "?page=" + pageBean.getTotalPage() + "\">尾页</a> \n" + " 页码" + pageBean.getPageCode() + "/" + pageBean.getTotalPage()); pageContext.getOut().print(sb.toString()); } catch (IOException e) { e.printStackTrace(); } return super.doStartTag(); } } RequestPage package utils; public class RequestPage { public static final int PAGE_SIZE =5; public static Integer getPage(Integer page){ if (page==null||page<1){ page=1; } return page; } }
datetag.tld
<?xml version="1.0" encoding="utf-8"?> <taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1"> <tlib-version>1.0</tlib-version> <short-name>myshortname</short-name> <uri>http://mycompany.com</uri> <tag> <name>date</name> <tag-class>utils.DateTag</tag-class> <body-content>empty</body-content> <attribute> <name>format</name> <required>false</required> </attribute> <attribute> <name>color</name> <required>false</required> </attribute> <attribute> <name>fontSize</name> <required>false</required> </attribute> </tag> <tag> <name>page</name> <tag-class>utils.PageTag</tag-class> <body-content>empty</body-content> <attribute> <name>pageBean</name> <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>url</name> <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
book.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="z" uri="http://mycompany.com" %> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/book.css"> <html> <head> <title>图书</title> </head> <body> <h1 align="center">图书列表</h1> <hr> <table> <tr> <th>ID</th> <th>书名</th> <th>价格</th> </tr> <c:forEach var="book" items="${pageBean.pageList}"> <tr> <td>${book.id}</td> <td>${book.bookname}</td> <td>${book.price}</td> </tr> </c:forEach> </table> <div id="page"> <z:page url="${pageContext.request.contextPath}/book/query" pageBean="${pageBean}"></z:page> </div> </body> </html>
运行显示
分享结束
后面我会持续分享SSM框架知识,欲知后文如何,请看下回分解
*****************************************************************************************************
我的博客园地址:https://www.cnblogs.com/zyx110/
作者:泰斗贤若如
微信公众号:去有风的地方飞翔
Github:https://github.com/zyx110
有事微信:zyxt1637039050
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。
我不能保证我所说的都是对的,但我能保证每一篇都是用心去写的,我始终认同: “分享的越多,你的价值增值越大”,我们一同在分享中进步,在分享中成长,越努力越幸运。再分享一句话“十年前你是谁,一年前你是谁,甚至昨天你是谁,都不重要。重要的是,今天你是谁,以及明天你将成为谁。”
人生赢在转折处,改变从现在开始!
支持我的朋友们记得点波推荐哦,您的肯定就是我前进的动力。