前言
该文档主要介绍如何创建一个简单的、能够正常运行的spring项目。为往后项目的开发提供便利
创建spring项目
创建maven项目
使用sts开发软件创建项目,STS是Spring Tool Suite的简称,该软件是一个基于Eclipse环境的,用于开发spring应用程序的软件。其提供了很多spring相关的辅助工具,为开发项目提供诸多便利。
导入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软件测试
统一返回结果
-
编写返回结果实体类【该类包含成功返回,异常返回与错误返回】
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 /*