功能设计:

1.实现读者文章的预览及下载

(实现了单击预览,双击下载)

2.实现文章查找

(实现了通过文章名查找(关键字)或者文章期数或年份(或者年份加期数))

实现步骤:

首先是数据库设计:

数据库使用一个数据表即可,三个字段,一个是filename用于储存文章名,一个是filepath用于储存文章链接,最后一个是time用于储存文章年份及期数。

create table duzhefile
(
filename char(20),
filepath char(100),
time char(6)
)

数据库创建成功后先将数据写入:

Duzhecurl.java

 package All;

 import java.sql.Connection;
import java.sql.PreparedStatement; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements; public class Duzhecurl { public static void main(String[] args) throws Exception {
// 第一步:访问读者首页
String url = "https://www.dzwzzz.com/";
Document document = Jsoup.connect(url).get(); // 第二步:解析页面
Elements datatime = document.select("a");
//获取a标签
for(int num=0;num<datatime.size();num++) {
//判断文章链接
if(datatime.get(num).attr("href").charAt(4)=='_') {
//获取a标签中href属性的值
String deHref = datatime.get(num).attr("href");
System.out.println("开始获取"+deHref.substring(0, 4)+"年第"+deHref.substring(5,7)+"期");
String time = deHref.substring(0,4)+deHref.substring(5,7);
//访问不同期刊页面
String DuZhe = "https://www.dzwzzz.com/"+deHref;
Document newdocu = Jsoup.connect(DuZhe).get();
//获取a标签
Elements a_Elements = newdocu.select("a");
for(int i=0;i<a_Elements.size();i++) {
//判断是否是文章链接
if (a_Elements.get(i).attr("href").charAt(0)=='d'
&&a_Elements.get(i).attr("href").charAt(1)=='u')
{
//访问文章所在页
String purpose = "https://www.dzwzzz.com/"+deHref.substring(0, 8)+a_Elements.get(i).attr("href");
Document finaldocu = Jsoup.connect(purpose).get();
//获取文章标题
Elements h1_elements = finaldocu.select("h1");
String title = h1_elements.text();
//获取文章内容
Elements p_Elements = finaldocu.select("p");
String Content = p_Elements.text();
String sql = "insert into duzhefile values(?,?,?)";
Connection conn = Connect.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, title);
pstmt.setString(2, purpose);
pstmt.setString(3, time);
pstmt.execute();
System.out.println("文章地址"+purpose);
System.out.println(title+" 写入成功!");
}
}
}
} } }

数据库写入之后开始设计界面:

FirstPage.fxml

 <?xml version="1.0" encoding="UTF-8"?>

 <?import javafx.scene.paint.*?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?> <AnchorPane prefHeight="361.0" prefWidth="643.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="All.FirstPageController">
<children>
<Pane prefHeight="420.0" prefWidth="643.0">
<children>
<TextField fx:id="SelectFile" layoutX="27.0" layoutY="24.0" prefHeight="23.0" prefWidth="184.0" promptText="输入文件名搜索" />
<Button fx:id="Select" layoutX="236.0" layoutY="24.0" mnemonicParsing="false" onMouseClicked="#ClickToSelect" text="搜索" />
<TableView fx:id="FileTest" layoutY="74.0" onMouseClicked="#SelectFile" prefHeight="345.0" prefWidth="394.0">
<columns>
<TableColumn fx:id="FileName" editable="false" prefWidth="152.0" text="文件名" />
<TableColumn fx:id="FilePath" editable="false" prefWidth="241.0" text="路径" />
</columns>
</TableView>
<Text fx:id="Preview" layoutX="398.0" layoutY="-170.0" strokeType="OUTSIDE" strokeWidth="0.0" text="文件名" textAlignment="CENTER" wrappingWidth="246.12109375" y="200.0">
<font>
<Font size="18.0" />
</font>
<fill>
<RadialGradient centerX="0.40555555555555556" centerY="0.5" radius="0.5">
<stops>
<Stop color="#dd3b09" />
<Stop color="#00dff8" offset="1.0" />
</stops>
</RadialGradient>
</fill>
</Text>
<Text layoutX="22.0" layoutY="65.0" strokeType="OUTSIDE" strokeWidth="0.0" text="单击预览文章,双击下载文章" wrappingWidth="194.0" />
<Button fx:id="reset" layoutX="305.0" layoutY="24.0" mnemonicParsing="false" onMouseClicked="#ClickToReset" text="返回" />
<Text fx:id="content" layoutX="394.0" layoutY="62.0" strokeType="OUTSIDE" strokeWidth="0.0" text="内容预览" textAlignment="CENTER" wrappingWidth="253.12109375" />
</children>
</Pane>
</children>
</AnchorPane>

界面设计完成后是这个样的:

生成控制类后插入数据并实现各个方法:

FirstPageController.java
 package All;

 import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ResourceBundle;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.omg.CORBA.PUBLIC_MEMBER; import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.input.MouseEvent;
import javafx.scene.text.Text; public class FirstPageController implements Initializable {
@FXML
private TextField SelectFile;//输入框
@FXML
private Button Select;//查找按钮
@FXML
private Button reset;//返回按钮
@FXML
private Text content;//预览内容
@FXML
private TableView<Data> FileTest;//表格
@FXML
private TableColumn<Data, String> FileName;//第一列存文章名
@FXML
private TableColumn<Data, String> FilePath;//第二列存文章链接
@FXML private Text Preview;//预览标题 private ObservableList<Data> cellData = FXCollections.observableArrayList();
//用于存储数据Data类型的
@FXML
public void SelectFile(MouseEvent event) throws IOException {
Data data = FileTest.getSelectionModel().getSelectedItem();//获取所选择的行的Data对象
String filename = data.getFilename().getValue();//获取选择的Data对象的文章名
String url = data.getFilepath().getValue();//获取选择的Data对象的文章地址
Document doc;//用来存储爬取到的网页源码
String Finacontent;//用来存储文章内容
try {
doc = Jsoup.connect(url).get();//获取Data对象的文章源码
Elements p_Elements = doc.select("p");//查找P标签
String Content = p_Elements.text();//保存p标签的内容
Preview.setText(filename);//将文章名写入面板
content.setText(Content);//将P标签的内容写入预览内容框中
Finacontent = Content;//将文章内容传出去
} catch (IOException e) {
Finacontent = null;//告诉外面内容为空
}
if (event.getClickCount() == 2 && Finacontent.length() > 50) {
//如果点击了两下且文章内容大于50个字符则
File file = new File("E:/FileTest/" + filename + ".txt");
// 创建文件输出流
OutputStreamWriter fileOutputStream;
try {
fileOutputStream = new OutputStreamWriter(new FileOutputStream(file, true), "UTF-8");
// 这里的true功能是不覆盖原有内容,所以多次运行程序会造成重复
// 将文章内容写入文件
fileOutputStream.write(Finacontent.toString());
fileOutputStream.close();//关闭流操作
System.out.println(filename + " 下载成功!");//提示成功
//弹出弹窗提示下载成功
Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle("提示");
alert.setContentText("下载成功!!");
alert.setHeaderText("文章已保存到"+"E:/FileTest目录下");
alert.showAndWait();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} }
}
@FXML
public void ClickToReset(MouseEvent event) {
AddData();//如果点击了返回按钮则重新将数据写入表格
}
@FXML
public void ClickToSelect(MouseEvent event) {
String prama = SelectFile.getText();//获取输入框输入输入的内容
String strMatch1 = "^\\d{1,6}$";//正则表达式匹配1-6位数字
Pattern pattern = Pattern.compile(strMatch1);//使用匹配规则
Matcher matcher = pattern.matcher(prama);//进行匹配
String regex = "[\\u4E00-\\u9FA5]"; //正则表达式匹配汉字
Matcher m = Pattern.compile(regex).matcher(prama);//使用匹配汉字规则进行匹配
if (matcher.find()==true) {//如果匹配数字成功则进行数据库查找(对文章日期进行查找)
cellData.removeAll(cellData);//清空原有的cellData里的数据
Connection conn = Connect.getConnection();//获取数据库连接
String sql = "select * from duzhefile where time like ?";//定义数据库查询语句
try {
// 执行查询语句
PreparedStatement prep = conn.prepareStatement(sql);
prep.setString(1, '%' + prama.replace(" ", "") + '%');//将输入的内容除去空格后绑定到数据库语句中
ResultSet res = prep.executeQuery();//执行数据库查询语句并将结果返回到ResultSet对象中
while (res.next()) {//如果结果有下一行
String name = res.getString("filename");
String path = res.getString("filepath");
cellData.add(0, new Data(name, path));//将查询到的文章名和文章地址插入cellData中
}
if (!res.absolute(1)) {//如果查询结果不存在第一行(即为空),则弹窗提示查找结果为空
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("提示");
alert.setContentText("请重新输入!");
alert.setHeaderText("查询结果为空!");
alert.showAndWait();
AddData();//将所有数据重新插入(因为查询的时候清空了)
}
} catch (SQLException e) {
e.printStackTrace();
}
FileName.setCellValueFactory(cellData -> cellData.getValue().getFilename());
FilePath.setCellValueFactory(cellData -> cellData.getValue().getFilepath());
FileTest.setItems(cellData);//将cellData绑定到表格
}
else if (m.find()) {//如果匹配汉字成功
cellData.removeAll(cellData);//清空原有的数据
Connection conn = Connect.getConnection();//获取数据库连接
String sql = "select * from duzhefile where filename like ?";//定义数据库查询语句
try {
// 执行查询语句
PreparedStatement prep = conn.prepareStatement(sql);
prep.setString(1, '%'+ prama.replace(" ", "")+'%');//去除空格后绑定参数
ResultSet res = prep.executeQuery();//执行查询语句并返回结果
while (res.next()) {//如果查询结果不为空
String name = res.getString("filename");
String path = res.getString("filepath");
cellData.add(0, new Data(name, path));//将查询到的数据写入cellData中 }
if (!res.absolute(1)) {//如果查询结果不存在第一行(为空),则弹窗提示查找结果为空
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("提示");
alert.setContentText("请重新输入!");
alert.setHeaderText("查询结果为空!");
alert.showAndWait();
AddData();//将所有数据重新插入(因为查询的时候清空了)
}
} catch (SQLException e) {
e.printStackTrace();
}
FileName.setCellValueFactory(cellData -> cellData.getValue().getFilename());
FilePath.setCellValueFactory(cellData -> cellData.getValue().getFilepath());
FileTest.setItems(cellData);//将cellData绑定到表格中
}
else if(prama.length()==0){//如果输入的内容为空(即没有输入)则弹窗提示重新输入
AddData();
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("提示");
alert.setContentText("请重新输入!");
alert.setHeaderText("您输入的信息有误!\n输入文件名、年份、月份均可查找");
alert.showAndWait();
}
} private Main main;
public void setMain(Main main) {
this.main = main;
} @Override
public void initialize(URL location, ResourceBundle resources) {
AddData();//加载页面时写入数据
} private void AddData() {//将数据库查询结果写入cellData中,封装成方法方便多次调用
Connection conn = Connect.getConnection();
String Strsql = "select * from duzhefile";
try {
// 执行查询语句
PreparedStatement prep = conn.prepareStatement(Strsql);
ResultSet res = prep.executeQuery();
while (res.next()) {
String name = res.getString("filename");
String path = res.getString("filepath");
cellData.add(0, new Data(name,path)); }
} catch (SQLException e) {
e.printStackTrace();
}
FileName.setCellValueFactory(cellData -> cellData.getValue().getFilename());
FilePath.setCellValueFactory(cellData -> cellData.getValue().getFilepath());
FileTest.setItems(cellData);
} }

用到的Data类如下:

Data.java

 package All;

 import javafx.beans.property.SimpleStringProperty;

 public class Data {
private SimpleStringProperty filename;
private SimpleStringProperty filepath; public Data(String name,String path) {
this.filename = new SimpleStringProperty(name);
this.filepath = new SimpleStringProperty(path);
} public SimpleStringProperty getFilename() {
return filename;
} public void setFilename(String filename) {
this.filename = new SimpleStringProperty(filename);
} public SimpleStringProperty getFilepath() {
return filepath;
} public void setFilepath(String filepath1) {
this.filepath = new SimpleStringProperty(filepath1);
}
}

数据库连接类如下:

Connect.java

package All;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties; public class Connect { // 连接数据库url
static String url;
// 创建Properties对象
static Properties info = new Properties(); // 驱动程序加载
static {
// 获得属性文件输入流
InputStream input = Connect.class.getResourceAsStream("config.properties"); try {
// 加载属性文件内容到Properties对象
info.load(input);
// 从属性文件中取出url
url = info.getProperty("url");
// 从属性文件中取出driver
String driverClassName = info.getProperty("driver");
Class.forName(driverClassName);
System.out.println("驱动程序加载成功..."); } catch (ClassNotFoundException e) {
System.out.println("驱动程序加载失败...");
} catch (IOException e) {
System.out.println("加载属性文件失败...");
}
}
// 获得数据库连接
public static Connection getConnection() {
// 创建数据库连接
Connection conn = null;
try {
conn = DriverManager.getConnection(url, info);
System.out.println("数据库连接成功!");
} catch (SQLException e) {
System.out.println("数据库连接失败!");
System.out.println(url);
System.out.println(info);
} return conn;
}
}

最后主类如下:

Main.java

package All;

import java.io.IOException;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage; public class Main extends Application{
private Stage primaryStage;
@Override
public void start(Stage primaryStage){
this.primaryStage = primaryStage;
try {
FirstPage();
} catch (IOException e) {
e.printStackTrace();
}
} public void FirstPage() throws IOException {
FXMLLoader loder = new FXMLLoader(Main.class.getResource("FirstPage.fxml"));
AnchorPane root = loder.load();
Scene scene = new Scene(root);
FirstPageController controller = loder.getController();
controller.setMain(this);
primaryStage.setTitle("读者文摘");
primaryStage.setScene(scene);
primaryStage.show(); }
public static void main(String[] args) {
launch(args);
}
}

最后实现的效果如下:

至此,所有功能实现。

总结:

用到了Jsoup的知识爬取网页源代码,

用到了正则表达式进行数据匹配

用到了JDBC进行数据库连接并进行数据查找

用到了javafx内的TableView绑定数据操作

用到了流操作进行数据写入文件

重温了File类文件及文件夹的创建

重温了Alter弹窗

javafx实现读者文摘上的文章预览及下载的更多相关文章

  1. servlet实现文件上传,预览,下载和删除

      一.准备工作 1.1 文件上传插件:uploadify: 1.2 文件上传所需jar包:commons-fileupload-1.3.1.jar和commons-io-2.2.jar 1.3 将数 ...

  2. web端文件上传,预览,下载,删除

      //HTML部分 <div class="item attachment attachmentNew"> <span class="name&quo ...

  3. bbs项目引入富文本编辑器和处理xss攻击和文章预览

    一.富文本编辑上传文章和图片 富文本编辑器我们使用kindeditor,我们首先去官网下载,然后解压,放到我们的static的目录中 然后我们在html中这样使用富文本编辑器 <!DOCTYPE ...

  4. github 上如何直接预览仓库中的html,搭建自己的主页

    前言:最近在写vue+element ui 的一些demo,就在github上建了个仓库来管理,但是希望能直接在github上就能预览效果,所以才有了这篇文章.转载请注明出处:https://www. ...

  5. PHP如何生成文章预览图

    PHP如何生成文章预览图 一.总结 一句话总结:php的wkhtmltox扩展,php官方文档有怎么使用,或者github,或者百度,等等等等 wkhtmltox 1.PHP如何自动生成文章预览图? ...

  6. hTML5实现表单内的上传文件框,上传前预览图片,针刷新预览images

    hTML5实现表单内的上传文件框,上传前预览图片,针刷新预览images, 本例子主要是使用HTML5 的File API,建立一個可存取到该file的url, 一个空的img标签,ID为img0,把 ...

  7. html之file标签 --- 图片上传前预览 -- FileReader

    记得以前做网站时,曾经需要实现一个图片上传到服务器前,先预览的功能.当时用html的<input type="file"/>标签一直实现不了,最后舍弃了这个标签,使用了 ...

  8. 【转】HTML5 jQuery图片上传前预览

    hTML5实现表单内的上传文件框,上传前预览图片,针刷新预览images,本例子主要是使用HTML5 的File API,建立一個可存取到该 file的url,一个空的img标签,ID为img0,把选 ...

  9. ASP.NET MVC图片上传前预览

    回老家过春节,大半个月,在家的日子里,吃好睡好,人也长了3.5Kg.没有电脑,没有网络,无需写代码,工作上相关的完全放下......开心与父母妻儿过个年,那样的生活令Insus.NET现在还在留恋.. ...

随机推荐

  1. java虚拟机规范(se8)——java虚拟机的编译(四)

    3.12 抛出和处理异常 在程序中使用throw关键字来抛出异常.编译结果很简单. void cantBeZero(int i) throws TestExc { if (i == 0) { thro ...

  2. java synchronized的四种用法

    一 修饰方法 Synchronized修饰一个方法很简单,就是在方法的前面加synchronized,synchronized修饰方法和修饰一个代码块类似,只是作用范围不一样,修饰代码块是大括号括起来 ...

  3. Linux操作练习

    打印显示当前时间,格式是:20181209211008 [root@Centos7 ~]#date "+%Y%m%d%H%M%S" 实现晚上20:30自动关机 [root@Cent ...

  4. mysql---级联更新和删除操作

    我们通常有这样的需求:删除表Table 1中记录,需要同时删除其它表中与Table 1有关的若干记录. 对于这种,我们有两种解决方法: 一,使用innodb表的外键约束 ALTER TABLE `sc ...

  5. 一、创建且运行JPA工程

    1. 创建JPA 工程 (1)选择创建 JPA Project,注意不是Java Project (2)JPA version选择 2.0 (3)选择用户库,否则会出现 At least one us ...

  6. 力扣 ——Remove Duplicates from Sorted List II(删除排序链表中的重复元素 II)python实现

    题目描述: 中文: 给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字. 示例 1: 输入: 1->2->3->3->4->4-> ...

  7. Spring data jpa persistence .xml 配置文件

    <?xml version="1.0" encoding="UTF-8"?><persistence xmlns="http://j ...

  8. 【IP】DHCP介绍

    DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)是一个局域网的网络协议,使用UDP协议工作, 主要有两个用途:给内部网络或网络服务供应商自动分配IP ...

  9. CSS 布局 - Overflow

    CSS 布局 - Overflow CSS overflow 属性用于控制内容溢出元素框时显示的方式. 这里的文本内容是可以滚动的,滚动条方向是垂直方向.dd马达价格 这里的文本内容是可以滚动的,滚动 ...

  10. win10 解决telnet不是内部或外部命令的方案

    1.Telnet用于远程操作互联网中的设备或终端计算机服务器,可以有效的减少现场操作的麻烦.因为设备或终端是遍布整个省或市,有的甚至是国外,如何高效的处理问题是当务之急,除了telnet还可以ssh使 ...