list = s.selectList(null); //查询所有对象,null表示没有条件,会返回所有对象,Mybatis-Plus的特性
48 | if(!list.isEmpty()){
49 | return Rest.okData(list);
50 | }
51 | throw new NotFindDataException("未查询到任何对象");
52 |
53 | }
54 |
55 | @GetMapping("/{id}")
56 | public Rest get(@PathVariable("id") Serializable id){
57 |
58 | if(id==null){
59 | throw new RuntimeException("参数{id}不能为空");
60 | }
61 | if(id instanceof String){
62 | if(StringUtils.isBlank((String)id)){
63 | throw new RuntimeException("参数{id}不能为空");
64 | }
65 | }
66 | T t = s.selectById(id);
67 | if(t != null){
68 | return Rest.okData(t);
69 | }
70 | throw new NotFindDataException(String.format("id为[%s]的对象不存在",id));
71 | }
72 |
73 | /**
74 | * 创建对象
75 | * @param t
76 | * @param result 验证器,和Mode层配合使用
77 | * @return
78 | */
79 | @PostMapping
80 | public Rest add(@Valid T t,BindingResult result){
81 |
82 | if(result.hasErrors()){
83 | return Rest.failure(500,"参数验证失败",ValidateUtil.toStringJson(result),"error");
84 | }
85 | s.insert(t);
86 | return Rest.ok();
87 | }
88 |
89 | @PutMapping
90 | public Rest update(@Valid T t,BindingResult result){
91 | if(result.hasErrors()){
92 | return Rest.failure(500,"参数验证失败",ValidateUtil.toStringJson(result),"error");
93 | }
94 | s.updateById(t);
95 | return Rest.ok();
96 | }
97 |
98 | /**
99 | * 删除对象
100 | * @param id
101 | * @return
102 | */
103 | @DeleteMapping("/{id}")
104 | public Rest delete(@PathVariable("id") Serializable id){
105 |
106 | if(id==null){
107 | throw new RuntimeException("参数{id}不能为空");
108 | }
109 | if(id instanceof String){
110 | if(StringUtils.isBlank((String)id)){
111 | throw new RuntimeException("参数{id}不能为空");
112 | }
113 | }
114 | T t = s.selectById(id);
115 | if(t== null){
116 | throw new NotFindDataException("要删除的对象不存在");
117 | }else if(s.deleteById(id)){
118 | return Rest.ok("删除成功");
119 | }else{
120 | throw new RuntimeException("糟糕,删除失败");
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/restful-api-core/src/main/java/com/restful/api/core/ex/ForbidAccessException.java:
--------------------------------------------------------------------------------
1 | package com.restful.api.core.ex;
2 |
3 | /**
4 | * 禁止访问异常
5 | * Created by Gaojun.Zhou 2017年6月8日
6 | */
7 | public class ForbidAccessException extends RuntimeException{
8 |
9 | private static final long serialVersionUID = 1L;
10 |
11 | public ForbidAccessException() {
12 | super();
13 | // TODO Auto-generated constructor stub
14 | }
15 |
16 | public ForbidAccessException(String message, Throwable cause, boolean enableSuppression,
17 | boolean writableStackTrace) {
18 | super(message, cause, enableSuppression, writableStackTrace);
19 | // TODO Auto-generated constructor stub
20 | }
21 |
22 | public ForbidAccessException(String message, Throwable cause) {
23 | super(message, cause);
24 | // TODO Auto-generated constructor stub
25 | }
26 |
27 | public ForbidAccessException(String message) {
28 | super(message);
29 | // TODO Auto-generated constructor stub
30 | }
31 |
32 | public ForbidAccessException(Throwable cause) {
33 | super(cause);
34 | // TODO Auto-generated constructor stub
35 | }
36 |
37 |
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/restful-api-core/src/main/java/com/restful/api/core/ex/NotFindDataException.java:
--------------------------------------------------------------------------------
1 | package com.restful.api.core.ex;
2 |
3 | /**
4 | * 未查到数据异常
5 | * Created by Gaojun.Zhou 2017年6月8日
6 | */
7 | public class NotFindDataException extends RuntimeException{
8 |
9 | private int code = 604 ;
10 |
11 |
12 | public int getCode() {
13 | return code;
14 | }
15 |
16 | public void setCode(int code) {
17 | this.code = code;
18 | }
19 |
20 | /**
21 | *
22 | */
23 | private static final long serialVersionUID = 1L;
24 |
25 | public NotFindDataException() {
26 | super();
27 | // TODO Auto-generated constructor stub
28 | }
29 |
30 | public NotFindDataException(String message, Throwable cause, boolean enableSuppression,
31 | boolean writableStackTrace) {
32 | super(message, cause, enableSuppression, writableStackTrace);
33 | // TODO Auto-generated constructor stub
34 | }
35 |
36 | public NotFindDataException(String message, Throwable cause) {
37 | super(message, cause);
38 | // TODO Auto-generated constructor stub
39 | }
40 |
41 | public NotFindDataException(String message) {
42 | super(message);
43 | // TODO Auto-generated constructor stub
44 | }
45 |
46 | public NotFindDataException(Throwable cause) {
47 | super(cause);
48 | // TODO Auto-generated constructor stub
49 | }
50 |
51 |
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/restful-api-core/src/main/java/com/restful/api/core/jackson/CustomObjectMapper.java:
--------------------------------------------------------------------------------
1 | package com.restful.api.core.jackson;
2 |
3 | import java.text.DateFormat;
4 | import java.text.SimpleDateFormat;
5 |
6 | import org.springframework.util.StringUtils;
7 |
8 | import com.fasterxml.jackson.annotation.JsonInclude;
9 | import com.fasterxml.jackson.databind.ObjectMapper;
10 | import com.fasterxml.jackson.databind.PropertyNamingStrategy;
11 | import com.fasterxml.jackson.databind.SerializationFeature;
12 |
13 | /**
14 | * Json转换配置
15 | * @author Administrator
16 | *
17 | */
18 | public class CustomObjectMapper extends ObjectMapper {
19 |
20 | /**
21 | *
22 | */
23 | private static final long serialVersionUID = 1L;
24 |
25 | private boolean camelCaseToLowerCaseWithUnderscores = false;
26 | private String dateFormatPattern;
27 |
28 | public void setCamelCaseToLowerCaseWithUnderscores(
29 | boolean camelCaseToLowerCaseWithUnderscores) {
30 | this.camelCaseToLowerCaseWithUnderscores = camelCaseToLowerCaseWithUnderscores;
31 | }
32 |
33 | public void setDateFormatPattern(String dateFormatPattern) {
34 | this.dateFormatPattern = dateFormatPattern;
35 | }
36 |
37 | public void init() {
38 | // 排除值为空属性
39 | setSerializationInclusion(JsonInclude.Include.NON_NULL);
40 | // 进行缩进输出
41 | configure(SerializationFeature.INDENT_OUTPUT, true);
42 | // 将驼峰转为下划线
43 | if (camelCaseToLowerCaseWithUnderscores) {
44 | setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
45 | }
46 | // 进行日期格式化
47 | if (!StringUtils.isEmpty(dateFormatPattern)) {
48 | DateFormat dateFormat = new SimpleDateFormat(dateFormatPattern);
49 | setDateFormat(dateFormat);
50 | }
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/restful-api-core/src/main/java/com/restful/api/core/jsonp/JsonpSupportAdvice.java:
--------------------------------------------------------------------------------
1 | package com.restful.api.core.jsonp;
2 | import org.springframework.web.bind.annotation.ControllerAdvice;
3 | import org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice;
4 | /**
5 | * JSONP支持
6 | * @author Administrator
7 | *
8 | */
9 | @ControllerAdvice
10 | public class JsonpSupportAdvice extends AbstractJsonpResponseBodyAdvice {
11 | public JsonpSupportAdvice() {
12 | //参数包含callback的时候 使用jsonp返回数据
13 | super("callback");
14 | }
15 | }
--------------------------------------------------------------------------------
/restful-api-core/src/main/java/com/restful/api/core/log/LogAdvice.java:
--------------------------------------------------------------------------------
1 | package com.restful.api.core.log;
2 |
3 | import java.lang.reflect.Method;
4 | import java.util.Date;
5 |
6 | import javax.servlet.http.HttpServletRequest;
7 |
8 | import org.apache.log4j.Logger;
9 | import org.aspectj.lang.JoinPoint;
10 | import org.aspectj.lang.annotation.AfterReturning;
11 | import org.aspectj.lang.annotation.Aspect;
12 | import org.aspectj.lang.annotation.Pointcut;
13 | import org.aspectj.lang.reflect.MethodSignature;
14 | import org.springframework.beans.factory.annotation.Autowired;
15 | import org.springframework.stereotype.Component;
16 | import org.springframework.web.context.request.RequestContextHolder;
17 | import org.springframework.web.context.request.ServletRequestAttributes;
18 |
19 | import com.google.gson.Gson;
20 | import com.restful.api.core.anno.Log;
21 | import com.restful.api.core.util.IpUtil;
22 | /**
23 | * 正常业务日志记录
24 | * @author Administrator
25 | *
26 | */
27 | @Aspect
28 | @Component
29 | public class LogAdvice {
30 |
31 | public static final Logger logger = Logger.getLogger(LogAdvice.class);
32 |
33 | /**
34 | * 注入日志记录接口,若存在则记录日志,不存在就忽略
35 | */
36 | @Autowired(required=false) LogApi logApi;
37 |
38 | @Pointcut("@annotation(com.restful.api.core.anno.Log)")
39 | public void controllerAspect() {
40 |
41 | }
42 | /**
43 | * 当方法正常返回是执行
44 | * @param joinPoint
45 | */
46 | @AfterReturning("controllerAspect()")
47 | public void doBefore(JoinPoint joinPoint) {
48 |
49 | MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
50 | Method method = methodSignature.getMethod();
51 | Log log = method.getAnnotation(Log.class);
52 | if(log != null){
53 | String logTitle = log.title();
54 | String logContent = log.value();
55 | logger.debug("logs:[logTitle:"+logTitle+"][logContent:"+logContent+"]");
56 | if(logApi != null){
57 | HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
58 | LogBean logBean = new LogBean();
59 | logBean.setLogTitle(logTitle);
60 | logBean.setLogTime(new Date());
61 | logBean.setLogContent(logContent);
62 | logBean.setRequestMethod(request.getMethod());
63 | logBean.setClientIp(IpUtil.getIpAddr(request));
64 | logBean.setRequestParams(new Gson().toJson(request.getParameterMap()));
65 | logger.debug("logBean:"+logBean.toString());
66 | logApi.log(logBean);
67 | }else{
68 | logger.warn("LogApi not finish.");
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/restful-api-core/src/main/java/com/restful/api/core/log/LogApi.java:
--------------------------------------------------------------------------------
1 | package com.restful.api.core.log;
2 |
3 | /**
4 | * 记录日志接口
5 | * Created by Gaojun.Zhou 2017年6月20日
6 | */
7 | public interface LogApi {
8 |
9 | /**
10 | * 记录日志
11 | * @param log
12 | */
13 | void log(LogBean log);
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/restful-api-core/src/main/java/com/restful/api/core/log/LogBean.java:
--------------------------------------------------------------------------------
1 | package com.restful.api.core.log;
2 |
3 | import java.util.Date;
4 |
5 | /**
6 | * 日志对象
7 | * Created by Gaojun.Zhou 2017年6月20日
8 | */
9 | public class LogBean {
10 |
11 | /**
12 | * 日志标题
13 | */
14 | private String logTitle;
15 | /**
16 | * 日志内容
17 | */
18 | private String logContent;
19 | /**
20 | * 客户端IP
21 | */
22 | private String clientIp;
23 | /**
24 | * 日志时间
25 | */
26 | private Date logTime;
27 | /**
28 | * 请求方法
29 | */
30 | private String requestMethod;
31 | /**
32 | * 请求参数
33 | */
34 | private String requestParams;
35 |
36 | /**
37 | * 其他数据
38 | */
39 | private String other;
40 |
41 | public String getLogTitle() {
42 | return logTitle;
43 | }
44 |
45 | public void setLogTitle(String logTitle) {
46 | this.logTitle = logTitle;
47 | }
48 |
49 | public String getLogContent() {
50 | return logContent;
51 | }
52 |
53 | public void setLogContent(String logContent) {
54 | this.logContent = logContent;
55 | }
56 |
57 | public String getClientIp() {
58 | return clientIp;
59 | }
60 |
61 | public void setClientIp(String clientIp) {
62 | this.clientIp = clientIp;
63 | }
64 |
65 | public Date getLogTime() {
66 | return logTime;
67 | }
68 |
69 | public void setLogTime(Date logTime) {
70 | this.logTime = logTime;
71 | }
72 |
73 |
74 | public String getRequestParams() {
75 | return requestParams;
76 | }
77 |
78 | public void setRequestParams(String requestParams) {
79 | this.requestParams = requestParams;
80 | }
81 |
82 | public String getRequestMethod() {
83 | return requestMethod;
84 | }
85 |
86 | public void setRequestMethod(String requestMethod) {
87 | this.requestMethod = requestMethod;
88 | }
89 |
90 | public String getOther() {
91 | return other;
92 | }
93 |
94 | public void setOther(String other) {
95 | this.other = other;
96 | }
97 |
98 | @Override
99 | public String toString() {
100 | return "LogBean [logTitle=" + logTitle + ", logContent=" + logContent + ", clientIp=" + clientIp + ", logTime="
101 | + logTime + ", requestMethod=" + requestMethod + ", requestParams=" + requestParams + ", other=" + other
102 | + "]";
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/restful-api-core/src/main/java/com/restful/api/core/util/IpUtil.java:
--------------------------------------------------------------------------------
1 | package com.restful.api.core.util;
2 |
3 | import java.net.InetAddress;
4 | import java.net.UnknownHostException;
5 |
6 | import javax.servlet.http.HttpServletRequest;
7 |
8 | import org.apache.log4j.Logger;
9 |
10 | /**
11 | * IP工具类
12 | * Created by Gaojun.Zhou 2017年6月22日
13 | */
14 | public class IpUtil {
15 |
16 |
17 | private static final Logger logger = Logger.getLogger("IpHelper");
18 |
19 | private static String LOCAL_IP_STAR_STR = "192.168.";
20 |
21 | static {
22 | String ip = null;
23 | String hostName = null;
24 | try {
25 | hostName = InetAddress.getLocalHost().getHostName();
26 | InetAddress ipAddr[] = InetAddress.getAllByName(hostName);
27 | for (int i = 0; i < ipAddr.length; i++) {
28 | ip = ipAddr[i].getHostAddress();
29 | if (ip.startsWith(LOCAL_IP_STAR_STR)) {
30 | break;
31 | }
32 | }
33 | if (ip == null) {
34 | ip = ipAddr[0].getHostAddress();
35 | }
36 |
37 | } catch (UnknownHostException e) {
38 | logger.error("IpHelper error.");
39 | e.printStackTrace();
40 | }
41 |
42 | LOCAL_IP = ip;
43 | HOST_NAME = hostName;
44 |
45 | }
46 |
47 | /** 系统的本地IP地址 */
48 | public static final String LOCAL_IP;
49 |
50 | /** 系统的本地服务器名 */
51 | public static final String HOST_NAME;
52 |
53 | /**
54 | *
55 | * 获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。
56 | * 但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了,如果通过了多级反向代理的话,
57 | * X-Forwarded-For的值并不止一个,而是一串IP值, 究竟哪个才是真正的用户端的真实IP呢?
58 | * 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。
59 | * 例如:X-Forwarded-For:192.168.1.110, 192.168.1.120,
60 | * 192.168.1.130, 192.168.1.100 用户真实IP为: 192.168.1.110
61 | *
62 | *
63 | * @param request
64 | * @return
65 | */
66 | public static String getIpAddr(HttpServletRequest request) {
67 | String ip = request.getHeader("x-forwarded-for");
68 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
69 | ip = request.getHeader("Proxy-Client-IP");
70 | }
71 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
72 | ip = request.getHeader("WL-Proxy-Client-IP");
73 | }
74 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
75 | ip = request.getRemoteAddr();
76 | if (ip.equals("127.0.0.1")) {
77 | /** 根据网卡取本机配置的IP */
78 | InetAddress inet = null;
79 | try {
80 | inet = InetAddress.getLocalHost();
81 | ip = inet.getHostAddress();
82 | } catch (UnknownHostException e) {
83 | logger.error("IpHelper error." + e.toString());
84 | }
85 | }
86 | }
87 | /**
88 | * 对于通过多个代理的情况, 第一个IP为客户端真实IP,多个IP按照','分割 "***.***.***.***".length() =
89 | * 15
90 | */
91 | if (ip != null && ip.length() > 15) {
92 | if (ip.indexOf(",") > 0) {
93 | ip = ip.substring(0, ip.indexOf(","));
94 | }
95 | }
96 | return ip;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/restful-api-core/src/main/java/com/restful/api/core/util/ValidateUtil.java:
--------------------------------------------------------------------------------
1 | package com.restful.api.core.util;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | import org.springframework.validation.BindingResult;
7 | import org.springframework.validation.FieldError;
8 |
9 | /**
10 | * 验证工具类
11 | * Created by Gaojun.Zhou 2017年6月22日
12 | */
13 | public class ValidateUtil {
14 |
15 | public static Map toStringJson(BindingResult result){
16 |
17 | Map map = new HashMap();
18 |
19 | for(FieldError fieldError : result.getFieldErrors()){
20 | map.put(fieldError.getField(), fieldError.getDefaultMessage());
21 | }
22 |
23 | return map;
24 |
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/restful-api-web/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.vaco
8 | restful-api
9 | 0.0.1-SNAPSHOT
10 |
11 | restful-api-web
12 | war
13 | restful-api-web Maven Webapp
14 | http://maven.apache.org
15 |
16 |
17 |
18 | com.vaco
19 | restful-api-core
20 | 0.0.1-SNAPSHOT
21 |
22 |
23 |
24 |
25 | io.springfox
26 | springfox-swagger2
27 |
28 |
29 | io.springfox
30 | springfox-swagger-ui
31 |
32 |
33 | com.fasterxml
34 | classmate
35 |
36 |
37 |
38 |
39 | org.apache.velocity
40 | velocity
41 | 1.7
42 | test
43 |
44 |
45 |
46 |
47 | restful-api-web
48 |
49 |
50 |
51 |
52 | src/main/java
53 |
54 | **/*.xml
55 |
56 | false
57 |
58 |
59 |
60 |
61 |
62 | org.mortbay.jetty
63 | jetty-maven-plugin
64 | 8.1.16.v20140903
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/restful-api-web/src/main/java/com/restful/api/web/component/RestExceptionAdvice.java:
--------------------------------------------------------------------------------
1 | package com.restful.api.web.component;
2 |
3 | import org.springframework.web.bind.annotation.ControllerAdvice;
4 | import org.springframework.web.bind.annotation.ResponseBody;
5 |
6 | import com.restful.api.core.advice.ExceptionAdvice;
7 |
8 | /**
9 | * 全局异常处理
10 | * Created by Gaojun.Zhou 2017年6月20日
11 | */
12 | @ControllerAdvice
13 | @ResponseBody
14 | public class RestExceptionAdvice extends ExceptionAdvice{
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/restful-api-web/src/main/java/com/restful/api/web/component/SwaggerConfig.java:
--------------------------------------------------------------------------------
1 | package com.restful.api.web.component;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 |
6 | import springfox.documentation.builders.ApiInfoBuilder;
7 | import springfox.documentation.builders.PathSelectors;
8 | import springfox.documentation.service.ApiInfo;
9 | import springfox.documentation.service.Contact;
10 | import springfox.documentation.spi.DocumentationType;
11 | import springfox.documentation.spring.web.plugins.Docket;
12 | import springfox.documentation.swagger2.annotations.EnableSwagger2;
13 |
14 | /**
15 | * swagger-ui配置
16 | * Created by Gaojun.Zhou 2017年6月19日
17 | */
18 | @EnableSwagger2
19 | @Configuration
20 | public class SwaggerConfig {
21 |
22 | @Bean
23 | public Docket createRestApi() {
24 | return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
25 | //.apis(RequestHandlerSelectors.basePackage("com.vacomall.controller"))
26 | .paths(PathSelectors.any())
27 | .build();
28 | }
29 |
30 | private ApiInfo apiInfo() {
31 | return new ApiInfoBuilder().title("restful-api,Restfull接口生成框架")
32 | .termsOfServiceUrl("http://blog.jdoop.cn/")
33 | .description("springmvc + swagger2 Restfull接口生成框架")
34 | .contact(new Contact("JamesZhou", "http://blog.jdoop.cn/", "gaojun.zhou@qq.com"))
35 | .version("1.0.0")
36 | .build();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/restful-api-web/src/main/java/com/restful/api/web/controller/BlogController.java:
--------------------------------------------------------------------------------
1 | package com.restful.api.web.controller;
2 |
3 | import java.util.Map;
4 |
5 | import org.springframework.web.bind.annotation.GetMapping;
6 | import org.springframework.web.bind.annotation.RequestMapping;
7 | import org.springframework.web.bind.annotation.RequestParam;
8 | import org.springframework.web.bind.annotation.RestController;
9 |
10 | import com.baomidou.mybatisplus.plugins.Page;
11 | import com.restful.api.core.Rest;
12 | import com.restful.api.core.anno.ForbidMethod;
13 | import com.restful.api.core.anno.Log;
14 | import com.restful.api.core.controller.AppController;
15 | import com.restful.api.web.entity.Blog;
16 | import com.restful.api.web.service.IBlogService;
17 | /**
18 | * 标准的Rest接口,实例控制器
19 | * Created by Gaojun.Zhou 2017年6月8日
20 | */
21 | @RestController
22 | @RequestMapping("/blog")
23 | @ForbidMethod({"delete"}) //禁止客户端调用delete方法,可穿入多个参数
24 | public class BlogController extends AppController{
25 |
26 | /**
27 | * 自定义方法分页多表连接查询博客
28 | */
29 | @GetMapping("/findJoinPage")
30 | public Rest findJoinPage(@RequestParam (required = true,defaultValue="1")
31 | Integer page,@RequestParam (defaultValue="10")Integer size){
32 | Page