#系統入口javascript
首先根據系統入口文檔,進行開發 ##1. 登陸頁 ###LoginController 首先根據登陸文檔編寫Controllercss
package com.hava.contentsale.login.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * Created by zhanpeng on 11/11/2016. */ @Controller public class LoginController { @RequestMapping(value = "/login") public String login_view() { return "login"; } }
###Spring配置FreeMarker 因爲沒有在配置文件中配置FreeMarker模板,須要變動配置,添加以下配置html
<!-- FreeMarket在這裏進行prefix的設置 --> <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <property name="templateLoaderPath" value="/template" /> <property name="freemarkerSettings"> <props> <prop key="defaultEncoding">utf8</prop> </props> </property> </bean> <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <property name="viewResolvers"> <!-- FreeMarker ViewResolver --> <bean id="freeMarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"> <property name="cache" value="true" /> <property name="suffix" value=".ftl" /> <property name="prefix" value="" /> <property name="contentType" value="text/html; charset=utf-8" /> </bean> <!-- 這裏還能夠添加JSP的viewResolver --> </property> <property name="defaultViews"> <list> <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" /> <!-- 能夠添加更多的XML、PDF等 --> </list> </property> </bean>
###FreeMarker模板異常 - 沒有忽略對象 直接運行發生異常,異常報告以下java
FreeMarker template error: The following has evaluated to null or missing: ==> user [in template "include/header.ftl" at line 5, column 14]
報告位置mysql
<#if user> ... </#if>
因爲在FreeMarker模板當中,若是沒有user對象,報告異常,應當按照以下方式變動web
<#if user??> ... </#if>
###資源文件沒法加載 登陸界面後,看到的是素雅的html,而沒有js和css 有兩種方法能夠解決
方案1:Spring靜態資源spring
<!-- 用於頁面框架裏面的靜態頁面 --> <mvc:resources mapping="/css/**" location="/css/" /> <mvc:resources mapping="/html/**" location="/html/" /> <mvc:resources mapping="/js/**" location="/js/" /> <!-- DefaultServletHttpRequestHandler檢查對進入DispatcherServlet的URL進行篩查,若是發現是靜態資源的請求,就將該請求轉由Web應用服務器默認的Servlet處理 --> <mvc:default-servlet-handler />
方案2:在web.xml直接使用tomcat的默認Servlet進行處理sql
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.jpg</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.js</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.css</url-pattern> </servlet-mapping>
因爲方案一的通用性更強,選擇方案一。數據庫
###FreeMarker靜態資源相對路徑 默認給出的css,js等靜態資源是使用的以下方式apache
<link rel="stylesheet" href="/css/style.css"/>
當咱們在部署war時,沒有部署的ROOT,則訪問的URL以下,是沒法訪問資源的
http://localhost:8080/css/style.css
當咱們的war名稱爲content_sale時,咱們實際的css所在目錄爲
http://localhost:8080/content_sale/css/style.css
這時,須要對ftl模板和FreeMarker配置進行修改,修改配置以下:
<!-- FreeMarker ViewResolver --> <bean id="freeMarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"> <property name="cache" value="true" /> <property name="suffix" value=".ftl" /> <property name="prefix" value="" /> <property name="contentType" value="text/html; charset=utf-8" /> <!-- 經過request獲取context_path --> <property name="requestContextAttribute" value="request" /> </bean>
須要動態路徑的ftl修改以下
<link rel="stylesheet" href="${request.contextPath}/css/style.css"/>
這樣就能夠直接訪問
##2. 退出 LogoutController
package com.hava.contentsale.login.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * Created by zhanpeng on 11/11/2016. */ @Controller public class LogoutController { @RequestMapping(value = "/logout") public String logout_view() { return "login"; } }
##3. 展現頁 首先進行頁面的映射
package com.hava.contentsale.index.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * Created by zhanpeng on 2016/11/11. */ @Controller public class IndexController { @RequestMapping(value = "/") public String index_view() { return "index"; } }
運行發現以下錯誤內容:僅僅展現部分錯誤內容
嚴重: Error executing FreeMarker template FreeMarker template error: The following has evaluated to null or missing: ==> RequestParameters['type'] [in template "index.ftl" at line 7, column 21]
該問題的錯誤模板代碼內容以下
<#assign listType = RequestParameters['type']> <div class="g-doc"> <div class="m-tab m-tab-fw m-tab-simple f-cb"> <div class="tab"> <ul> <li <#if !listType || listType != 1>class="z-sel"</#if> ><a href="/">全部內容</a></li> <#if user && user.usertype == 0><li <#if listType == 1>class="z-sel"</#if> ><a href="/?type=1">未購買的內容</a></li></#if>
該問題是因爲ftl模板文件使用的是FreeMarker 1.7之前的語法進行編寫,並不規範。有兩種解決方式,一種修改正ftl文件,爲新的FreeMarker語法版本,另一種解決方法,修改配置文件
<!-- FreeMarket在這裏進行prefix的設置 --> <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <property name="templateLoaderPath" value="/template" /> <property name="freemarkerSettings"> <props> <prop key="defaultEncoding">utf8</prop> <!-- 開啓FreeMarker的傳統模式,自動忽略空值 --> <prop key="classic_compatible">true</prop> </props> </property> </bean>
修正ftl四處context_path,詳細略
因爲需求當中須要判斷user和product,則須要傳遞freemarker的view的同時,還須要傳遞數據內容。則須要使用ModelAndView對象進行傳遞,重寫Controller
@RequestMapping(value = "/") public ModelAndView index_view() { ModelAndView modelAndView = new ModelAndView("index"); return modelAndView; }
####編寫數據層DAO 因爲index的接口,與ftl界面的用戶的名稱都是user,而數據庫當中的表是person,須要進行轉換。
因爲index的接口描述,與ftl界面的產品名稱都是product,而數據庫表是content,須要進行轉換。
因爲User和Product均爲顯示層內容,則對象名稱爲UserVO與ProductVO,代碼以下: UserVO
public class UserVO { String username; byte usertype; // Getter and Setter }
ProductVO
public class ProductVO { long id; String title; String image; long price; boolean isBuy; boolean isSell; // Getter and Setter }
因爲須要對兩張表進行聯合查詢,則使用以下Dao
package com.hava.contentsale.dao; import com.hava.contentsale.meta.ProductVO; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import java.util.List; /** * Created by zhanpeng on 17/11/2016. */ public interface ProductVODao { @Select("SELECT content.id,content.title,content.icon AS image,content.price,IF(trx.contentId,True,False) AS isSell,IF(trx.personId = #{param1},True,False) AS isBuy FROM content LEFT JOIN trx ON content.id = trx.contentId;") public List<ProductVO> findAll(long user_id); }
注意:這裏使用了MySQL特有的語法IF ###修改數據庫鏈接 因爲是MySQL,在數據庫鏈接時須要按照以下內容進行添加
jdbc.driverClassName= com.mysql.jdbc.Driver jdbc.url= jdbc:mysql://192.168.1.200:3306/content_sale?useUnicode=true&characterEncoding=UTF-8 jdbc.username=root jdbc.password=xxxxxx
這樣纔可以保證數據庫讀取是列爲varchar存儲時不發生錯誤
###Service 這裏只展現實現部分
package com.hava.contentsale.service.impl; import com.hava.contentsale.dao.ContentDao; import com.hava.contentsale.dao.ProductVODao; import com.hava.contentsale.meta.ProductVO; import com.hava.contentsale.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.UnsupportedEncodingException; import java.util.*; /** * Created by yanfa on 2016/11/15. */ @Service public class ProductServiceImpl implements ProductService{ @Autowired ProductVODao productVODao; @Override public List<ProductVO> findAll(long user_id) { return this.productVODao.findAll(user_id); } }
###鏈接Service與Controller
package com.hava.contentsale.web.controller; import com.hava.contentsale.meta.UserVO; import com.hava.contentsale.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; /** * Created by zhanpeng on 2016/11/11. */ @Controller public class IndexController { @Autowired ProductService productServiceImpl; @RequestMapping(value = "/") public ModelAndView index_view() { ModelAndView modelAndView = new ModelAndView("index"); modelAndView.addObject("productList",this.productServiceImpl.findAll(1)); return modelAndView; } }
**TODO:**獲取當前用戶沒有實現,僅僅添加了測試用戶的數據內容 ##4. 查看頁 因爲需求致使productVO對象屬性發生變化,則添加屬性
package com.hava.contentsale.meta; import com.hava.contentsale.utils.OutputObject; /** * Created by yanfa on 2016/11/15. */ public class ProductVO extends OutputObject{ long id; String title; String summary; String detail; String image; long price; long buyPrice; boolean isBuy; boolean isSell; // Getter and Setter }
實現查看頁的Dao
package com.hava.contentsale.dao; import com.hava.contentsale.meta.ProductVO; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import java.util.List; /** * Created by zhanpeng on 17/11/2016. */ public interface ProductVODao { @Select("SELECT content.id,content.title,content.icon AS image,content.price,IF(trx.contentId,True,False) AS isSell,IF(trx.personId = #{param1},True,False) AS isBuy " + "FROM content LEFT JOIN trx ON content.id = trx.contentId;") public List<ProductVO> findAll(long user_id); @Select("SELECT content.id,content.title,content.abstract AS summary,content.text AS detail,content.icon AS image,content.price,IF(trx.contentId,True,False) AS isSell,IF(trx.personId = #{param1},True,False) AS isBuy " + "FROM content LEFT JOIN trx ON content.id = trx.contentId WHERE (content.id = #{param2});") public ProductVO findOne(long user_id,long product_id); }
修改Service
package com.hava.contentsale.service.impl; import com.hava.contentsale.dao.ContentDao; import com.hava.contentsale.dao.ProductVODao; import com.hava.contentsale.meta.ProductVO; import com.hava.contentsale.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.UnsupportedEncodingException; import java.util.*; /** * Created by yanfa on 2016/11/15. */ @Service public class ProductServiceImpl implements ProductService{ @Autowired ProductVODao productVODao; @Override public List<ProductVO> findAll(long user_id) { return this.productVODao.findAll(user_id); } @Override public ProductVO findOne(long user_id, long product_id) { ProductVO productVO = this.productVODao.findOne(user_id,product_id); try { productVO.setDetail(new String(productVO.getDetail().getBytes("iso-8859-1"),"UTF-8")); } catch (UnsupportedEncodingException e) { System.out.println("[Exception]:" + e.toString()); } return productVO; } }
編寫Controller
package com.hava.contentsale.web.controller; import com.hava.contentsale.meta.ProductVO; import com.hava.contentsale.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; /** * Created by yanfa on 2016/11/16. */ @Controller public class ShowController { @Autowired ProductService productServiceImpl; @RequestMapping(value = "/show") public ModelAndView index_view(@RequestParam("id") long id) { ModelAndView modelAndView = new ModelAndView("show"); //ftl ProductVO productVO = this.productServiceImpl.findOne(1l,id); productVO.printProperties(); modelAndView.addObject("product",productVO); return modelAndView; } }
**TODO:**沒有讀取用戶
##異步數據接口文檔 - 1.登錄 因爲絕大多數的功能都須要用戶登錄,和用戶的信息驗證,包括上面的全部頁面,因此在此實現用戶登錄功能,登錄驗證,功能。
因爲須要全部API都要返回固定的JSONRESULT,則定義以下
package com.hava.contentsale.web.controller.api; /** * Created by yanfa on 2016/11/17. */ public class JsonResult { String code; String message; Object result; // Getter and Setter public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Object getResult() { return result; } public void setResult(Object result) { this.result = result; } }
編寫loginApiController,獲取username、password
package com.hava.contentsale.web.controller.api; import com.hava.contentsale.meta.UserVO; import com.hava.contentsale.service.UserService; import com.hava.contentsale.utils.web.MediaType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpSession; /** * Created by yanfa on 2016/11/16. * */ @Controller @RequestMapping(value = "/api") public class LoginApiController { @Autowired UserService userServiceImpl; @ResponseBody @RequestMapping(value = "/login",method= RequestMethod.POST,produces = MediaType.JSON) public JsonResult api_login(@RequestParam("userName") String username, @RequestParam("password") String password, HttpSession httpSession) { System.out.println("[username]:" + username); System.out.println("[password]:" + password); System.out.println("[session]:" + httpSession.getId()); JsonResult jsonResult = new JsonResult(); UserVO userVO = this.userServiceImpl.getUser(username,password); //TODO:username password 空值檢測,想法是使用AOP+反射進行實現 if(userVO == null) { //根據http響應,須要響應401.1表示登錄失敗 jsonResult.setCode("401.1"); //根據javascript上面所提示的內容進行,以便在界面上彈出登錄失敗 jsonResult.setMessage("登陸失敗"); jsonResult.setResult(false); } else { jsonResult.setCode("200"); jsonResult.setMessage("登錄成功"); jsonResult.setResult(true); } return jsonResult; } }
注意:這裏須要根據js上面的提示內容對message進行返回。