2017-6-13 Lifusen 此文章僅代表個人觀點,如有問題提出請聯系Q:570429601 1、Hibernate (開放源代碼的對象關系映射框架) Hibernate是一個開放源代碼的對象關系映射框架,它對JDBC進行了非常輕量級的對象封裝,它將POJO與數據庫表建立映射關系,是一個全自動的orm框架,hibernate可以自動生成SQL語句,自動執行,使得Java程序員可以隨心所欲的使用對象編程思維來操縱數據庫。 Hibernate可以應用在任何使用JDBC的場合,既可以在Java的客戶端程序使用,也可以在Servlet/JSP的Web應用中使用,最具革命意義的是,Hibernate可以在應用EJB的J2EE架構中取代CMP,完成數據持久化的重任。 !(Hibernate默認用的是slf4j-nop.jar日志實現方式。 但是我們可以替換成log4j的實現。但不是簡單的加上log4j-1.2.17.jar就行了。 中間還需要一個轉換器slf4j-log4j12-1.5.8.jar) 1.在src目錄下創建hibernate.cfg.xml配置文件(文件名字不能修改) <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/sampe_h5_db</property> <property name="connection.username">root</property> <property name="connection.password">root</property> <!-- 為Hibernate指定不同數據庫的方言 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <mapping class="sample.h5.entity.User" /> <!-- create and update the database automaticlly --> <property name="hbm2ddl.auto">update</property> <!-- javax.persistence.validation.mode默認情況下是auto的,就是說如果不設置的話它是會自動去你的classpath下面找一個 bean-validation**包,但是找不到,所以beanvalitionFactory錯誤 --> <property name="javax.persistence.validation.mode">none</property> </session-factory> </hibernate-configuration> 注意: hibernate.hbm2ddl.auto屬性不要亂用,也可以不用 (1)<property name="hibernate.hbm2ddl.auto"> create-drop </property> create-drop:表示在hebarinate初始化時創建表格,程序運行結束的時候會刪除相應的表格,在實際項目中不用 (2)<property name="hibernate.hbm2ddl.auto">create</property> 在hibernate初始化時會創建表格,在運行結束之后不刪除表格,而是在下一次運行的時候如果有舊的刪掉,沒有舊的,重新建表格 (3)<property name="hibernate.hbm2ddl.auto">update</property> 只是根據映射文件去和數據庫中的表對應起來,如果不一致,就更新表的結構 (4)<property name="hibernate.hbm2ddl.auto">validate</property> 校驗映射文件和數據庫中的表是不是能對應起來,不能對應報錯,實際中常用 最后一條javax.persistence.validation.mode可以不用, 加上<mapping class="sample.h5.entity.User" /> ------------------------------------------------------------------------------------------------------------------------------------------ @Entity @Table(name="tbl_book") public class Book { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="bid") private Integer id; @Column(name="btitle") private String title; @ManyToOne @JoinColumn(name="bcategoryid") private Category category; category--- @OneToMany(mappedBy="category") private Set<Book> books; @Column(name="otime") @Temporal(TemporalType.TIMESTAMP) private Date time; @OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER, mappedBy="order")級聯,緊急加載 private Set<OrderItem> items = new HashSet<OrderItem>(); //組件注解:使用Embedded注解說明,我要使用ZhangHao(組件類)類中的屬性來匹配表中的列(數據庫沒有實體對應) @Embedded @AttributeOverrides({ @AttributeOverride(name="username", column=@Column(name="uloginid")), @AttributeOverride(name="password", column=@Column(name="uloginpsw")) }) private ZhangHao zhaoHao; @ElementCollection(fetch=FetchType.EAGER) // 將所有集合的默認抓取策略(fetch),LAZY(延遲加載)設置成EAGER(緊急加載) @CollectionTable(name="tbl_tel", joinColumns=@JoinColumn(name="tuid")) @Column(name="tphone") @SortNatural private SortedSet<String> phones = new TreeSet<String>(); @ElementCollection(fetch=FetchType.EAGER) @CollectionTable(name="tbl_score", joinColumns=@JoinColumn(name="suid")) @MapKeyColumn(name="scourse") @Column(name="sscore") @SortNatural @ElementCollection(fetch=FetchType.EAGER) @CollectionTable(name="tbl_recieve", joinColumns=@JoinColumn(name="ruid")) @MapKeyColumn(name="rname") @OrderBy(clause="rid") private Map<String, Recieve> recieves = new HashMap<String, Recieve>(); private Map<String, Integer> scores = new HashMap<String, Integer>(); @Column(name="uregistDate", updatable=false) // 日期時間類型的注解 @Temporal(TemporalType.DATE) private Date registDate; // 計算列:該注解修飾的字段(count)是根據注解指定的語句查詢計算出來的值,並不存在一個叫做count的列在表中 @Formula("(select count(*) from tbl_user)") private Integer count; // 瞬時屬性的注解:表示Hibernate忽略該屬性 @Transient private String other; hql // 查詢出一組或一個實體對象 //List<Book> list = session.createQuery("from Book b where b.title = '西游記'").list(); 查出單個的對象(值) //Object result = session.createQuery("select avg(b.price) from Book b").uniqueResult(); // hql的更新和修改 //int row = session.createQuery("update Book b set b.price = b.price * 0.8").executeUpdate(); //System.out.println("修改了" + row +"本書的價格!"); int pageSize = 2; int pageNO = 1; List<Book> list = session.createQuery("from Book b where b.price >= :price") .setParameter("price", 30.0) .setFirstResult((pageNO-1) * pageSize) .setMaxResults(pageSize) .list(); //String hql = "from Book b where b.title <> '西游記' and b.price >= 50 "; //String hql = "from Book b where b.title like '%記%'"; //String hql = "from Book b where b.price between 40 and 80"; //String hql = "from Book b where b.author in ('吳承恩', '司馬遷')"; //String hql = "from Book b where b.category is not null"; //String hql = "select b from Book b, Category c where b.category = c"; //String hql = "select b.id, b.title, b.price from Book b"; //String hql = "select new list(b.id, b.title, b.price) from Book b"; //String hql = "select new map(b.id as ID, b.title as 標題, b.price as 價格) from Book b"; //String hql = "select new Book(b.id, b.title, b.price) from Book b"; //String hql = "from Book b where b.category.name = '歷史'"; //String hql = "select b from Book b left join b.category c where c.name = '歷史' "; //String hql = "select distinct c from Category c left join fetch c.books b where b.price < 30.0"; //String hql = "select c from Category c where size(c.books) > 0 order by c.id"; String hql = "select new map(b.category.name as 分類, count(b) as 圖書本數, avg(b.price) as 圖書平均售價) from Book b group by b.category having avg(b.price) >= 40.0 order by 圖書平均售價 desc"; List<Map> list = session.createQuery(hql).list(); /* List<Order> orders = session.createCriteria(Order.class) .add(Restrictions.ge("money", 300.0)) .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) .list(); */ 連接池 hibernate.cfg.xml <property name="hibernate.c3p0.min_size">5</property><!-- 連接池中最小連接數 --> <property name="hibernate.c3p0.max_size">20</property><!-- 連接池中最大連接數 --> <property name="hibernate.c3p0.timeout">120</property><!-- 設定數據庫連接超時時間,以秒為單位。如果連接池中某個數據庫連接處於空閑狀態且超過timeout秒時,就會從連接池中移除--> <property name="hibernate.c3p0.idle_test_period">3000</property> <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property> <property name="hibernate.cache.use_second_level_cache">true</property> <property name="hibernate.cache.use_query_cache">true</property> ehcache.xml <?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"> <diskStore path="D:\ehcacheData"/> <defaultCache maxElementsInMemory="1000" eternal="false" overflowToDisk="true" diskPersistent="true" timeToIdleSeconds="120" timeToLiveSeconds="240" maxElementsOnDisk="10000000" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> </defaultCache> </ehcache> 存儲過程 // 創建了一個存儲過程 調用器對象 ProcedureCall call = session.createStoredProcedureCall("getOrderDetails"); call.registerParameter("m", Double.class, ParameterMode.IN).bindValue(300.0); call.registerParameter("c", Long.class, ParameterMode.OUT); ProcedureOutputs outputs = call.getOutputs(); // 從存儲過程的輸出的對象組中,獲取輸出參數的值 Long count = (Long) outputs.getOutputParameterValue("c"); // 從存儲過程的輸出的對象組中獲取結果集類型的輸出結果 ResultSetOutput output = (ResultSetOutput) outputs.getCurrent(); // 從結果集類型的輸出結果中,獲取數據列表 List<Object[]> orderinfos = output.getResultList(); System.out.println("下單顧客\t下單次數\t總消費額"); for(Object[] orderinfo : orderinfos) { System.out.println(orderinfo[0] + "\t" + orderinfo[1] + "\t" + orderinfo[2]); } System.out.println("\n訂單金額在200以上的訂單數量是:" + count ); } 命名查詢 // 調用session的創建命名查詢對象的方法:createNamedQuery List<Order> orders = session.createNamedQuery("getOrdersByMoney", Order.class) .setParameter("minMoney", 300.0) .list(); for(Order o : orders) { System.out.println(o.getId() + ", " + o.getCustomer() + ", " + o.getMoney() + ", " + o.getTime() + ", " + o.getItems()); } } 存儲過程2 @Test public void testSencodLevelCache() { Category c1 = session.get(Category.class, 1); System.out.println(c1.getId() +", " + c1.getName()); session.createQuery("from Category c").setCacheable(true).list(); } @Test public void testSencodLevelCache2() { Category c1 = session.get(Category.class, 1); System.out.println(c1.getId() +", " + c1.getName()); session.createQuery("from Category c").setCacheable(true).list(); } 二級緩存 List<Book> list = session.createQuery("from Book b left join fetch b.category").list(); for(Book elem : list) { System.out.println(elem); } List<Category> list2 = session.createQuery("select distinct c from Category c left join fetch c.books").list(); for(Category elem : list2) { System.out.println(elem); } 總結: 1、一級緩存是session級別的,二級緩存和查詢緩存都是sessionfactory級別的,查詢緩存和二級緩存是一起來使用的 2、任何sql執行都會存入到同一個session的一級緩存中去 3、同時開啟查詢緩存和二級緩存,可以在不同session間共享緩存的結果 4、二級緩存緩存的是實體,不是屬性 5、查詢緩存的結果如果只是屬性,那么查詢緩存中存儲的是id和屬性的值,如果是實體的集合,那么查詢緩存存儲的只是實體的id,對應的實體會存儲到二級緩存中去。 6、不同session間返回數據的順序是,二級緩存先將數據返回,然后將數據存入本session的一級緩存中去,以便下次調用時的使用 2、Struts2:Struts2是一個基於MVC設計模式的Web應用框架,它本質上相當於一個servlet,在MVC設計模式中,Struts2作為控制器(Controller)來建立模型與視圖的數據交互。Struts 2是Struts的下一代產品,是在 struts 1和WebWork的技術基礎上進行了合並的全新的Struts 2框架。其全新的Struts 2的體系結構與Struts 1的體系結構差別巨大。Struts 2以WebWork為核心,采用攔截器的機制來處理用戶的請求,這樣的設計也使得業務邏輯控制器能夠與ServletAPI完全脫離開,所以Struts 2可以理解為WebWork的更新產品。雖然從Struts 1到Struts 2有着太大的變化,但是相對於WebWork,Struts 2的變化很小。 1. web.xml <filter> <filter-name>struts2-filter</filter-name> <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2-filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 如果你的Action類沒有繼承ActionSupport,而你又沒有在struts.xml中對應<action>標簽中用method屬性指定你自己的方法的話, 默認就要找execute方法,這時是必須要實現execute方法的,否則Struts2會找不到對應的方法而報錯。 src下面struts.xml <struts> <!-- 配置的是全局的國際化資源包的基礎包名 --> <constant name="struts.custom.i18n.resources" value="myRes" /> <!-- 配置常量:struts.devMode是控制是否啟用開發模式 --> <constant name="struts.devMode" value="false" /> <constant name="struts.i18n.encoding" value="UTF-8" /> <constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant> <include file="struts-user.xml" /> <package name="default" extends="struts-default"> <!-- 指定當前包中的默認處理器為notFound處理器:當請求到當前包中時,沒有匹配到對應的action,則執行該默認action <default-action-ref name="notFound" /> --> <action name="notFound"> <result>/WEB-INF/jsp/not-found.jsp</result> </action> </package> </struts> struts-user.xml <package name="zjp" extends="struts-default" namespace="/"> <!-- 全局(包范圍)結果定義 --> <global-results> <result name="ex">/WEB-INF/jsp/errorHandle.jsp</result> </global-results> <!-- 全局(包范圍)“異常映射”定義 --> <global-exception-mappings> <exception-mapping result="ex" exception="java.lang.Exception" /> </global-exception-mappings> <action name="userLoginForm" class="sample.s2.web.action.UserAction" method="loginForm"> <result name="success" type="dispatcher"> <param name="location">/WEB-INF/jsp/login.jsp</param> </result> </action> <action name="userLogin" class="sample.s2.web.action.UserAction" method="login"> <result name="success" type="redirectAction">userHome</result> <result name="error" type="chain">userLoginForm</result> </action> <action name="userHome" class="sample.s2.web.action.UserAction" method="home"> <result>/WEB-INF/jsp/home.jsp</result> </action> <action name="userRegistForm" class="sample.s2.web.action.UserAction" method="registForm"> <result>/WEB-INF/jsp/regist.jsp</result> </action> <action name="userRegist" class="sample.s2.web.action.UserAction" method="regist"> <result type="chain">userRegistForm</result> </action> </package> <package name="back" extends="struts-default" namespace="/mgr"> <global-results> <result name="ex">/WEB-INF/jsp/errorHandle.jsp</result> </global-results> <global-exception-mappings> <exception-mapping result="ex" exception="java.lang.Exception" /> </global-exception-mappings> <action name="adminLoginForm"> <result>/WEB-INF/jsp/mgr/admin-login.jsp</result> </action> </package> <s:debug></s:debug>標簽 type------------chain 、dispatcher 、stream 、redirect 、redirectAction UserAction 繼承ActionSupport private User u; 有get set 下面有 private Integer id; private String name; private Integer age; private Date birthdate; private boolean married; private List<Integer> luckyNumbers; private List<Parent> parents; private List<Game> games; 國際化資源包myRes_zh_CN.properties 、myRes_en_US.properties <a href="/SampleStruts2/userLoginForm?request_locale=zh_CN">中文</a> | <a href="/SampleStruts2/userLoginForm?request_locale=en_US">English</a> user.home.header=Hello:{0},Welcome to the site! <h3><s:text name="user.home.header"><s:param>${currLoginId }</s:param></s:text></h3> 前端:<p><s:text name="user.login.form.label.loginId" /><input type="text" name="u.loginId" value="${loginId }" /></p> 后端:ctx.put("loginErrorMsg", super.getText("user.login.faile")); 服務器異常查看 <%@ taglib prefix="s" uri="/struts-tags"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>服務器異常</title> <script type="text/javascript"> function showDetails() { document.getElementById('details').style.display = 'block'; } </script> </head> <body> <h3>Sorry,服務器出錯了,請稍后再試!</h3> <p><a href="javascript: showDetails();">技術人員,查看詳情</a></p> <div id='details' style="font-size:12px; color: red; display:none;"> <p style="font-size:14px; font-weight: bold;">${ exception }</p> <s:iterator value="#request.exception.stackTrace"> <p><s:property /></p> </s:iterator> </div> </body> </html> 傳入id轉成類 <p>喜歡的游戲: <s:iterator value="#allGames" var="g"> <input type="checkbox" name="u.games" value="${g.id }" />${g.name } </s:iterator> </p> src下面xwork-conversion.properties 內容sample.s2.entity.Game=sample.s2.web.typeconverter.GameTypeConverter GameTypeConverter extends StrutsTypeConverter 內容 @Override public Object convertFromString(Map context, String[] params, Class kls) { int id = Integer.parseInt(params[0]); Game game = new Game(); game.setId(id); return game; } @Override public String convertToString(Map arg0, Object obj) { Game game = (Game)obj; return "游戲信息:id=" + game.getId() + ", name=" + game.getName(); } struths驗證 userAction private User u; 同包下面userAction_zh_CN.properties invalid.fieldvalue.u.age=\u7528\u6237\u5E74\u9F84\u503C\u683C\u5F0F\u9519\u8BEF\uFF0C\u5FC5\u987B\u662F\u4E2A\u6574\u6570 //年齡格式錯誤,必須是個整數 invalid.fieldvalue.u.birthdate=\u51FA\u751F\u65E5\u671F\u683C\u5F0F\u9519\u8BEF\uFF0C\u5E94\u8BE5\u4F8B\u5982\uFF1A1995-01-01 //出生日期格式錯誤,應該例如:1995-01-01 如果沒有就在xwork.default.invalid.fieldvalue=\u6570\u636E\u7684\u683C\u5F0F\u9519\u8BEF\u201C{0}\u201D //數據的格式錯誤 前端顯示<s:property value="[0].fieldErrors" /> 格式驗證失敗返回input 上傳文件 <action name="userRegist" class="sample.s2.web.action.UserAction" method="regist"> <interceptor-ref name="fileUpload"> <param name="allowedTypes">image/jpeg, image/png, image/gif</param> <param name="maximumSize">1024000</param> </interceptor-ref> <interceptor-ref name="myDefault"/> <result name="input" type="chain">userRegistForm</result> </action> userAction_zh_CH.properties struts.messages.error.uploading=Error uploading: {0} struts.messages.error.file.too.large=\u6587\u4EF6{1}\u592A\u5927\u4E86\uFF0C\u5FC5\u987B\u5C0F\u4E8E {4} \u5B57\u8282\uFF01 struts.messages.error.content.type.not.allowed=\u5934\u50CF\u6587\u4EF6\u5FC5\u987B\u662F\u56FE\u7247 struts.messages.error.file.extension.not.allowed=File extension not allowed: {0} "{1}" "{2}" {3} private File face; if(face != null) { System.out.println("face: " + face); System.out.println("faceContentType: " + faceContentType); /* 獲取相對網站根路徑的相應的磁盤路徑 */ String realPath = ServletActionContext.getServletContext().getRealPath("/upload/" + faceFileName); try { FileUtils.copyFile(face, new File(realPath)); } catch (IOException e) { e.printStackTrace(); } } else { System.out.println("用戶未上傳頭像"); 強加驗證 UserAction-userRegist-validation.xml <field name="u.age"> <field-validator type="required"> <message>年齡必填</message> </field-validator> <field-validator type="int"> <param name="min">18</param> <param name="max">40</param> <message>年齡必須在18到40歲之間</message> </field-validator> </field> <field name="u.birthdate"> <field-validator type="required"> <param name="trim">true</param> <message>出生日期不能為空</message> </field-validator> </field> </validators> 前端 <s:property value="[1].fieldErrors['u.birthdate'][0]" /> 自定義驗證類型 src validators.xml <validators> <validator name="zip" class="sample.s2.web.validator.ZipValidator" /> </validators> class public class ZipValidator extends FieldValidatorSupport { @Override public void validate(Object action) throws ValidationException { String fieldName = super.getFieldName(); // "zip" String fieldValue = (String) super.getFieldValue(fieldName, action); // "610000" if(fieldValue != null && !fieldValue.equals("")) { System.out.println("fieldName: " + fieldValue); System.out.println("fieldValue: " + fieldValue); if(!Pattern.matches("^\\d{6}$", fieldValue)) { super.addFieldError(fieldName, action); } } } } UserAction-userRegist-validation.xml <field name="zip"> <field-validator type="zip"> <message>郵政編碼格式錯誤!</message> </field-validator> </field> 攔截器 <!-- 聲明攔截器 --> <interceptors> <interceptor name="sample" class="sample.s2.web.interceptor.SampleInterceptor" /> <interceptor name="log" class="sample.s2.web.interceptor.LogInterceptor"> <param name="datePattern">yyyy年MM月dd日 HH點mm分ss秒</param> </interceptor> <interceptor-stack name="myDefault"> <interceptor-ref name="log" /> <interceptor-ref name="defaultStack" /> </interceptor-stack> </interceptors> <!-- 配置默認攔截器引用: 該包下的所有未直接配置攔截器引用的action,都使用myDefault這個攔截器棧 --> <default-interceptor-ref name="myDefault" /> 文件下載 <action name="download" class="sample.s2.web.action.ResourceAction" method="download"> <result name="success" type="stream"> <param name="inputName">is</param> <param name="contentType">${contentType}</param> <param name="contentDisposition">attchement;filename=${fileName}</param> <param name="bufferSize">4096</param> </result> </action> private Integer rid; private InputStream is; private String fileName; private String contentType; //get set public String download() throws UnsupportedEncodingException { System.out.println("download... rid: " + rid); if(rid == 1001) { // 想下載/WEB-INF/resources/bbs_gd.doc this.is = ServletActionContext.getServletContext().getResourceAsStream("/WEB-INF/resources/bbs_gd.doc"); this.fileName = URLEncoder.encode("bbs設計文檔.doc", "utf-8"); System.out.println("fileName encode: " + this.fileName); System.out.println("fileName decode: " + URLDecoder.decode(this.fileName, "UTF-8")); this.contentType="application/msword"; } else if(rid == 1002) { // 想下載10.jpg this.is = ServletActionContext.getServletContext().getResourceAsStream("/WEB-INF/resources/10.jpg"); this.fileName = "10.jpg"; this.contentType = "image/jpeg"; } // ActionContext.getContext().put("downloadError", "下載失敗:必須是登錄用戶才能下載,現在馬上<a href='#'>去登錄</a>。"); return SUCCESS; } private InputStream fengJingInputName; @Override public String execute() throws Exception { this.fengJingInputName = ServletActionContext.getServletContext().getResourceAsStream("/WEB-INF/resources/Ajax:2.avi"); return SUCCESS; } <action name="downloadFengJing" class="sample.s2.web.action.DownloadFengJingAction"> <!-- 啟用攔截器:為當前處理器 --> <interceptor-ref name="sample" /> <interceptor-ref name="myDefault" /> <result type="stream"> <param name="inputName">fengJingInputName</param> <param name="contentDisposition">attchement;filename=Ajax:2.avi</param> </result> </action> 權限驗證 <package name="management" extends="json-default" namespace="/mgr"> <interceptors> <!-- 聲明“權限驗證”攔截器 --> <interceptor name="authority" class="sample.s2.web.interceptor.mgr.AuthorityInterceptor"> <param name="excludeMethods">loginForm,loginCheck</param> </interceptor> <!-- 聲明“后台管理默認攔截器棧” --> <interceptor-stack name="mgrDefaultStack"> <interceptor-ref name="authority" /> <interceptor-ref name="defaultStack" /> </interceptor-stack> </interceptors> AuthorityInterceptor.java @SuppressWarnings("serial") public class AuthorityInterceptor extends MethodFilterInterceptor { @Override protected String doIntercept(ActionInvocation invocation) throws Exception { ActionContext ctx = invocation.getInvocationContext(); if(ctx.getSession().get("currAdmin") == null) { ctx.put("tip", "請先登錄,再進行其他操作!"); return "login"; } else { return invocation.invoke(); } } } <action name="getRandom" class="sample.s2.web.action.mgr.DemoAjaxAction" method="getRandom"> <result type="stream"> <param name="inputName">bais</param> <param name="contentType">text/html;charset=UTF-8</param> </result> </action> action name="getAllAdmins" class="sample.s2.web.action.mgr.DemoAjaxAction" method="getAllAdmins"> <result type="json"> <param name="root">admins</param> <param name="contentType">application/json;charset=UTF-8</param> </result> </action> private String type; private InputStream bais; private List<Admin> admins; public String getRandom() throws Exception { int offset = type.equals("small") ? 0 : 5; String r = (int)(Math.random() * 5) + offset + ""; // "9" bais = new ByteArrayInputStream(r.getBytes("utf-8")); return SUCCESS; } public String getAllAdmins() { admins = adminService.getAdmins(); return SUCCESS; } $(function(){ $.get("/SampleStruts2/mgr/getRandom", {"type" : "small"}, function(data){ $("#num").text(data); }); $.getJSON("/SampleStruts2/mgr/getAllAdmins", function(data){ alert(data.length); }); }); 3、Spring是一個開源框架,Spring是於2003 年興起的一個輕量級的Java 開發框架,由Rod Johnson創建。 簡單來說,Spring是一個分層的JavaSE/EEfull-stack(一站式) 輕量級開源框架。 src下面 applicationContext.xml <bean id="inkPrinter" class="demo.spring4.bean.InkPrinter" /> <bean id="lesserPrinter" class="demo.spring4.bean.LesserPrinter" /> <bean id="computer" class="demo.spring4.bean.Computer"> <property name="printer" ref="lesserPrinter" /> </bean> <bean id="zwj" class="demo.spring4.bean.Student" scope="prototype"> <property name="name" value="張無忌" /> <property name="age" value="23" /> <property name="birthdate"> <bean class="java.util.Date" /> </property> <property name="lover" ref="zm" /> <property name="loveBooks"> <list> <value>西游記</value> <value>水滸傳</value> <value>三國演義</value> <value>紅樓夢</value> </list> </property> <property name="scores"> <map> <entry key="HTML" value="95" /> <entry key="JSP" value="87" /> <entry key="JavaBasic" value="91" /> </map> </property> <property name="healthPoster"> <props> <prop key="height">1.81</prop> <prop key="weight">82</prop> </props> </property> </bean> <bean id="zm" class="demo.spring4.bean.Student"> <constructor-arg index="0" value="趙敏" /> <constructor-arg index="1" value="22" /> <property name="birthdate" ref="now" /><!-- ref屬性代表引用了容器中的其他Bean的ID --> </bean> <bean id="now" class="java.util.Date" /> src test.properties # a common properties file name=\u5F20\u4E09 age=23 sex=male height=1.79 public void testProperties() { /* Properties props = System.getProperties(); for(Object key : props.keySet()) { System.out.println(key + " = " + props.get(key)); } */ Properties props = new Properties(); try { props.load(new InputStreamReader(Spring4Test.class.getResourceAsStream("/test.properties"), "UTF-8")); System.out.println(props); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } ApplicationContext context = new ClassPathXmlApplicationContext("/applicationContext.xml"); System.out.println("-- ApplicationContext 已經創建完成 -----------------------------\n"); context.getBean("zwj"); context.getBean("zwj"); ApplicationContext context = new ClassPathXmlApplicationContext("/applicationContext.xml"); System.out.println("-- ApplicationContext 已經創建完成 -----------------------------\n"); context.getBean("zwj"); context.getBean("zwj"); 4、Spring MVC屬於SpringFrameWork的后續產品,已經融合在Spring Web Flow里面。Spring 框架提供了構建 Web 應用程序的全功能 MVC 模塊。使用 Spring 可插入的 MVC 架構, 從而在使用Spring進行WEB開發時,可以選擇使用Spring的SpringMVC框架或集成其他MVC開發框架,如Struts1,Struts2等。 WEB-INF下面 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:/springmvc-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app> src下面 springmvc-servlet.xml <context:component-scan base-package="demo.springmvc.web.controller" /> <mvc:annotation-driven /> <!-- 防止無法正確訪問靜態資源 --> <mvc:default-servlet-handler/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> controller頁面 @Controller @RequestMapping("/mvc") public class mvcController { //類上面 @Controller 負責注冊一個bean 到spring 上下文中 @RequestMapping 注解為控制器指定可以處理哪些 URL 請求 Date類型轉 //the parameter was converted in initBinder @RequestMapping("/date") public String date(Date date){ System.out.println(date); return "hello"; } //At the time of initialization,convert the type "String" to type "date" @InitBinder public void initBinder(ServletRequestDataBinder binder){ binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true)); } //pass the parameters to front-end @RequestMapping("/show") public String showPerson(Map<String,Object> map){ Person p =new Person(); map.put("p", p); p.setAge(20); p.setName("jayjay"); return "show"; } 前台可在Request域中取到"p" //pass the parameters to front-end using ajax @RequestMapping("/getPerson") public void getPerson(String name,PrintWriter pw){ pw.write("hello,"+name); } @RequestMapping("/name") public String sayHello(){ return "name"; } 前台用下面的Jquery代碼調用 $(function(){ $("#btn").click(function(){ $.post("mvc/getPerson",{name:$("#name").val()},function(data){ alert(data); }); }); }); //redirect @RequestMapping("/redirect") public String redirect(){ return "redirect:hello"; }
