前言

该文档主要介绍如何创建一个简单的、能够正常运行的spring项目。为往后项目的开发提供便利

创建spring项目

创建maven项目

使用sts开发软件创建项目,STS是Spring Tool Suite的简称,该软件是一个基于Eclipse环境的,用于开发spring应用程序的软件。其提供了很多spring相关的辅助工具,为开发项目提供诸多便利。

创建spring项目步骤一_第1张图片

导入spring-mvc jar包

编辑spring项目的pom.xml文件,加入spring-mvc容器 相关jar依赖、spring-ioc容器相关的jar


    4.0.0
    com.bear.simple_spring
    simple_spring
    0.0.1-SNAPSHOT

    
        
        
            org.springframework
            spring-webmvc
            5.1.2.RELEASE
        
        
            org.springframework
            spring-web
            5.1.2.RELEASE
        
        
        
            com.fasterxml.jackson.core
            jackson-databind
            2.9.8
        
        
            com.fasterxml
            classmate
            1.4.0
        
    
配置servlet容器web.xml
  • 编辑web.xml文件,让servlet容器启动的时候加载spring-mvc配置文件及spring-ioc的配置文件,以启动spring-mvc容器与spring-ioc容器


    
    
        springDispatcherServlet
        org.springframework.web.servlet.DispatcherServlet
        
            contextConfigLocation
            
            classpath:spring-mvc.xml
        
        1
    
    
    
        springDispatcherServlet
        
        /
    

    
    
        contextConfigLocation
        classpath:spring-beans.xml
    
    
        org.springframework.web.context.ContextLoaderListener
    
创建spring-mvc容器的配置文件【spring-mvc.xml】

创建spring-mvc的配置文件



    
    
        
        
        
    

    
    
        
        
    

    
    

    
    

创建spring-ioc容器的配置文件【spring-beans.xml】


    
    
        
               
    

测试spring-mvc项目是否创建成功
  • 编写controller

    package com.bear.simple.spring.controller;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.bear.simple.spring.entity.Account;
    import com.bear.simple.spring.service.AccountService;
    
    @RestController
    @RequestMapping("account")
    public class AccountController {
    
    @Autowired
    private AccountService accountService;
    
    /**
     * 获取帐号信息
     * @param id
     * @param request
     * @return
     */
    @RequestMapping("/get")
    public Account getAccount(@RequestParam String id,HttpServletRequest request) {
        if(null == id || "".equals(id)) 
            throw new RuntimeException("请求参数缺少id");
        Account result = accountService.loadAccountById(id);
        return result;
    }
    }
  • 编写实体层

    package com.bear.simple.spring.entity;
    
    /**
    * 登陆帐号信息
    * @author bear
    *
    *
    public class Account {
    //登陆帐号ID
    private String id;
    //登陆帐号
    private String acccountNo;
    //帐号密码
    private String password;
    //帐号描述
    private String desc;
    //帐号是否启用 0 禁用 1启用,默认为启用
    private int enable = 1;
    
    public Account(String id, String acccountNo, String password) {
        super();
        this.id = id;
        this.acccountNo = acccountNo;
        this.password = password;
    }
    
    public Account(String id, String acccountNo, String password, String desc, int enable) {
        super();
        this.id = id;
        this.acccountNo = acccountNo;
        this.password = password;
        this.desc = desc;
        this.enable = enable;
    }
    
    public Account() {
        super();
    }
    
    public String getId() {
        return id;
    }
    
    public void setId(String id) {
        this.id = id;
    }
    
    public String getAcccountNo() {
        return acccountNo;
    }
    
    public void setAcccountNo(String acccountNo) {
        this.acccountNo = acccountNo;
    }
    
    public String getPassword() {
        return password;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }
    
    public int getEnable() {
        return enable;
    }
    
    public void setEnable(int enable) {
        this.enable = enable;
    }
    
    public Boolean isEnable() {
        return 1 == this.enable;
    }
    
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((acccountNo == null) ? 0 : acccountNo.hashCode());
        result = prime * result + ((desc == null) ? 0 : desc.hashCode());
        result = prime * result + enable;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        result = prime * result + ((password == null) ? 0 : password.hashCode());
        return result;
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Account other = (Account) obj;
        if (acccountNo == null) {
            if (other.acccountNo != null)
                return false;
        } else if (!acccountNo.equals(other.acccountNo))
            return false;
        if (desc == null) {
            if (other.desc != null)
                return false;
        } else if (!desc.equals(other.desc))
            return false;
        if (enable != other.enable)
            return false;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        if (password == null) {
            if (other.password != null)
                return false;
        } else if (!password.equals(other.password))
            return false;
        return true;
    }
    
    @Override
    public String toString() {
        return "Account [id=" + id + ", acccountNo=" + acccountNo + ", password=" + password + ", desc=" + desc
                + ", enable=" + enable + "]";
    }
    
    }
  • 编写服务层

    package com.bear.simple.spring.service;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Optional;
    
    import org.springframework.stereotype.Service;
    
    import com.bear.simple.spring.entity.Account;
    
    @Service
    public class AccountService {
    
    private static final Map cache = new HashMap();
    
    static {
        cache.put("1", new Account("1", "黄大仙", "123456"));
        cache.put("2", new Account("2", "刘不三", "12345678"));
        cache.put("3", new Account("3", "刘不四", "8888888"));
    }
    
    /**
     * 加载帐号,不存在报异常
     * 
     * @param id
     * @return
     */
    public Account loadAccountById(String id) {
        Optional accountOpt = findAccountById(id);
        if (!accountOpt.isPresent())
            throw new RuntimeException(String.format("帐号【%s】不存在", id));
        return accountOpt.get();
    }
    
    /**
     * 查找帐号
     * 
     * @param id
     * @return
     */
    public Optional findAccountById(String id) {
        if (null == id || "".equals(id))
            return Optional.empty();
        Account account = cache.get(id);
        return Optional.ofNullable(account);
    }
    
    }
  • 测试请求处理

    使用postman软件测试

    创建spring项目步骤一_第2张图片

统一返回结果
  • 编写返回结果实体类【该类包含成功返回,异常返回与错误返回】

    package com.bear.simple.spring.entity;
    
    import java.io.PrintWriter;
    import java.io.StringWriter;
    
    public class JsonData {
    //是否正确返回
    private final boolean ret;
    //状态码
    private String code = "000";
    //数据
    private Object data;
    //提示信息
    private String msg;
    //异常详细信息
    private String detail;
    
    private JsonData(boolean ret) {
        this.ret = ret;
    }   
    /**
     * 创建错误返回结果
     * @param msg 提示信息
     * @return
     */
    public static JsonData error(String msg) {
        JsonData result = new JsonData(false);
        result.msg = msg;
        result.code = "999";
        return result;
    }
    
    public static JsonData error(String msg,Exception e,String code) {
        JsonData result = new JsonData(false);
        result.msg = msg;
        result.code = code;
        result.detail = getStackTraceInfo(e);
        return result;
    }
    
    public static JsonData error(Exception e) {
        JsonData result = new JsonData(false);
        result.msg = e.getMessage();
        result.code = "999";
        result.detail = getStackTraceInfo(e);
        return result;
    }
    
    public static JsonData error(Exception e,String code) {
        JsonData result = new JsonData(false);
        result.msg = e.getMessage();
        result.code = code;
        result.detail = getStackTraceInfo(e);
        return result;
    }
    
    public static JsonData success(Object data,String msg) {
        JsonData result = new JsonData(true);
        result.msg = msg;
        result.data = data;
        return result;
    }
    public static JsonData success(Object data) {
        return success(data, null);
    }
    
    public static JsonData success() {
        return success(null,null);
    }
    
    public String getCode() {
        return code;
    }
    
    public Object getData() {
        return data;
    }
    
    public String getMsg() {
        return msg;
    }
    
    public String getDetail() {
        return detail;
    }
    
    public boolean isRet() {
        return ret;
    }
    
    /**
     * 打印异常堆栈信息
     * @param e
     * @return
     */
    public static String getStackTraceInfo(Exception e) {
          StringWriter sw = new StringWriter();
          PrintWriter pw = new PrintWriter(sw);
          try {
              e.printStackTrace(pw);
              pw.flush();
              sw.flush();
              return sw.toString();
          } finally {
              try {
                  pw.close();
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
              try {
                  sw.close();
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
          }
      }
    
    }

统一异常处理

编写异常处理控制器(统一处理系统发生的所有异常)

package com.bear.simple.spring.controller;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.bear.simple.spring.entity.JsonData;

@ControllerAdvice
public class ExceptionController {

    /**
     * 处理特定异常
     * @param ex
     * @return
     */
    @ExceptionHandler
    @ResponseBody
    public JsonData handleUserNotExistException(UserNotExistException ex) {
        if(null == ex.getMessage() || "".equals(ex.getMessage()))
            return JsonData.error("用户不存在", ex, "998");
        return JsonData.error(ex, "998");
    }

    /**
     * 处理上述遗漏的异常
     * @param ex
     * @return
     */
    @ExceptionHandler
    @ResponseBody
    public JsonData handleUserNotExistException(Exception ex) {
        if(null == ex.getMessage() || "".equals(ex.getMessage()))
            return JsonData.error("系统发生未知异常", ex, "999");
        return JsonData.error(ex, "999");
    }
}

添加日志处理

  • 日志记录是项目中不可或缺的一部分。它的存在让我们定位问题更为方便。目前使用比较普遍的日志框架有log4j、logback等。当前项目将采用logback。
  • 引用logback相应jar包

            org.slf4j
            slf4j-api
            1.7.21
        
        
            ch.qos.logback
            logback-core
            1.1.7
        
        
            ch.qos.logback
            logback-classic
            1.1.7
        
  • 编写日志配置文件【logback.xml(名称可自定义)】

    
    
    
    
    
    
    
    
    ${appName}
    
    
    
        
        
            %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            
        
    
    
    
    
        ${logFilePath}/testFile.log
        true
        
            %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            
        
    
    
    
    
        
        
            ${logFilePath}/%d{yyyy-MM-dd}.log
            30
        
        
        
            %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            
        
    
    
    
            
            
                INFO
                ACCEPT
                DENY
            
            
            
                ${logFilePath}/timeout/%d{yyyy-MM-dd}.log
                30
            
            
            
                %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
                
            
        
    
    
    
        
        
    
    
    
    
        
        
    
    
  • 使用springmvc启动加载日志配置文件,编辑web.xml文件使用配置监听器加载日志配置文件,只需在web.xml文件中添加如下代码段即可

    
        logbackConfigLocation
        
        C:/developer/apache-tomcat-8.0.32/web_log/logback.xml
    
    
        ch.qos.logback.ext.spring.web.LogbackConfigListener
    

配置统一编码过滤器

  • 配置springmvc接收的所有请求的编码格式为utf-8,只需在web.xml文件中添加字符集过滤器即可,添加的内容如下

    
    
        characterEncodingFilter
        org.springframework.web.filter.CharacterEncodingFilter
        
        
            encoding
            UTF-8
        
        
        
            forceEncoding
            true
        
    
    
        characterEncodingFilter
        /*