上傳圖片後自動生成 120x120 等比例縮圖,無需第三方庫,使用 javax.imageio 與 java.awt.geom.AffineTransform:
public static void createPreviewImage(String srcFile, String destFile) {
final int IMAGE_SIZE = 120;
try {
File src = new File(srcFile);
File dest = new File(destFile);
BufferedImage srcImg = ImageIO.read(src);
int w = srcImg.getWidth(), h = srcImg.getHeight();
double scale = (double) w / h;
int nw = IMAGE_SIZE, nh = (nw * h) / w;
if (nh > IMAGE_SIZE) { nh = IMAGE_SIZE; nw = (nh * w) / h; }
double sx = (double) nw / w, sy = (double) nh / h;
AffineTransform transform = new AffineTransform();
transform.setToScale(sx, sy);
AffineTransformOp op = new AffineTransformOp(transform, null);
BufferedImage thumb = new BufferedImage(nw, nh, BufferedImage.TYPE_3BYTE_BGR);
op.filter(srcImg, thumb);
ImageIO.write(thumb, "jpeg", dest);
} catch (Exception e) {
throw new RuntimeException("Failed to create preview image: " + e.getMessage(), e);
}
}
下載 rsslibj-1_0RC2.jar 與 exml.jar 放入 WEB-INF/lib。動態生成 RSS 2.0 XML:
Channel channel = new Channel();
channel.setDescription(account.getDescription());
channel.setLink("https://server/home.c?accountId=" + accountId);
channel.setTitle(account.getTitle());
List articles = facade.getArticles(accountId, account.getMaxPerPage(), 1);
for (Article article : articles) {
channel.addItem(
"https://server/article.c?articleId=" + article.getArticleId(),
article.getSummary(),
article.getTitle()
);
}
response.setContentType("text/xml");
PrintWriter pw = response.getWriter();
pw.print(channel.getFeed("rss"));
pw.close();
關係型資料庫 LIKE '%kw%' 全表掃描效能極差。採用純 Java 開源 Lucene 建立倒排索引,毫秒級搜尋。
Document:索引/搜尋結果單元Field:文件欄位(Keyword 不分詞、Text 分詞)IndexWriter:建立/更新索引Analyzer:分詞器(中文需 ChineseAnalyzer 或 IKAnalyzer)Query / QueryParser:查詢解析Searcher / Hits:執行搜尋與結果遍歷// 建立索引目錄
String indexDir = "C:/search/blog";
IndexWriter writer = new IndexWriter(indexDir, new StandardAnalyzer(), true);
writer.close();
// 新增文章索引
writer = new IndexWriter(indexDir, new StandardAnalyzer(), false);
Document doc = new Document();
doc.add(Field.Keyword("title", title));
doc.add(Field.Text("content", content));
writer.addDocument(doc);
writer.close();
// 搜尋
Searcher searcher = new IndexSearcher(indexDir);
Query query = QueryParser.parse(keyword, "content", new StandardAnalyzer());
Hits hits = searcher.search(query);
for (int i = 0; i < hits.length(); i++) {
Document d = hits.doc(i);
System.out.println("Found: " + d.get("title"));
}
searcher.close();
封裝 LuceneSearcher 類,索引目錄置於 /WEB-INF/search/ 保護存取,配置檔初始化路徑。
避免依賴外部 SMTP 伺服器,手寫 SendMail 組件直連收件方郵件伺服器(需配置 DNS IP)。採用緩衝隊列 + 多執行緒後台發送,不阻塞 Web 請求。詳細代碼見 SendMail.java。
web.xml 配置 EncodingFilter 強制 gb2312,批次替換所有 .html/.properties 中的 iso-8859-1。Lucene 需替換支援中文的 Analyzer。Spring 強大的整合與配置能力,讓我們輕鬆構建靈活多層 J2EE 應用,無需複雜 EJB 元件支撐。