1. 確定Web Container支持Serverlet2.4, 復(fù)制支持jstl 1.1版本的jstl.jar,standard.jar(可查閱meta-inf)到web-inf/lib。
2. 在Web.xml,Root節(jié)點改為
<web-app version="2.4" 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-app_2_4.xsd ">
3.在jsp中,對core,ftm taglib的引入改為
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"% >
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"% >
充分使用JSP2.0的EL,直接在html中寫${book} 而不是<c:out value="${book}">將獲得簡潔無比,可比美velocity,freemarker的界面。
Function標(biāo)簽里最有用的一項是取得List,Map的size了。另外有一些StringUtils和Collection的函數(shù)。
JSTL里面不給調(diào)用對象除getXXX()外的任何方法真是件很讓讓人郁悶的事情!!
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
${fn:length(myList)}
除了最基本的算術(shù)運算符,邏輯運算符,比較運算符外,還有一個empty運算符,用來判斷變量是否為null 或list, map的size 是否為零。
<c:if test="${not empty myList}">
EL的運算符都有文字和符號兩種版本,如|| 和 or, >= 和 ge,適用于不能使用文字或符號的時候。
${book.name}與${book["name"]}等價。
${book["name"]}主要用于"name"串為變量,或者字符串中含有"."字符的情況
如 ${myMap[order.status]} 是訪問Map元素的一種很重要的方式。
orderList[0] 返回第一個元素
用key和value遍歷map
<c:forEach var="entry" items="${myMap}">
<option value="${entry.key}">${entry.value}</option> </c:forEach>
EL本身不支持靜態(tài)變量訪問,變通的方法是寫一個tag,將某個類的靜態(tài)變量反射到一個map中, 如http://www.javaranch.com/journal/200601/Journal200601.jsp#a3
不過使用Map將失去靜態(tài)變量編譯期安全的意義,因此還是建議在這種情況下,使用普通JSP,見showOrder.jsp
?
自己的第一個項目IQBoree
里面要求有提供給客戶Rss訂閱的功能,找了下網(wǎng)上介紹,最后還是在rome的管網(wǎng)找到了解決方案
解決方案有兩種:
1,寫一個servlet,生成feed,直接由客戶來訂閱
2,寫一個java.自動生成feed的xml文件,然后讓客戶通過讀取這個xml文件來達(dá)到訂閱Rss的目的
首先我就來講解下第一種方法:
1.
FeedServlet.java
package com.iqboree.rss.servlet;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.iqboree.po.Article;
import com.iqboree.service.impl.ArticleManagerImpl;
import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndEntryImpl;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndFeedImpl;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedOutput;
/**
* @author Michael
*
*/
public class FeedServlet extends HttpServlet {
?
?private static final Log log = LogFactory.getLog(FeedServlet.class);?
??? private static final String DEFAULT_FEED_TYPE = "default.feed.type";
??? private static final String FEED_TYPE = "type";
??? private static final String MIME_TYPE = "application/xml; charset=UTF-8";
??? private static final String COULD_NOT_GENERATE_FEED_ERROR = "Could not generate feed";
??? private static final DateFormat DATE_PARSER = new SimpleDateFormat("yyyy-MM-dd");
??? private String _defaultFeedType;
???
??? List list;
??? public void init() {
??????? _defaultFeedType = getServletConfig().getInitParameter(DEFAULT_FEED_TYPE);
??????? _defaultFeedType = (_defaultFeedType!=null) ? _defaultFeedType : "atom_0.3";
?????? log.info("初始化完成");//用來調(diào)試,可以看出在tomcat里的輸出信息,自己可以去掉,后面的log.info()?也是同樣的效果.
???????DATE_PARSER.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));//這里用來設(shè)置時區(qū)
???
??? }
??? public void doGet(HttpServletRequest req,HttpServletResponse res) throws IOException {
??????? try {
??????? ?log.info("doget方法完成");
??????????? SyndFeed feed = getFeed(req);
??????????? String feedType = req.getParameter(FEED_TYPE);
??????????? feedType = (feedType!=null) ? feedType : _defaultFeedType;
??????????? feed.setFeedType(feedType);
??????????? res.setContentType(MIME_TYPE);
??????????? SyndFeedOutput output = new SyndFeedOutput();
??????????? output.output(feed,res.getWriter());
??????? }
??????? catch (FeedException ex) {
??????????? String msg = COULD_NOT_GENERATE_FEED_ERROR;
??????????? log(msg,ex);
??????????? res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,msg);
??????? }
??? }
??? protected SyndFeed getFeed(HttpServletRequest req) throws IOException,FeedException {
??? ?log.info("Synd方法開始");
??? ?
??????? SyndFeed feed = new SyndFeedImpl();
??????? feed.setTitle("Sample Feed (created with ROME)");//channle name ;display as the title
??????? feed.setLink("http://rome.dev.java.net");
??????? feed.setDescription("This feed has been created using ROME (Java syndication utilities");
???????
??????? List entries = new ArrayList();
??????? SyndEntry entry;
??????? SyndContent description;
???????
??????? List list = new ArrayList();
??????//項目是基于spring+webwork+hibernate的,但是在這里不知道讓為這個servlet自動獲得對應(yīng)的DAO,所以只能用jdbc手動獲取
??????? String sql = "";
??????? try {
??????? ?log.info("開始進(jìn)行jdbc操作");
???Class.forName("com.mysql.jdbc.Driver");
???String url="jdbc:mysql://localhost:3306/iqboree";
???Connection conn = DriverManager.getConnection(url,"root","ahuango");
???if(conn == null)
???{
????log.info("conn NULL");
???}
???Statement stmt = conn.createStatement();
???if(stmt==null)
???{
????log.info("NULLNULLNULL");
???}
???log.info("開始進(jìn)行sql操作");
???sql = "Select id,AddedDate,AddedBy,Title,Abstract,Body,CommentsEnabled,ViewCount," +
?????"ReleaseDate,ExpireDate,Approved,Listed,OnlyForMembers,Category_ID from iq_article";
???ResultSet rs = stmt.executeQuery(sql);
???log.info("begin iterator resultSet");
???while(rs.next())
???{
????log.info("test 1");
????Article art = new Article();
????art.setId(Long.valueOf(rs.getString(1)));
????log.info("test 2");
????art.setAddedDate(rs.getDate(2));
????log.info("test 3");
????art.setAddedBy(rs.getString(3));
????log.info("test 4");
????art.setTitle(rs.getString(4));
????log.info("test 5");
????art.setAbstracts(rs.getString(5));
????log.info("test 6");
????art.setBody(rs.getString(6));
????log.info("test 7");
????art.setCommentsEnabled(Boolean.valueOf(rs.getBoolean(7)));
????log.info("test 8");
????art.setViewCount(Integer.valueOf(rs.getString(8)));
????log.info("test 9");
????art.setReleaseDate(rs.getDate(9));
????log.info("test 10");
????art.setExpireDate(rs.getDate(10));
????log.info("test 11");
????art.setApproved(Boolean.valueOf(rs.getBoolean(11)));
????log.info("test 12");
????art.setListed(Boolean.valueOf(rs.getBoolean(12)));
????log.info("test 13");
????art.setOnlyForMembers(Boolean.valueOf(rs.getBoolean(13)));
????log.info("test 14");
//????art.getCategory().setId(Long.valueOf(rs.getString(14)));
????log.info("test 15");
????
????list.add(art);
???}??
???stmt.close();
???conn.close();
???
??} catch (ClassNotFoundException e) {
???// TODO Auto-generated catch block
???e.printStackTrace();
??}catch(Exception e)
??{
???log.error("sql:"+sql+"?????? "+e.toString());
??}
//數(shù)據(jù)庫信息獲取完畢,里面的信息大家根據(jù)實際需要自己更改.
??????? log.info("開始獲取db");
??????? //List articles=new ArticleManagerImpl().getCurrentNArticles(2);
??????? log.info("開始迭代");
??????
???????
??????? Iterator its = list.iterator();
??????? log.info("開始添加feed條目");
??????? while(its.hasNext())
??????? {
??????? ?Article art=(Article)its.next();
??????? ?log.info("在while內(nèi)部");
??????? entry = new SyndEntryImpl();
??????? entry.setTitle("\""+art.getTitle()+"\"");
??????? entry.setLink("Link is:"+art.getId()+"\"");
??????? try {
??????????? entry.setPublishedDate(DATE_PARSER.parse("2004-06-08"));
??????? }
??????? catch (ParseException ex) {
??????????? // IT CANNOT HAPPEN WITH THIS SAMPLE
??????? }
??????? description = new SyndContentImpl();
??????? description.setType("text/plain");
??????? description.setValue("The value is here:"+art.getTitle()); //set the content of this feed
??????? entry.setDescription(description);
??????? entries.add(entry);
??????? }
?
??????? feed.setEntries(entries);
??????? return feed;
??? }
}
然后在web.xml中配置這個Rss的訂閱地址
The web.xml:
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
??? <display-name>ROME Samples</display-name>
??? <servlet>
??????? <servlet-name>FeedServlet</servlet-name>
??????? <servlet-class>com.sun.syndication.samples.servlet.FeedServlet</servlet-class>
??????? <init-param>
??????????? <param-name>default.feed.type</param-name>
??????????? <param-value>rss_2.0</param-value>
??????? </init-param>
??? </servlet>
??? <servlet-mapping>
???????? <servlet-name>FeedServlet</servlet-name>
???????? <url-pattern>/feed</url-pattern>
ervlet-mapping>
</web-app>
我的項目名稱為IQBoree,所以這個feed相應(yīng)的訂閱地址為:http://localhost:8080/IQBoree/feed
2,自己生成一個xml文件,然后讓客戶來讀取這個xml文件
生成xml文件:
if (true) {
??????????? try {
??????????????? String feedType = "rss_1.0";
??????????????? String fileName = "rssTest2.xml";
??????????????? DateFormat dateParser = new SimpleDateFormat(DATE_FORMAT);
??????????????? SyndFeed feed = new SyndFeedImpl();
??????????????? feed.setFeedType(feedType);
??????????????? feed.setTitle("Sample Feed (created with Rome)");
??????????????? feed.setLink("??????????????? feed.setDescription("This feed has been created using Rome (Java syndication utilities");
??????????????? List entries = new ArrayList();
??????????????? SyndEntry entry;
??????????????? SyndContent description;
??????????????? entry = new SyndEntryImpl();
??????????????? entry.setTitle("Rome v1.0");
??????????????? entry.setLink("??????????????? entry.setPublishedDate(dateParser.parse("2006-11-16"));
??????????????? description = new SyndContentImpl();
??????????????? description.setType("text/plain");
??????????????? description.setValue("Initial release of Rome");
??????????????? entry.setDescription(description);
??????????????? entries.add(entry);
//以上九行可以用來添加一條feed,可以更具自己的需要多添加幾個,或者和第一種生成servlet的方法一樣來從數(shù)據(jù)庫讀取
??????????????? feed.setEntries(entries);
??????????????? Writer writer = new FileWriter(fileName);
??????????????? SyndFeedOutput output = new SyndFeedOutput();
??????????????? output.output(feed,writer);
??????????????? writer.close();
??????????????? System.out.println("The feed has been written to the file ["+fileName+"]");
??????????????? ok = true;
??????????? }
??????????? catch (Exception ex) {
??????????????? ex.printStackTrace();
??????????????? System.out.println("ERROR: "+ex.getMessage());
??????????? }
??????? }
使用rom讀取rssUrl
把jdom和rom包拷貝到lib目錄下。
直接在jsp頁面上嵌入如下代碼:
<%@ page language="java"
import="java.util.*;
import java.net.URL;
import java.io.InputStreamReader;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;
" pageEncoding="UTF-8"%>
<%
? try {
??????????????? URL feedUrl = new URL("http://www.aygfsteel.com/crazycy/CommentsRSS.aspx");
//上面是那個需要讀取的xml文件的存放地址,我這里找的是偶大哥的blog地址.
??????????????? SyndFeedInput input = new SyndFeedInput();
??????????????? SyndFeed feed = input.build(new XmlReader(feedUrl));
//??????????????? System.out.println(feed);
out.println(feed);
//??????????????? ok = true;
??????????? }
??????????? catch (Exception ex) {
??????????????? ex.printStackTrace();
??????????????? System.out.println("ERROR: "+ex.getMessage());
??????????? }
?
? %>
???而我的這個web使用的是XML Schema
<servlet-mapping>? ????????<servlet-name>Connector</servlet-name>? ????????<url-pattern>/editor/filemanager/browser/default/connectors/jsp/connector</url-pattern>? ????</servlet-mapping>? ????<servlet-mapping>? ????????<servlet-name>SimpleUploader</servlet-name>? ????????<url-pattern>/editor/filemanager/upload/simpleuploader</url-pattern>?? ?</servlet-mapping> |
為
<servlet-mapping>?
????????<servlet-name>Connector</servlet-name>?
????????<url-pattern>/FCKeditor/editor/filemanager/browser/default/connectors/jsp/connector</url-pattern>?
????</servlet-mapping>?
????<servlet-mapping>?
????????<servlet-name>SimpleUploader</servlet-name>?
????????<url-pattern>/FCKeditor/editor/filemanager/upload/simpleuploader</url-pattern>??
??</servlet-mapping>
這里的/FCKeditor/是對應(yīng)你webroot目錄下的FCKeditor目錄。
5.拷貝FCKeditor-2.3\web\WEB-INF\lib下的兩個jar包到WebRoot\WEB-INF\lib目錄下
(在項目的庫中添加FCKeditor-2.3\web\WEB-INF\lib下的兩個jar包? 達(dá)不到同樣的效果,一定要拷貝到lib目錄下)
6.在webroot目錄下新建一個jsp,使用默認(rèn)的MyJsp.jsp即可。
7. 文件開頭處加入? :
<%@ taglib uri="
8.在jsp中嵌入的代碼:在Jsp中使用
方法一:(可能會出現(xiàn):The requested resource (/FCK/editor/fckeditor.html) is not available)
<c:set var="basepath"><c:url value="/fck/" /></c:set>
<FCK:editor id="descn" basePath="${basepath}" height="500px">
<c:out value="${book.descn}" escapeXml="false" default="" />
</FCK:editor>
方法二:
<FCK:editor id="infoContent" basePath="/FCK/FCKeditor/"
????????????? width="800"
????????????? height="300"?????????????????????????
????????????? >
????????????? 請輸入內(nèi)容
</FCK:editor>
9.部署好工程,開啟tomcat,打開MyJsp.jsp頁面即可。
10.三種方法調(diào)用FCKeditor
<%--
三種方法調(diào)用FCKeditor
1.FCKeditor自定義標(biāo)簽 (必須加頭文件 <%@ taglib uri="/TestFCKeditor" prefix="FCK" %> )
2.script腳本語言調(diào)用 (必須引用 腳本文件 <script type="text/javascript" src="/TestFCKeditor/FCKeditor/fckeditor.js"></script> )
3.FCKeditor API 調(diào)用 (必須加頭文件 <%@ page language="java" import="com.fredck.FCKeditor.*" %> )
--%>
<%--
<form action="show.jsp" method="post" target="_blank">
<FCK:editor id="content" basePath="/TestFCKeditor/FCKeditor/"
width="700"
height="500"
skinPath="/TestFCKeditor/FCKeditor/editor/skins/silver/"
toolbarSet = "Default"
>
input
</FCK:editor>
<input type="submit" value="Submit">
</form>
--%>
<form action="show.jsp" method="post" target="_blank">
<table border="0" width="700"><tr><td>
<textarea id="content" name="content" style="WIDTH: 100%; HEIGHT: 400px">input</textarea>
<script type="text/javascript">
var oFCKeditor = new FCKeditor('content') ;
oFCKeditor.BasePath = "/TestFCKeditor/FCKeditor/" ;
oFCKeditor.Height = 400;
oFCKeditor.ToolbarSet = "Default" ;
oFCKeditor.ReplaceTextarea();
</script>
<input type="submit" value="Submit">
</td></tr></table>
</form>
<%--
<form action="show.jsp" method="post" target="_blank">
<%
FCKeditor oFCKeditor ;
oFCKeditor = new FCKeditor( request, "content" ) ;
oFCKeditor.setBasePath( "/TestFCKeditor/FCKeditor/" ) ;
oFCKeditor.setValue( "input" );
out.println( oFCKeditor.create() ) ;
%>
<br>
<input type="submit" value="Submit">
</form>
--%>
添加文件/TestFCKeditor/show.jsp:
<%
String content = request.getParameter("content");
out.print(content);
out.println(request.getParameter("title"));
%>
<!--表單中的input的name可以等于這里request.getParameter("parameter") 中的parameter參數(shù)。可以通過out.println輸出
<FCK:editor id="content".....>FCK中的id相當(dāng)于input的name
-->
11.FCKeditor編輯器文件上傳配置
FCKeditor編輯器的配置文件是fckconfig.js,其中有對編輯器各種默認(rèn)屬性的設(shè)置。以下是fckeditor與java集成使用 時上傳文件的設(shè)置(需要注意的是編輯器不會自動創(chuàng)建文件上傳的文件夾,需要在項目的根目錄中手動添加),將fckeditor.js文件中以下幾個屬性原 來的值修改為如下設(shè)置:
FCKConfig.LinkBrowserURL = FCKConfig.BasePath + "filemanager/browser/default/browser.html?Connector=connectors/jsp/connector" ;
FCKConfig.ImageBrowserURL = FCKConfig.BasePath + "filemanager/browser/default/browser.html?Type=Image&Connector=connectors/jsp/connector" ;
FCKConfig.FlashBrowserURL =FCKConfig.BasePath + "filemanager/browser/default/browser.html?Type=Flash&Connector=connectors/jsp/connector" ;
FCKConfig.LinkUploadURL = FCKConfig.BasePath + 'filemanager/upload/simpleuploader?Type=File' ;
FCKConfig.ImageUploadURL = FCKConfig.BasePath + 'filemanager/upload/simpleuploader?Type=Image' ;
FCKConfig.FlashUploadURL = FCKConfig.BasePath + 'filemanager/upload/simpleuploader?Type=Flash' ;
至此,即可使用FCKeditor的文件上傳功能。
Struts中的 ?struts-config.xml的配置
ActionMapping的配置元素
?path -?????? 該ActionMapping的唯一標(biāo)識符,它包括對應(yīng)的Web地址 (不包括擴(kuò)展名.do)
?type?-?????? 當(dāng)請求該路徑時,調(diào)用的Action對象
?name?-? ?? HTML表單對應(yīng)的JavaBean(ActionForm)
?scope?-???? 定義了存儲該JavaBean在請求中(request)還是在會話中(session)
?validate?- 定義了在調(diào)用Action對象前是否調(diào)用JavaBean上的validate方法
?input -????? 定義了當(dāng)validate方法返回false時要轉(zhuǎn)移到的地址
(Struts中的很多命名都是很含糊的;比如ActionMapping中的name屬性并不是指該ActionMapping對象的名字,而是指該ActionMapping使用的JavaBean的名字;)?