Jsp+Servlet+JDBC新闻发布系统2.0
很久之前写了这样一篇博客,就很久没有更新博客了,后面陆陆续续有朋友在下面评论,询问一些问题。由于之前写的实在是时代久远,索性直接重构了一遍,重构过后的系统界面如下:
开发环境:
- windows
- eclipse
- mysql
白嫖地址
链接: https://pan.baidu.com/s/1-Fojg6p36GjiiWZSvLr-AA 提取码: n4em
【首页】
首页还沿用之前的样式,稍作调整。提供按条件查询新闻,可以根据新闻类型、关键字、类型+关键字进行检索。
- 加载方式采用了无限下拉分页加载,判断滚动条到了底部:$(window).scrollTop() == $(document).height() - $(window).height();
$(function(){var flag = 0;$(window).scroll(function(){ if ($(window).scrollTop() == $(document).height() - $(window).height()) {var pageCount = $("input[name='pageCount']").val();var pageNo = $("input[name='pageNo']").val();var keyWord = $("input[name='keyWord']").val();var type = $("input[name='type']").val();if(pageNo < pageCount){$.ajax({url:"coreServlet?bizCode=7",dataType:"json",data:{'keyword':keyWord, 'type':type, 'pageNo':parseInt(pageNo)+1},success:function(data){var html = "";$.each(data.newsList, function(i,val){ html += '<div class="new"> ';html += ' <div class="content row">';html += ' <div class="imgdiv">';html += ' <a href="coreServlet?bizCode=4&id='+val.id+'"><img src="'+val.img+'"/></a>';html += ' </div>';html += ' <div class="text">';html += ' <a href="coreServlet?bizCode=4&id='+val.id+'"><h4>"'+val.title+'</h4></a>';html += ' <p class="p1">"'+val.pudate+'-"'+val.type+'-"'+val.author+'-阅"'+val.click+'</p>';html += ' <p class="p2">"'+val.content+'</p>';html += ' </div>';html += ' </div>';html += '</div> ';});$(".new").last().after(html);$("input[name='pageNo']").val(parseInt(pageNo) + 1);}});}else if(pageNo == pageCount && flag == 0){flag ++;var html = '<p style="text-align:center; color:#FF8C69; font-size:14px; margin-top:10px; margin-bottom:10px;">-没有更多了-</p>';$(".new").last().after(html);}}});
});
- 时间格式化:采用自定义jstl标签。
- WEB-INF下面创建mytag.tld
<?xml version="1.0" encoding="UTF-8"?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0"> <tlib-version>1.0</tlib-version> <short-name>myTag</short-name> <function> <description>date change</description><!-- 对这个EL方法的描述 --> <name>formatDate</name><!-- 调用EL方法的名称 --> <function-class>cn.nicecoder.util.UFunction</function-class> <function-signature> java.lang.String formatDate(java.lang.String) </function-signature> <example>${myTag:formatDate(str)}</example><!-- 例如 --> </function> </taglib>
- 创建类,创建方法
public class UFunction {/*** 转换格式"年-月-日"* @param dateTime* @return*/public static String formatDate(String dateTime){if(StringUtil.isNotEmpty(dateTime)){return dateTime.substring(0,4) + "-" +dateTime.substring(4,6) + "-" + dateTime.substring(6,8); }return dateTime;}}
- 调用方式,jsp里面调用如下
<%@ taglib uri="/WEB-INF/mytag.tld" prefix="myTag" %> //顶部添加
<p class="p1">${myTag:formatDate(news.pudate)} - <span style="color: #20B2AA;">${news.type}</span> - ${news.author} - 阅${news.click}</p>
【详情页】
详情页和下面的管理员页面都采用了我最近发现的一个好用的UI框架layui,这个框架有自己的社区,而且持续更新中,感兴趣的可以百度layui。抛弃了在我看来只适合做后端的bootstrap。提供了发表评论和点赞评论功能。评论评论和点赞文章功能也有预留,type传值不同罢了,但是ui要稍作修改,暂时还没想好,后续可能会加上。评论的头像显示,再加入用户表之后也可以完善进去。
- layui富文本编辑器,功能不是很强,但是我更看中它的简洁和外观,鹅且持续更新中,用法见官网。
- 锚点定位,滑下来再滑上去手会很痛。使用起来很简单。
<a name="mao"></a>//点击下面的a标签会跳转到这里
<a href="#mao" ><i class="layui-icon layui-icon-face-smile"></i></a>//图中的top箭头
- ajax异步提交评论
function discuss(type, id){$("#dis-btn").attr("disabled","true");var content = layedit.getContent(index);$.ajax({dataType:'json',data :{'content':content, 'type':type, 'id':id},url :"coreServlet?bizCode=5",async : true,success :function(data){location.href = "coreServlet?bizCode=4&id="+ id;}}); }
- 获取请求的IP,得到IP的地区信息,这两个就从别的地方借来用用,这里记录一下,有点长但是很好用。
public class IPUtil {public static String getIpAddress(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } }
public class AddressUtil{ /** * * @param content * 请求的参数 格式为:name=xxx&pwd=xxx * @param encoding * 服务器端请求编码。如GBK,UTF-8等 * @return * @throws UnsupportedEncodingException */ public static String getAddresses(String content, String encodingString)throws UnsupportedEncodingException { // 这里调用pconline的接口 String urlStr = "http://ip.taobao.com/service/getIpInfo.php"; // 从http://whois.pconline.com.cn取得IP所在的省市区信息 String returnStr = getResult(urlStr, content, encodingString); if (returnStr != null) { // 处理返回的省市区信息 String[] temp = returnStr.split(","); if(temp.length<3){ return "0";//无效IP,局域网测试 } String region = (temp[5].split(":"))[1].replaceAll("\"", ""); region = decodeUnicode(region);// 省份 String country = ""; String area = ""; // String region = ""; String city = ""; String county = ""; String isp = ""; for (int i = 0; i < temp.length; i++) { switch (i) { case 1: country = (temp[i].split(":"))[2].replaceAll("\"", ""); country = decodeUnicode(country);// 国家 break; case 3: area = (temp[i].split(":"))[1].replaceAll("\"", ""); area = decodeUnicode(area);// 地区 break; case 5: region = (temp[i].split(":"))[1].replaceAll("\"", ""); region = decodeUnicode(region);// 省份 break; case 7: city = (temp[i].split(":"))[1].replaceAll("\"", ""); city = decodeUnicode(city);// 市区 break; case 9: county = (temp[i].split(":"))[1].replaceAll("\"", ""); county = decodeUnicode(county);// 地区 break; case 11: isp = (temp[i].split(":"))[1].replaceAll("\"", ""); isp = decodeUnicode(isp); // ISP公司 break; } } return region; } return null; } /** * @param urlStr * 请求的地址 * @param content * 请求的参数 格式为:name=xxx&pwd=xxx * @param encoding * 服务器端请求编码。如GBK,UTF-8等 * @return */ private static String getResult(String urlStr, String content, String encoding) { URL url = null; HttpURLConnection connection = null; try { url = new URL(urlStr); connection = (HttpURLConnection) url.openConnection();// 新建连接实例 connection.setConnectTimeout(2000);// 设置连接超时时间,单位毫秒 connection.setReadTimeout(2000);// 设置读取数据超时时间,单位毫秒 connection.setDoOutput(true);// 是否打开输出流 true|false connection.setDoInput(true);// 是否打开输入流true|false connection.setRequestMethod("POST");// 提交方法POST|GET connection.setUseCaches(false);// 是否缓存true|false connection.connect();// 打开连接端口 DataOutputStream out = new DataOutputStream(connection.getOutputStream());// 打开输出流往对端服务器写数据 out.writeBytes(content);// 写数据,也就是提交你的表单 name=xxx&pwd=xxx out.flush();// 刷新 out.close();// 关闭输出流 BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), encoding));// 往对端写完数据对端服务器返回数据 // ,以BufferedReader流来读取 StringBuffer buffer = new StringBuffer(); String line = ""; while ((line = reader.readLine()) != null) { buffer.append(line); } reader.close(); return buffer.toString(); } catch (IOException e) { e.printStackTrace(); } finally { if (connection != null) { connection.disconnect();// 关闭连接 } } return null; } /** * unicode 转换成 中文 * * @author fanhui 2007-3-15 * @param theString * @return */ public static String decodeUnicode(String theString) {char aChar;int len = theString.length();StringBuffer outBuffer = new StringBuffer(len);for (int x = 0; x < len;) {aChar = theString.charAt(x++);if (aChar == '\\') {aChar = theString.charAt(x++);if (aChar == 'u') {int value = 0;for (int i = 0; i < 4; i++) {aChar = theString.charAt(x++);switch (aChar) {case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':value = (value << 4) + aChar - '0';break;case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':value = (value << 4) + 10 + aChar - 'a';break;case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':value = (value << 4) + 10 + aChar - 'A';break;default:throw new IllegalArgumentException("Malformed encoding.");}}outBuffer.append((char) value);} else {if (aChar == 't') {aChar = '\t';} else if (aChar == 'r') {aChar = '\r';} else if (aChar == 'n') {aChar = '\n';} else if (aChar == 'f') {aChar = '\f';}outBuffer.append(aChar);}} else {outBuffer.append(aChar);}}return outBuffer.toString();}// 测试public static void main(String[] args) {AddressUtil addressUtils = new AddressUtil();String ip = "0:0:0:0:0:0:0:1";String address = "";try {address = addressUtils.getAddresses("ip=" + ip, "utf-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}System.out.println(address);} }
【管理员】
管理员页面依然采用的layui,实现了对新闻的发布,编辑,详情,删除。
- 点击箭头分页和首页采用的同一个js方法,传的参数不同。
- 类型转义可做成数据字典,通过自定义jstl标签进行转义显示。
- 上传图片,点击上传图片按钮和文章中插入图片采用同一个接口。采用的servlet3.0。好处就是写servlet不用配置web.xml,可以像springMVC一样使用注解。
- @WebServlet(name="imageUpload", urlPatterns="/imageUpload") 替代web.xml配置方式。
- @MultipartConfig 提供HttpServletRequest对文件上传的支持。通过Part p = req.getPart("name");name是input标签的name,如果name是不确定的,那么久用下面这种获取集合的方式获取到Part集合,再遍历之。通过下列一系列操作就可以把本地文件、图片上传到服务器。然后就可以被页面引用啦。
- 图片压缩是必要的,如果上传的图片过大,不仅占网速,占空间,在显示的时候也会出现问题,img会撑破div跑到外面去。后端处理方式通过Thumbnails这个jar包提供一些方法进行压缩,可以判断文件大小,也可以判断宽高,我采用的是宽高。同款jar包下载就在我的资源。
前端处理方式(发布新闻的时候,我是通过复制别的地方的新闻,图片自然就是引用的网上的地址,没有经过后台上传。没 有被压缩,显示会出问题。解决方法:img {max-width:762px;overflow:hidden;})
package cn.nicecoder.servlet;import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;import net.coobird.thumbnailator.Thumbnails;
import net.sf.json.JSONObject;/*** 上传文件servlet*-------------------------------* @author longtian* @date 2018年4月23日下午11:09:00* @description nicecoder.cn*-------------------------------*/
@WebServlet(name="imageUpload", urlPatterns="/imageUpload")
@MultipartConfig
public class UploadImageServlet extends HttpServlet {private static final long serialVersionUID = 1L; @Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("UTF-8"); Collection<Part> parts = req.getParts(); JSONObject result = new JSONObject();//Part p = req.getPart("name");for (Part part : parts) {String disposition = part.getHeader("content-disposition"); System.out.println("文件描述:" + disposition); //文件名,文件类型,文件大小String fileName = disposition.substring(disposition.lastIndexOf("=")+2, disposition.length()-1); String fileType = part.getContentType(); long fileSize = part.getSize(); System.out.println("fileName: " + fileName); System.out.println("fileType: " + fileType); System.out.println("fileSize: " + fileSize); //1.服务器保存文件路径String uploadPath = this.getServletConfig().getServletContext().getRealPath("/");//2.文件夹按日期分类String folder = new SimpleDateFormat("yyyyMMdd").format(new Date());//3.拼接文件名if(!new File(uploadPath + File.separator + folder).exists()) {new File(uploadPath + File.separator + folder).mkdirs();}//重命名并写入文件fileName = new SimpleDateFormat("yyyyMMdd_HHmmSS").format(new Date()) + fileName.subSequence(fileName.indexOf("."), fileName.length());part.write(uploadPath + folder + File.separator + fileName);//返回存储地址String src = uploadPath + folder + File.separator + fileName;BufferedImage bufferedImage = ImageIO.read(new File(src)); int width = bufferedImage.getWidth(); int height = bufferedImage.getHeight(); //图片过大的压缩一下if(width > 762){double scale = new BigDecimal((float)762/width).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); Thumbnails.of(src).size(762,(int) (height * scale)).keepAspectRatio(false).toFile(src); }result.put("code", 0);result.put("msg", "ok");JSONObject subObject = new JSONObject();subObject.put("src", folder + File.separator + fileName );subObject.put("title", fileName);result.put("data", subObject);/*适应layui,所以返回如下格式{"code": 0 //0表示成功,其它失败,"msg": "" //提示信息 //一般上传失败后返回,"data": {"src": "图片路径","title": "图片名称" //可选}}*/}PrintWriter wp = resp.getWriter();wp.write(result.toString());wp.close();}}
【其他页面】
管理员登录页面和权限页面,后期可能会加404页面,这里就一笔带过。
- 管理员登录,管理员界面通关口令通过微信公众号【在相思树下】,回复“1”获取。这样做是防止乱搞,非诚勿扰。公众号也可能会突然分享一波源码的链接,平时不会胡乱推送,可以放心关注啦~。
- 禁止访问页面,登录密码错误或者session过期都会跳到此页面。
【数据库设计】
系统共用了五张表,news<新闻表>,newsclass<新闻类别>,discuss<评论表>,agree<点赞表>,user<用户表>
news表 | |||
名 | 类型 | 长度 | 备注 |
id | int | 10 | 序号 |
img | varchar | 100 | 封面 |
title | varchar | 50 | 标题 |
content | blob | 0 | 内容 |
type | varchar | 10 | 类型 |
author | varchar | 50 | 作者 |
pudate | varchar | 50 | 修改时间 |
click | varchar | 20 | 点击量 |
discuss表 | |||
名 | 类型 | 长度 | 备注 |
id | int | 10 | 序号 |
type | varchar | 10 | 类型 |
discussid | varchar | 10 | 评论内容编号 |
content | blob | 0 | 内容 |
userid | varchar | 50 | 作者 |
pudate | varchar | 50 | 修改时间 |
agree | varchar | 20 | 点赞量 |
agree表 | |||
名 | 类型 | 长度 | 备注 |
id | int | 10 | 序号 |
type | varchar | 10 | 类型 |
agreeid | varchar | 10 | 点赞内容编号 |
userid | varchar | 50 | 作者 |
pudate | varchar | 50 | 修改时间 |
newsclass表 | |||
名 | 类型 | 长度 | 备注 |
id | int | 11 | 序号 |
clsname | varchar | 20 | 类型名 |
user表 | |||
名 | 类型 | 长度 | 备注 |
id | int | 11 | 序号 |
image | varchar | 255 | 头像 |
name | varchar | 255 | 昵称 |
ip | varchar | 20 | 评论人ip |
胡乱写了一堆,可能有的朋友对该项目的源码已经产生了一丢丢的兴趣。那么下面将放出源码的获取方式。虽然是个小项目,但是也投入了一定的精力,所以肯定不能无偿获取哈,希望能够理解。同时项目中仍有许多不足之处,也请多多批评指正。
方式一:CSDN资源下载链接,此乃土豪获取方式,仅需挥洒区区5个积分,便能立马将文中所述同款源码一波带走,简单而又粗暴。
方式二:通过公众号【在相思树下】,回复“签到”二字连续签到3天,亦可获得同款源码下载链接。而且后期有一些小项目的源码也能第一时间获取得到。敬请关注。有的朋友在公众号上私信我,说很着急,想立即获得源码的,请用方式一。说什么也没用,不听~不听~
公众号的回复是机器人回复,我不一定能够实时看见。BUG肯定是有的,有什么问题先自行研究,如果实在不行就在下面留言,或者私信,有时候回复较慢,请见谅。
2020-8-21 公众号故障中。。。
附:链接: https://pan.baidu.com/s/149VZ2ORNLk9eE4WP2ZxGHA 提取码: 39dt 包含表结构和数据。
白嫖地址
链接: https://pan.baidu.com/s/1-Fojg6p36GjiiWZSvLr-AA 提取码: n4em
Jsp+Servlet+JDBC新闻发布系统2.0相关推荐
- 基于JAVA+Servlet+JSP+MYSQL的新闻发布系统
项目功能: 系统包括用户登录注册,首页按列表查看新闻,浏览新闻详情,流量统计,找回密码,发布文章,更改个人资料,退出登录.管理员后台登录,总栏管理,类别管理,用户信息管理,管理员信息管理,新增文章,文 ...
- javaweb JSP JAVA 新闻发布系统源码(新闻管理系统)jsp新闻发布系统
javaweb JSP JAVA 新闻发布系统源码(新闻管理系统)jsp新闻发布系统 常见的Javaweb题材有 理财系统,就业管理系统,汽车租赁,简易网盘,疫情数据查看,在线招标房,屋租赁,教务管理 ...
- Jsp+Sevlet新闻发布系统
新版本已经发布, 点击查看2.0版本 . 一开始叫我写这个新闻发布系统的时候其实我是拒绝的,因为我有事,我想去写我的考试系统,但是他们说这个有学分,写完之后毕业变得很简单.很轻松.duang-的一 ...
- Java项目:小蜜蜂扩音器网上商城系统(java+JSP+Servlet+JDBC+Ajax+mysql)
源码获取:博客首页 "资源" 里下载! 一.项目简述 用户功能模块: 用户注册: 用户登录:商品模块:订单模块:后台管理系统功能:管理员模块: 商品模块:订单管理模块 : 二.项目 ...
- javaweb JSP JAVAJSP 新闻发布系统源码(JSP新闻管理系统)JSP新闻系统
javaweb JSP JAVAJSP 新闻发布系统源码(JSP新闻管理系统)JSP新闻系统 protected void doGet(HttpServletRequest req, HttpServ ...
- 基于jsp的新闻发布系统(论文)
Internet的蓬勃发展,使新闻的传播方式发生了巨大的变化,传统的信息传播媒体电视.广播.报纸已经不再是人们茶余饭后的主要精神甜点,人们更多的开始关注网络新闻.由于互联网所容纳的信息量大.内容丰富. ...
- 【免费毕设】基于jsp的新闻发布系统(论文)
文章目录 目录 一.系统设计 二.系统实现 源文件 目录 一.系统设计 3.1系统分析 3.1.1需求分析 1.通过相关调查,要求网站具有以下功能: 2.通过网络,展示各行业新闻及相关信息. 3.提供 ...
- JavaWeb新闻发布系统案例3
后台 后台主页模糊查询 <!-- 功能1:实现admin.jsp页面中新闻管理模块----模糊查询的搜索功能(根据标题进行模糊查询) --><!-- 注意:在没有学习servlet时 ...
- JavaWeb新闻发布系统案例08——完结篇
前台 注册登录界面+主界面+评论界面 效果: 代码: <%@ page language="java" contentType="text/html; charse ...
最新文章
- 物联网6类技术无线连接技术的分析
- 相同格式EXCEL汇总
- 产品诞生过程--导图
- python 接口测试 如何写配置文件_python接口自动化测试 - configparser配置文件解析器详细使用...
- 【OpenCV 例程200篇】37. 图像的灰度化处理和二值化处理
- 常用的一些页面操作 js jsp check
- Wince6.0应用开发:一、平台搭建
- MongoDB最大连接数的查看与修改
- python资料-Python资料汇总(建议收藏)
- 腾讯校园招聘笔试 2019-8-17 第四题 另一种解法
- 单模光纤和多模光纤的区别_一分钟了解光纤、单模光纤、多模光纤
- @autowired注解 抽象类_Spring容器注解注入
- 小白白红队初成长(2)主动信息收集
- OPPO Find X5系列领衔OPPO春季新品发布会,多款产品亮相
- 工业设备无线监控解决方案
- “(null)” is of a model that is not supported by this version of Xcode. Ple
- 以清净心看世界,以欢喜心过生活,以平常心生情味,以柔软心除挂碍。
- 大带宽、高灵敏度、扫描快速手持式监测接收机TFN DC700S
- Adobe相关(Windows平台)
- C++版-剑指offer 面试题6:重建二叉树(Leetcode105. Construct Binary Tree from Preorder and Inorder Traversal) 解题报告