前几天发布的《基于模版的内容网站开发》在RepeatFile.java存在一些问题,进行了修改。另外加了一个Paper类,用于与数据库数据进行交互。此外刚还加了个summary字符,用于存储文章的概要,现修改如下:
对于内容网站形成于上个世纪九十年代,Web1.0时代开发的网站大多数都是基于内容网站,比如新闻类。开发这类的网站可以采用ASP、JSP、PHP技术,但是基于这类开发出来的网站,内容都是在阅读的时候实时的从数据库中读取的,对于搜索引擎网站,比如百度、Google的排行榜上排名往往很低,只有做成静态的HTML,才可以被搜索引擎加大排名。本文以一个内容发布网站来介绍基于模版的内容网站开发。
1.建立数据库
create database sec;
use sec
create table paper(
id INT NOT NULL AUTO_INCREMENT,
title VARCHAR(200) NOT NULL,
summary VARCHAR(2000) NOT NULL,
content TEXT NOT NULL,
PRIMARY KEY (id)
)AUTO_INCREMENT = 71;
由于系统改造,以前的文章不收入现有数据库,所以编号从71开始。
2.建立后台数据收集系统
用Tomcat + jsp开发
输入页面:index.html
<!DOCTYPE HTML>
<html>
<head>
<title>文件输入</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<form action="index.jsp" method="post" >
<p>课程标题:<br><input type="text" name="title" size="100" maxlength="200"></p>
<p>课程概要:<br><textarea id="summary" name="summary" rows="20" cols="100">
课程适合人群:
本课程重点解答&解决:
本课程亮点+核心价值介绍:
课长:
</textarea></p>
<p>课程内容:<br><textarea id="content" name="content" rows="30" cols="100">
</textarea></p>
<p><input type="submit" value="提交"></p>
</form>
<body>
<body
将内容存储到数据库中
index.jsp
<%@ page contentType="text/html; charset=utf-8" %>
<%@ page language="java" %>
<%@ page import="java.sql.*" %>
<%@ page import="com.jerry.MySQLAccess" %>
<%@ page import="com.jerry.Paper" %>
<%
//设置字体
request.setCharacterEncoding("UTF-8");
//获取标题
String title = request.getParameter("title");
//获取概要
String summary = request.getParameter("summary");
//获取内容
String content = request.getParameter("content");
//建立Paper对象
Paper paper = new Paper();
paper.SetTitle(title);
paper.SetSummary(summary);
paper.SetContent(content);
//建立MySQLAccess对象
MySQLAccess mysql = new MySQLAccess();
try {
//建立数据库连接
Connection conn = mysql.connect();
//插入数据库
mysql.insert(conn, paper);
//断开链接
mysql.disconnect(conn);
} catch (SQLException e1) {
e1.printStackTrace();
}
%>
<!DOCTYPE HTML>
<html>
<head>
<title>文件输入</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
输入成功
</body>
</html>
改用Paper类存储
3. Bean端开发
MySQLAccess对象通过Eclipse开发
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jerry</groupId>
<artifactId>MySQL</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>9.0.0</version>
</dependency>
</dependencies>
</project>
版本用最新的9.0.0,由于下载速度很慢,可以通过浏览器从https://repo.maven.apache.org/maven2/下载,下载完毕放在.m2的相应目录下。
准备Paper.java用于与数据库交互
package com.jerry;
public class Paper {
int id;
String title;
String summary;
String content;
public int GetId(){
return this.id;
}
public String GetTitle(){
return this.title;
}
public String GetSummary(){
return this.summary;
}
public String GetContent(){
return this.content;
}
public void SetId(int id){
this.id=id;
}
public void SetTitle(String title){
this.title=title;
}
public void SetSummary(String summary){
this.summary=summary;
}
public void SetContent(String content){
this.content=content;
}
}
MySQLAccess .java
package com.jerry;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class MySQLAccess {
private static final String url = "jdbc:mysql://localhost:3306/sec";
private static final String user = "root";
private static final String password = "123456";
private static Statement stmt = null;
private static ResultSet rs;
//建立链接
public Connection connect() throws SQLException {
try {
//新版本改为"com.mysql.cj.jdbc.Driver"
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection(url, user, password);
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
return conn;
} catch (ClassNotFoundException e) {
System.out.println("JDBC 驱动未找到: " + e.getMessage());
} catch (SQLException e) {
System.out.println("数据库连接失败: " + e.getMessage());
}
return null;
}
//断开连接
public void disconnect(Connection conn) {
try {
if (rs != null) {
rs.close();
}
stmt.close();
conn.close();
}catch (Exception e) {
e.printStackTrace();
}
}
//插入数据
public boolean insert(Connection conn,Paper paper) throws SQLException {
String insertString = "INSERT INTO paper (title, summary, content) VALUES (?, ?, ?);";
try {
PreparedStatement pstmt= conn.prepareStatement(insertString);
// 设置参数
pstmt.setString(1, paper.GetTitle());
pstmt.setString(2, paper.GetSummary());
pstmt.setString(3, paper.GetContent());
// 执行插入操作
int affectedRows = pstmt.executeUpdate();
if (affectedRows == 1) {
return true;
}else {
return false;
}
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
//查询数据
public Paper[] query(String Query) throws SQLException {
ResultSet rs = stmt.executeQuery(Query);
int number=0;
while (rs.next()) {
number++;
}
rs.beforeFirst();
Paper[] paper = new Paper[number];
int i=0;
while (rs.next()) {
paper[i] = new Paper();
paper[i].SetId(rs.getInt("id"));
paper[i].SetTitle(rs.getString("title"));
paper[i].SetSummary(rs.getString("Summary"));
paper[i].SetContent(rs.getString("content"));
i++;
}
return paper;
}
//打印查询数据
public void print(Paper[] paper) throws SQLException {
int length = paper.length;
for (int i=0;i
System.out.print("Id:"+paper[i].GetId());
System.out.print("Title:"+paper[i].GetTitle());
System.out.print("Summary:"+paper[i].GetSummary());
System.out.println("Content:"+paper[i].GetContent());
}
}
}
由于包名为"com.jerry",在Tomcat使用,将MySQLAccess.class放在%TOMECAT_HOME%\webapps\sec\WEB-INF\classes\com\jerry目录下。
4.开发模版替换程序
准备模版文件:
把这些文件放在项目主目录.\source\下
RepeatFile.java
package com.jerry;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.FileWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RepeatFile {
private static FileInputStream fileInputStream = null;
private static InputStreamReader inputStreamReader = null;
//获取模版文件
public BufferedReader getFile(String myFile) {
try {
File file = new File(myFile);
fileInputStream = new FileInputStream(file);
inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
return bufferedReader;
} catch (FileNotFoundException e) {
System.out.println("文件未找到: " + e.getMessage());
}
return null;
}
//读取模版文件
public void readFile(BufferedReader bufferedReader) throws IOException {
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
}
//关闭模版文件
public void closeFile(BufferedReader bufferedReader) throws IOException {
bufferedReader.close();
inputStreamReader.close();
fileInputStream.close();
}
//替换HTML特殊字符,也为了防止XSS注入
public String repleatHTML(String sourceString) {
sourceString = sourceString.replaceAll("<", "<");
sourceString = sourceString.replaceAll(">", ">");
sourceString = sourceString.replaceAll(" ", " ");
sourceString = sourceString.replaceAll("\t", " ");
sourceString = sourceString.replaceAll("\n", "<br>");
sourceString = sourceString.replaceAll("\"", """);
sourceString = sourceString.replaceAll("’", "'");
return sourceString;
}
//替换概要信息
public String repleatSummary(String sourceString) {
sourceString = "<li>"+sourceString+"</li>";
sourceString = sourceString.replaceAll("<br>", "</li><br><li>");
sourceString = sourceString.replaceAll("<li> </li>","");
sourceString = sourceString.replaceAll("</li><br><li>","</li><li>");
sourceString = sourceString.replaceAll("</li><br>","</li>");
sourceString = sourceString.replaceAll("<p></p>","");
sourceString = sourceString.replaceAll("</b><br>","</b>");
String[] regex = new String[4];
regex[0] = "课程适合人群:";
regex[1] = "本课程重点解答&解决:";
regex[2] = "本课程亮点\\+核心价值介绍:";
regex[3] = "课长:";
for (int i=0;i<4;i++) {
sourceString = convertLiToBold(regex[i],sourceString);
}
return sourceString;
}
public static String convertLiToBold(String replearChar,String input) {
// 使用正则表达式匹配特定的 <li> 内容并替换
Pattern pattern = Pattern.compile("<li>"+replearChar+".*?</li>", Pattern.DOTALL);
Matcher matcher = pattern.matcher(input);
StringBuilder result = new StringBuilder();
int lastEnd = 0;
while (matcher.find()) {
// 将匹配前的内容添加到结果中
result.append(input, lastEnd, matcher.start());
// 获取匹配的内容
String matched = matcher.group();
// 替换 <li> 和 </li> 标签
String replaced = matched.replaceAll("<li>", "<b>")
.replaceAll("</li>", "</b>")
.replaceAll("\\s+", " ")
.trim();
// 将替换后的内容添加到结果中
result.append(replaced);
lastEnd = matcher.end();
}
// 添加最后一个匹配后的内容
result.append(input, lastEnd, input.length());
return result.toString();
}
//从数据库中获取数据
public Paper[] getDataFromDB() throws IOException {
Paper[] paper=null;
try {
MySQLAccess mysql = new MySQLAccess();
//SQL查询语句
String Query = "select id,title,Summary,content from paper";
//查询结果
paper=mysql.query(Query);
}catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return paper;
}
//根据文件名把文件分为非内容文件(一般文件)和内容文件
public String[][] putRecordInVar(String File,Paper[] paper) {
int number = paper.length;
//初始化将查询记录放入字符串数组
String[][] var = new String[number][4];
for (int i=0;i<number;i++) {
//将查询记录放入字符串数组内
String id = paper[i].GetId()+"";
var[i][0] = (id);
var[i][1] = repleatHTML(paper[i].GetTitle());
var[i][2] = repleatHTML(paper[i].GetSummary());
var[i][2] = repleatSummary(var[i][2]);
var[i][3] = repleatHTML(paper[i].GetContent());
}
return var;
}
//根据文件名把文件分为非内容文件(一般文件)和内容文件
public void classificationFile(String File,Paper[] paper,String[][] var) {
if ((File.equals("index_web.html"))||(File.equals("index_phone.html"))||(File.equals("class_web.html"))||(File.equals("class_phone.html"))) {
getTargetFileForNormalFile(File,paper,var);
}else if ((File.equals("content_web.html"))||(File.equals("content_phone.html"))) {
getTargetFileForContentFile(File,paper,var);
}
}
//获得普通文件的目标文件名
public void getTargetFileForNormalFile(String File,Paper[] paper,String[][] var) {
//替换后的目标文件
String destFile="";
//标题替换后的字符串
String replaceTitle = "";
int lenth = paper.length;
for (int i=0;i<lenth;i++) {
switch(File) {
case("index_web.html"):{
destFile = ".\\web\\index.html";
replaceTitle += "<a href=\"class/c"+var[i][0]+".html\"target=\"_blank\">《"+var[i][1]+"》</a>";
break;
}
case("index_phone.html"):{
destFile = ".\\phone\\index.html";
replaceTitle += "<a href=\"class/c"+var[i][0]+".html\">《"+var[i][1]+"》</a><br>";
break;
}
case("class_web.html"):{
destFile = ".\\web\\class.html";
replaceTitle += "<li><a href=\"../class/c"+var[i][0]+".html\" target=\"_blank\">《"+var[i][1]+"》;</a></li>";
break;
}
case("class_phone.html"):
{
destFile = ".\\phone\\class.html";
replaceTitle += "<li><a href=\"class/c"+var[i][0]+".html\">《"+var[i][1]+"》</a></li>";
break;
}default:
System.out.println("普通文件名不对");
}
}
replaceFile(File,destFile,replaceTitle,"","");
}
public void getTargetFileForContentFile(String File,Paper[] paper,String[][] var) {
//替换后的目标文件
String destFile="";
//标题替换后的字符串
String replaceTitle = "";
//概要替换后的字符串
String replaceSummary = "";
//内容替换后的字符串
String replaceContent = "";
int lenth = paper.length;
for (int i=0;i<lenth;i++) {
switch(File) {
case("content_web.html"):{
destFile = ".\\web\\c"+var[i][0]+".html";
break;
}
case("content_phone.html"):{
destFile = ".\\phone\\c"+var[i][0]+".html";
break;
}default:
System.out.println("普通文件名不对");
}
replaceTitle = var[i][1];
replaceSummary = var[i][2];
replaceContent = var[i][3];
replaceFile(File,destFile,replaceTitle,replaceSummary,replaceContent);
}
}
public void replaceFile(String File,String destFile,String replaceTitle,String replaceSummary,String replaceContent) {
File = ".\\source\\"+File;
//获取模本文件的bufferedReader
BufferedReader bufferedReader= getFile(File);
//替换结果文件放入result,进行叠加
String result="";
String line="";
try {
while ((line = bufferedReader.readLine()) != null) {
if ((line.equals("课程适合人群:"))||line.equals("本课程重点解答&解决:")||line.equals("本课程亮点+核心价值介绍:")||line.equals("课长:")) {
line ="<b>"+line+"</b>";
}
//将当前读取行的最后加上回车
line = line+"\n";
//标题的替换标识符
String regex1 = "###1";
//概要的替换标识符
String regex2 = "###2";
//内容的替换标识符
String regex3 = "###3";
//进行正则替换标题
line = line.replaceAll(regex1, replaceTitle);
//进行正则替换概要
line = line.replaceAll(regex2, replaceSummary);
//进行正则替换内容
result = result+line.replaceAll(regex3, replaceContent);
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//将替换后的内容写入目标文件
//打开目标文件
try (FileWriter writer = new FileWriter(destFile)) {
//写入目标文件
writer.write(result);
//关闭目标文件
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
//关闭模本文件
try {
closeFile(bufferedReader);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//处理文件
public void dealFile(String File) throws IOException {
//从数据库中获取数据
Paper[] paper = getDataFromDB();
//把记录放入单个数组中
String[][] var = putRecordInVar(File,paper);
//根据文件名把文件分为非内容文件(一般文件)和内容文件
classificationFile(File,paper,var);
}
//主函数
public static void main(String[] args) throws SQLException {
try {
//建立MySQLAccess对象变量
MySQLAccess mysql = new MySQLAccess();
//建立RepeatFile()对象变量
RepeatFile rf = new RepeatFile();
//建立数据库连接
Connection conn = mysql.connect();
//将要处理的模版文件名放在字符串数组内
String[] Files= {"index_web.html","index_phone.html","class_web.html","class_phone.html","content_web.html","content_phone.html"};
//遍历要处理的模版文件名的字符串数组
for (int i = 0; i < Files.length; i++) {
//处理文件
rf.dealFile(Files[i]);
}
//断开链接
mysql.disconnect(conn);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("生成成功");
}
}
现在数据库中有两条数据
模版文件
某个模版文件中的替换标识
…
<li><a href="../class/c63.html" target="_blank">《探索式软件测试》</a></li>
<li><a href="../class/c66.html" target="_blank">《JMeter从入门到精通》</a></li>
<li><a href="../class/c33.html" target="_blank">《APP软件专项测试》</a></li>
###1
…
形成的Web文件
形成的手机文件