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进行返回。

相关文章
相关标签/搜索