Java Web開發實踐 - 開發過程

#系統入口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進行返回。

相關文章
相關標籤/搜索