對了,代碼上傳到碼雲:https://gitee.com/tqbx/travel-maven-web.git
歡迎交流,菜雞求教~(ps:github好慢好慢)javascript
可能一開始建立出來的項目文件目錄形式不對,IDEA對目錄結構有明顯的要求,能夠經過如下方法修改,固然其餘狀況也可使用;html
後來發現能夠直接右鍵點擊目錄,選擇make directory as 效果是同樣的。java
視頻中使用的是Servlet3.0以後的版本,利用註解配置,我原來以前一直也是註解配置,想試着使用xml配置練練手。可是當我從xml到註解轉換的過程當中,遇到了一些問題,主要是Servlet版本和maven倉庫版本衝突?具體我也不太清清除,過於真實,整個過程迷迷糊糊的,bug頻出,也試過不少方法,真的不知道是哪一個方法起了做用。mysql
如下內容僅記錄本身的糾錯過程,首先我先去視頻中的代碼文件查看一下有誤差的地方:直接鎖定是Servlet的版本問題,servlet3.0以後纔可使用註解,而我使用的是2.5。git
接着,我參考了這個博客:Maven建立webapp骨架沒法使用@WebServlet來實現註解配置解決方案,修改了maven倉庫中的jar包的web.xml內容,多是我操做的問題,並無見效。github
接着又在某個論壇上看到一個方法,能夠從新指定xml的版本。【後面測試了幾回,貌似和這個關係不大】web
接着在pom.xml中添加servlet3.0以後的依賴,須要注意的是,要指定scope爲provide,否則的話可能會產生衝突。【必定要注意找到填寫正確座標,有一次我把artifactId裏寫成servlet-api死活下載不來】ajax
<!--Servlet--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency>
就像這樣的衝突錯誤(下面兩種都是由於scope沒有指定privided的緣由,由於添加上去就成功了)redis
com.travel.web.filter.CharacterFilter cannot be cast to javax.servlet.Filter
。spring
javax.servlet.ServletException: java.lang.LinkageError
。
中途會遇到缺乏javaEE啥啥啥的,annotation包依賴缺乏的錯誤,按照提示添加便可。
以上就是我從web.xml到註解配置的全過程,有點坎坷,可是從此遇到這樣的問題,興許會多一些思路吧。
settings
->Build,Execution,Deployment
->Build Tools
->Maven
->Runner
。
設置VM-Option
參數,指定虛擬機字符集:-Dfile.encoding=gb2312
,若是不行能夠設置稱其餘的。
//校驗經過,ajax發送請求,提交表單數據 $("#registerForm").serialize() $.post("registerUserServlet",$(this).serialize(),function (data) { if(data.flag){ //註冊成功,跳轉成功頁面 location.href= "register_ok.html"; }else{ //若是錯誤,須要從新對驗證碼servlet請求一次,否則會致使會話中的驗證碼消失,圖片雖然存在,但碼已經沒有了 document.getElementById("check_img").src= "checkCode?"+new Date().getTime(); //註冊失敗,給errormsg添加提示信息 $("#error_msg").html(data.errorMsg); } })
var reg_telephone = /^1(3|4|5|7|8)\d{9}$/;
var reg_email = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
注意此時將函數名做爲Function對象傳入,沒有()。
$("#username").blur(checkUsername);
將信息封裝爲對象,是值得我學習的地方。
public class ResultInfo implements Serializable { private boolean flag;//後端返回結果正常爲true,發生異常返回false private Object data;//後端返回結果數據對象 private String errorMsg;//發生異常的錯誤消息 }
參考:https://blog.csdn.net/ywl570717586/article/details/53130863,該博客分割線如下內容。
利用mapper對象操做json數據
import com.fasterxml.jackson.databind.ObjectMapper; //將info對象序列化爲json,返回客戶端 ObjectMapper mapper = new ObjectMapper(); String json = mapper.writeValueAsString(info); //將json數據寫回客戶端 //設置content-type response.setContentType("application/json;charset=utf-8"); response.getWriter().write(json);
沒有指定value屬性得時候,傳遞過去的值爲on!!!
//根據傳遞過來的參數name獲取對應的值 function getParameter(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)","i"); var r = location.search.substr(1).match(reg); if (r!=null) return (r[2]); return null; }
利用【MailUtils】完成郵箱發送,不過得在郵箱設置裏面申請開啓服務。
利用【uuid工具類】完成隨機激活碼的生成。
利用【JedisUtils】完成redis客戶端的獲取,從而操做redis數據庫。
利用【JDBCUtils】封裝druid鏈接池,返回數據源對象。
參考HttpServlet的service方法對請求的方式進行路徑分發,對應不一樣的方法,完成不一樣的相似Servlet完成的功能,真的受益不淺,回過頭來思考本來須要定義那麼多那麼多的Servlet,如今徹底封裝到一個UserServlet中,妙啊。
【分發Servlet】
try { Method method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class); //調用方法 method.invoke(this,req,resp); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); }
報錯:java.lang.NoSuchMethodException
緣由:調用方法是Protected修飾的。
解決:
忽略訪問權限修飾符+暴力破解。
try { //忽略訪問權限修飾符 Method method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class); //暴力破解 method.setAccessible(true); //調用方法 method.invoke(this,req,resp); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); }
直接將調用的方法權限修改成public便可。(看到這操做,忍不住笑了)
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
報錯緣由:多是由於MySQL服務沒有開啓,打開services.msc,開啓MySQL就ok了。
相似的問題還有redis服務端未開啓:redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect timed out
。
報錯:Every derived table must have its own alias
SELECT COUNT(*) FROM ( select * from department) AS aa; -- 語法如此,須要給子查詢的表加上別名。
有些資源每次加載頁面都會從新請求數據庫數據來加載,對數據庫的壓力比較大,且這些數據不會常常發生變化,能夠進行緩存優化。
https://blog.csdn.net/Sky_QiaoBa_Sum/article/details/105167978
這個插件下載以後,才發現本身原來寫的註釋那麼沒有原則,哈哈,這個東西對於有強迫症的人來講,簡直魔鬼無疑。
private boolean checkCode(HttpServletRequest request,HttpServletResponse response) throws IOException { //驗證碼校驗 String check = request.getParameter("check"); HttpSession session = request.getSession(); String checkCodeServer = (String) session.getAttribute("checkCode"); //保證驗證碼只能使用一次 session.removeAttribute("checkCode"); //驗證碼不相等 if(checkCodeServer == null||!checkCodeServer.equalsIgnoreCase(check)){ //對用戶輸入驗證碼進行判斷 if("".equals(check)){ info.setErrorMsg("驗證碼不能爲空"); }else { info.setErrorMsg("驗證碼錯誤"); } info.setFlag(false); response.setContentType(JSON_CONTENT_TYPE); String s = mapper.writeValueAsString(info); response.getWriter().write(s); return false; } return true; }
這也是我在回頭看代碼的時候思考的一個問題,曾經在一些微信公衆號上見過相似的科普。
有時候dao層可能會產生list集合爲空的狀況,好比沒有查詢到list,這時候若是返回null,在service層就須要作相應的非null判斷,有時候可能會忘記。我最初的想法是初始化一個空的ArrayList,List<Category> list = new ArrayList();
 @Override public List<Category> findAll() { //List<Category> list = Collections.emptyList(); List<Category> list = new ArrayList<>(); try{ String sql = "select * from tab_category"; list = template.query(sql,new BeanPropertyRowMapper<>(Category.class)); }catch (Exception e){ } return list; }
在查找資料的過程當中,發現Collections集合類有專門產生空集合的方法,例如List<Category> list = Collections.emptyList();
,查看他的源碼能夠發現,實際上它建立一個靜態內部類的對象private static class EmptyList<E>
。更特別的是,產生的list並無咱們熟悉的add,remove等方法,對他進行這些操做會直接拋出UnsupportedOperationException
異常。
https://blog.csdn.net/Sky_QiaoBa_Sum/article/details/105168546
避免圖文不符。
<a href="javascript:void(judgeUser())" id="myFavorite" class="collection">個人收藏</a> //點擊個人收藏 judgeUser = function (){ //未登陸 if(user == null){ alert("您還沒有登陸,請登陸!") location.href = "http://localhost/travel/login.html"; }else{ //已登陸a // alert(user.uid); var uid = user.uid; // http://localhost/travel/route/pageFavorite?uid=7 location.href = "http://localhost/travel/myfavorite.html?uid=7"; } }
利用cookie技術,在客戶端存儲帳號密碼,實現自動登陸。
增長熱門推薦,並鏈接路線具體信息。
可是上面對應的樣式是真的不知道哪裏改,通過debug,發現點擊狀態下會激活active樣式是沒錯的,bug處在左邊三欄和右邊字體差了一格,但願知道怎麼修復的小夥伴教教我!否則也太難受了。
這個部分在sql語句部分消耗了許多時間,表關係以下:
個人想法是,先根據tab_favorite中的rid進行分組,而後計算每一個rid的數量,就是用戶收藏的個數,按照降序排列,生成新的子查詢表。而後在tab_route中尋找rid與子查詢表rid相同的路線,並進行where子查詢,模糊匹配路線名,以及金額大小,最後就能夠得到:
由收藏次數降序排序的route,而且是徹底符合搜尋條件的。
@Override public List<Route> findRouteByRangePage(int start, int pageSize, String rname, int first, int last) { //String sql = "select * from tab_route where cid = ? limit ? , ?"; String sql = "SELECT * FROM (SELECT * FROM (SELECT rid,COUNT(rid) AS COUNT FROM tab_favorite " + "GROUP BY rid ORDER BY COUNT(rid) DESC)AS aa)AS bb,tab_route t WHERE t.rid = bb.rid "; StringBuilder sb = new StringBuilder(); //條件們 List params = new ArrayList(); //判斷參數是否有值 if(rname!=null&&rname.length()>0){ sb.append("and t.rname like ?"); params.add("%"+rname+"%"); } if(first!=0){ sb.append("and t.price > ? "); //添加?對應的值 params.add(first); } if(last!=0){ sb.append("and t.price < ? "); //添加?對應的值 params.add(last); } //分頁 sb.append("limit ? , ? "); sql += sb.toString(); params.add(start); params.add(pageSize); return template.query(sql,new BeanPropertyRowMapper<>(Route.class),params.toArray()); }
面前可以完成需求,只是比較繁瑣,不知有沒有更好的方案,歡迎交流。
console.log("5">"123");
結果是true,由於字符串比較回從前向後依次比較,若是但願數值比較,能夠利用parseInt(first) > parseInt(last)
。""
,而不是null
,調用favoriteRank(null, rname, first, last)
,會形成javascript:favoriteRank(2,,,)
函數調用失敗。我想了個很蠢辦法:在調用以前對參數進行判斷,若是爲""
,就認爲賦null。if (rname === "" && first === "" && last === "") { favoriteRank(null, null, null, null) } else if (rname === "" && first === "") { favoriteRank(null, null, null, last) } else if (rname === "") { favoriteRank(null, null, first, last) } else { favoriteRank(null, rname, first, last) }
這樣子就能夠解決了:
整體來講在看視頻學習的時候可以跟上思路,也許跟項目複雜度不高有些許關係。
在一些小知識掌握的不夠紮實,致使許多細節的地方四處尋找博客,時間消耗較多。
還有一個明顯的感覺就是,聽的時候都會,本身作的時候就有點猶豫,生怕哪裏搞錯。
本身也對項目自己不足之處進行優化,例如驗證碼刷新失效、某些頁面跳轉、代碼部分重構等,這個過程仍是挺鍛鍊個人排錯糾錯能力,debug漸漸熟練,本來的一些問題就愈加容易解決。
最重要的一點:在敲代碼前必定要肯定本身的思路,有了思路,寫起來真的很清晰!看老師從前臺分析到後臺,從servlet到service,再到dao,每一層的任務都劃分得清清楚楚,真的值得我學習再學習。
最近在培養這種列提綱的意識,真的吃邏輯,但列出來以後就感受本身仍是能行的,無非就是消耗的時間多一點。
其實以前看過一些spring,看到一些依賴注入的問題,其實理解沒有那麼深入的,又回過頭來練練web項目,理解又更加深入一些。
一塊兒奮戰的兄弟們,加油!