增加简单的部署打包脚本

增加 Dubbo 参数校验
This commit is contained in:
YunaiV 2019-02-28 19:28:02 +08:00
parent 5616a3cd8b
commit 0386a736e4
20 changed files with 251 additions and 53 deletions

18
Server.md Normal file
View File

@ -0,0 +1,18 @@
# 前端 Server
* admin 18083
*
# 后端 Server
# 基础服务
## MySQL
## Zookeeper
# 运维
* ssh 端口
* 工作目录 /work2/

View File

@ -113,6 +113,16 @@
</annotationProcessorPaths> </annotationProcessorPaths>
</configuration> </configuration>
</plugin> </plugin>
<!-- 打包 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>

View File

@ -2,12 +2,14 @@ package cn.iocoder.mall.admin.application;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication(scanBasePackages = {"cn.iocoder.mall.admin"}) @SpringBootApplication(scanBasePackages = {"cn.iocoder.mall.admin"})
public class AdminApplication { public class AdminApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(AdminApplication.class, args); ConfigurableApplicationContext ctx = SpringApplication.run(AdminApplication.class, args);
System.out.println(); // TODO 后面去掉这里是临时的
} }
} }

View File

@ -5,10 +5,7 @@ import cn.iocoder.mall.admin.sdk.interceptor.AdminSecurityInterceptor;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@EnableWebMvc @EnableWebMvc
@Configuration @Configuration
@ -36,4 +33,13 @@ public class MVCConfiguration implements WebMvcConfigurer {
registry.addResourceHandler("webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); registry.addResourceHandler("webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
} }
// TODO 芋艿允许跨域
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedHeaders("*")
.allowedMethods("*")
.allowedOrigins("*");
}
} }

View File

@ -11,7 +11,7 @@ import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2; import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration @Configuration
@EnableSwagger2 @EnableSwagger2 // TODO 生产环境时禁用掉
public class SwaggerConfiguration { public class SwaggerConfiguration {
@Bean @Bean
@ -19,7 +19,7 @@ public class SwaggerConfiguration {
return new Docket(DocumentationType.SWAGGER_2) return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo()) .apiInfo(apiInfo())
.select() .select()
.apis(RequestHandlerSelectors.basePackage("cn.iocoder.mall.admin.controller")) .apis(RequestHandlerSelectors.basePackage("cn.iocoder.mall.admin.application.controller"))
.paths(PathSelectors.any()) .paths(PathSelectors.any())
.build(); .build();
} }

View File

@ -4,19 +4,19 @@ import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.admin.api.ResourceService; import cn.iocoder.mall.admin.api.ResourceService;
import cn.iocoder.mall.admin.api.bo.ResourceBO; import cn.iocoder.mall.admin.api.bo.ResourceBO;
import cn.iocoder.mall.admin.api.constant.ResourceType; import cn.iocoder.mall.admin.api.constant.ResourceType;
import cn.iocoder.mall.admin.api.dto.ResourceAddDTO;
import cn.iocoder.mall.admin.application.convert.ResourceConvert; import cn.iocoder.mall.admin.application.convert.ResourceConvert;
import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder;
import cn.iocoder.mall.admin.application.vo.AdminMenuTreeNodeVO; import cn.iocoder.mall.admin.application.vo.AdminMenuTreeNodeVO;
import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder;
import com.alibaba.dubbo.config.annotation.Reference; import com.alibaba.dubbo.config.annotation.Reference;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@RestController @RestController
@ -24,11 +24,13 @@ import java.util.stream.Collectors;
@Api("资源模块") @Api("资源模块")
public class ResourceController { public class ResourceController {
@Reference @Reference(validation = "true")
private ResourceService resourceService; private ResourceService resourceService;
// =========== 当前管理员相关的资源 API ===========
@GetMapping("/admin_menu_tree") @GetMapping("/admin_menu_tree")
@ApiOperation(value = "获得管理员拥有的菜单权限", notes = "以树结构返回") @ApiOperation(value = "获得当前登陆的管理员拥有的菜单权限", notes = "以树结构返回")
public CommonResult<List<AdminMenuTreeNodeVO>> adminMenuTree() { public CommonResult<List<AdminMenuTreeNodeVO>> adminMenuTree() {
List<ResourceBO> resources = resourceService.getResourceByTypeAndRoleIds(ResourceType.MENU, AdminSecurityContextHolder.getContext().getRoleIds()); List<ResourceBO> resources = resourceService.getResourceByTypeAndRoleIds(ResourceType.MENU, AdminSecurityContextHolder.getContext().getRoleIds());
// 创建 AdminMenuTreeNodeVO Map // 创建 AdminMenuTreeNodeVO Map
@ -53,9 +55,36 @@ public class ResourceController {
} }
@GetMapping("/admin_url_list") @GetMapping("/admin_url_list")
@ApiOperation(value = "获得管理员拥有的 URL 权限列表") @ApiOperation(value = "获得当前登陆的管理员拥有的 URL 权限列表")
public CommonResult adminUrlList() { // @ApiModelProperty(value = "data", example = "['/admin/role/add', '/admin/role/update']") 没效果
return null; public CommonResult<Set<String>> adminUrlList() {
List<ResourceBO> resources = resourceService.getResourceByTypeAndRoleIds(ResourceType.URL, AdminSecurityContextHolder.getContext().getRoleIds());
return CommonResult.success(resources.stream().map(ResourceBO::getHandler).collect(Collectors.toSet()));
}
// =========== 资源管理 API ===========
// TODO 芋艿注释
@PostMapping("/add")
@ApiOperation(value = "创建资源", notes = "例如说菜单资源Url 资源")
public void add(@RequestParam("name") String name,
@RequestParam("type") Integer type,
@RequestParam("sort") Integer sort,
@RequestParam("displayName") String displayName,
@RequestParam("pid") Integer pid,
@RequestParam("handler") String handler) {
ResourceAddDTO resourceAddDTO = new ResourceAddDTO().setName(name).setType(type).setSort(sort)
.setDisplayName(displayName).setPid(pid).setHandler(handler);
CommonResult<ResourceBO> result = resourceService.addResource(resourceAddDTO);
}
public void update() {
}
public void delete() {
} }
} }

View File

@ -1,28 +1,22 @@
package cn.iocoder.mall.admin.application.vo; package cn.iocoder.mall.admin.application.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.List; import java.util.List;
@ApiModel("管理员拥有的菜单 VO")
public class AdminMenuTreeNodeVO { public class AdminMenuTreeNodeVO {
/** @ApiModelProperty(value = "菜单编号", required = true, example = "1")
* 菜单编号
*/
private Integer id; private Integer id;
/** @ApiModelProperty(value = "菜单名", required = true, example = "商品管理")
* 彩蛋名
*/
private String name; private String name;
/** @ApiModelProperty(value = "菜单操作", required = true, example = "/order/list")
* 操作
*/
private String handler; private String handler;
/** @ApiModelProperty(value = "父菜单编号", required = true, example = "1", notes = "如果无父菜单,则值为 0")
* 父菜单编号
*/
private Integer pid; private Integer pid;
/** @ApiModelProperty(value = "子节点数组", example = "[1, 2, 3]")
* 子节点数组
*/
private List<AdminMenuTreeNodeVO> children; private List<AdminMenuTreeNodeVO> children;
public Integer getId() { public Integer getId() {

View File

@ -4,4 +4,4 @@ spring:
# server # server
server: server:
port: 8083 port: 18083

View File

@ -8,6 +8,7 @@
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>admin-sdk</artifactId> <artifactId>admin-sdk</artifactId>

View File

@ -8,6 +8,7 @@
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>admin-service-api</artifactId> <artifactId>admin-service-api</artifactId>
<dependencies> <dependencies>
@ -17,9 +18,8 @@
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>cn.iocoder.mall</groupId> <groupId>org.hibernate.validator</groupId>
<artifactId>admin-service-api</artifactId> <artifactId>hibernate-validator</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -1,6 +1,8 @@
package cn.iocoder.mall.admin.api; package cn.iocoder.mall.admin.api;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.admin.api.bo.ResourceBO; import cn.iocoder.mall.admin.api.bo.ResourceBO;
import cn.iocoder.mall.admin.api.dto.ResourceAddDTO;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -9,4 +11,6 @@ public interface ResourceService {
List<ResourceBO> getResourceByTypeAndRoleIds(Integer type, Set<Integer> roleIds); List<ResourceBO> getResourceByTypeAndRoleIds(Integer type, Set<Integer> roleIds);
CommonResult<ResourceBO> addResource(ResourceAddDTO resourceAddDTO);
} }

View File

@ -0,0 +1,94 @@
package cn.iocoder.mall.admin.api.dto;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* 资源添加 DTO
*/
public class ResourceAddDTO {
/**
* 资源名字标识
*/
@NotEmpty(message = "资源名字不能为空")
private String name;
/**
* 类型
*/
@NotNull(message = "类型不能为空")
private Integer type;
/**
* 排序值
*/
@NotNull(message = "类型不能为空")
private Integer sort;
/**
* 展示名
*/
@NotEmpty(message = "资源名字不能为空")
private String displayName;
/**
* 父资源比那好
*/
private Integer pid;
/**
* 操作
*/
private String handler;
public String getName() {
return name;
}
public ResourceAddDTO setName(String name) {
this.name = name;
return this;
}
public Integer getType() {
return type;
}
public ResourceAddDTO setType(Integer type) {
this.type = type;
return this;
}
public Integer getSort() {
return sort;
}
public ResourceAddDTO setSort(Integer sort) {
this.sort = sort;
return this;
}
public String getDisplayName() {
return displayName;
}
public ResourceAddDTO setDisplayName(String displayName) {
this.displayName = displayName;
return this;
}
public Integer getPid() {
return pid;
}
public ResourceAddDTO setPid(Integer pid) {
this.pid = pid;
return this;
}
public String getHandler() {
return handler;
}
public ResourceAddDTO setHandler(String handler) {
this.handler = handler;
return this;
}
}

View File

@ -1,7 +1,9 @@
package cn.iocoder.mall.admin.service; package cn.iocoder.mall.admin.service;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.admin.api.ResourceService; import cn.iocoder.mall.admin.api.ResourceService;
import cn.iocoder.mall.admin.api.bo.ResourceBO; import cn.iocoder.mall.admin.api.bo.ResourceBO;
import cn.iocoder.mall.admin.api.dto.ResourceAddDTO;
import cn.iocoder.mall.admin.convert.ResourceConvert; import cn.iocoder.mall.admin.convert.ResourceConvert;
import cn.iocoder.mall.admin.dao.ResourceMapper; import cn.iocoder.mall.admin.dao.ResourceMapper;
import cn.iocoder.mall.admin.dataobject.ResourceDO; import cn.iocoder.mall.admin.dataobject.ResourceDO;
@ -13,7 +15,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
@Service @Service
@com.alibaba.dubbo.config.annotation.Service @com.alibaba.dubbo.config.annotation.Service(validation = "true")
public class ResourceServiceImpl implements ResourceService { public class ResourceServiceImpl implements ResourceService {
@Autowired @Autowired
@ -31,4 +33,9 @@ public class ResourceServiceImpl implements ResourceService {
return ResourceConvert.INSTANCE.convert(resourceMapper.selectListByTypeAndRoleIds(type, roleIds)); return ResourceConvert.INSTANCE.convert(resourceMapper.selectListByTypeAndRoleIds(type, roleIds));
} }
@Override
public CommonResult<ResourceBO> addResource(ResourceAddDTO resourceAddDTO) {
return null;
}
} }

View File

@ -1,14 +1,10 @@
spring: spring:
# datasource # datasource
datasource: datasource:
url: jdbc:mysql://127.0.0.1:33061/mall_admin?useSSL=false url: jdbc:mysql://180.167.213.26:13306/mall_admin?useSSL=false
driver-class-name: com.mysql.jdbc.Driver driver-class-name: com.mysql.jdbc.Driver
username: root username: root
password: 123456 password: ${MALL_MYSQL_PASSWORD}
# server
server:
port: 8083
# mybatis # mybatis
mybatis: mybatis:
@ -27,6 +23,3 @@ dubbo:
name: dubbo name: dubbo
scan: scan:
base-packages: cn.iocoder.mall.admin.service base-packages: cn.iocoder.mall.admin.service
demo:
service:
version: 1.0.0

1
build_admin.sh Normal file
View File

@ -0,0 +1 @@
mvn clean package -am -DskipTests

View File

@ -44,6 +44,11 @@
<artifactId>jackson-annotations</artifactId> <artifactId>jackson-annotations</artifactId>
<version>2.9.7</version> <version>2.9.7</version>
</dependency> </dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.15.Final</version>
</dependency>
<!--<dependency>--> <!--<dependency>-->
<!--<groupId>com.baomidou</groupId>--> <!--<groupId>com.baomidou</groupId>-->
<!--<artifactId>mybatis-plus-support</artifactId>--> <!--<artifactId>mybatis-plus-support</artifactId>-->

View File

@ -3,13 +3,14 @@ package cn.iocoder.common.framework.config;
import cn.iocoder.common.framework.constant.SysErrorCodeEnum; import cn.iocoder.common.framework.constant.SysErrorCodeEnum;
import cn.iocoder.common.framework.exception.ServiceException; import cn.iocoder.common.framework.exception.ServiceException;
import cn.iocoder.common.framework.util.ExceptionUtil; import cn.iocoder.common.framework.util.ExceptionUtil;
import cn.iocoder.common.framework.vo.RestResult; import cn.iocoder.common.framework.vo.CommonResult;
import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException;
import java.lang.reflect.UndeclaredThrowableException; import java.lang.reflect.UndeclaredThrowableException;
@ControllerAdvice @ControllerAdvice
@ -17,33 +18,49 @@ public class GlobalExceptionHandler {
@ResponseBody @ResponseBody
@ExceptionHandler(value = ServiceException.class) @ExceptionHandler(value = ServiceException.class)
public RestResult serviceExceptionHandler(HttpServletRequest req, ServiceException ex) { public CommonResult serviceExceptionHandler(HttpServletRequest req, ServiceException ex) {
return RestResult.error(ex.getCode(), ex.getMessage()); return CommonResult.error(ex.getCode(), ex.getMessage());
}
@ResponseBody
@ExceptionHandler(value = ConstraintViolationException.class)
public CommonResult constraintViolationExceptionHandler(HttpServletRequest req, ConstraintViolationException ex) {
// TODO 芋艿后续要想一个更好的方式
// 拼接详细报错
StringBuilder detailMessage = new StringBuilder("\n\n详细错误如下");
ex.getConstraintViolations().forEach(constraintViolation -> detailMessage.append("\n").append(constraintViolation.getMessage()));
return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getMessage()
+ detailMessage.toString());
} }
@ResponseBody @ResponseBody
@ExceptionHandler(value = UndeclaredThrowableException.class) @ExceptionHandler(value = UndeclaredThrowableException.class)
public RestResult undeclaredThrowableExceptionHandler(HttpServletRequest req, UndeclaredThrowableException e) { public CommonResult undeclaredThrowableExceptionHandler(HttpServletRequest req, UndeclaredThrowableException e) {
// 尝试获得 ServiceException 异常如果是则使用 serviceExceptionHandler 方法处理 // 尝试获得 ServiceException 异常如果是则使用 serviceExceptionHandler 方法处理
ServiceException serviceException = ExceptionUtil.getServiceException(e); ServiceException serviceException = ExceptionUtil.getServiceException(e);
if (serviceException != null) { if (serviceException != null) {
return serviceExceptionHandler(req, serviceException); return serviceExceptionHandler(req, serviceException);
} }
// 尝试获得 ConstraintViolationException 异常如果是
ConstraintViolationException constraintViolationException = ExceptionUtil.getConstraintViolationException(e);
if (constraintViolationException != null) {
return constraintViolationExceptionHandler(req, constraintViolationException);
}
// 获得不到使用 异常日志 方法处理 // 获得不到使用 异常日志 方法处理
return resultExceptionHandler(req, e); return resultExceptionHandler(req, e);
} }
@ResponseBody @ResponseBody
@ExceptionHandler(value = Exception.class) @ExceptionHandler(value = Exception.class)
public RestResult resultExceptionHandler(HttpServletRequest req, Exception e) { public CommonResult resultExceptionHandler(HttpServletRequest req, Exception e) {
// TODO 异常日志 // TODO 异常日志
e.printStackTrace(); e.printStackTrace();
// TODO 翻译不同的异常 // TODO 翻译不同的异常
if (e instanceof MissingServletRequestParameterException) { if (e instanceof MissingServletRequestParameterException) {
return RestResult.error(SysErrorCodeEnum.MISSING_REQUEST_PARAM_ERROR.getCode(), SysErrorCodeEnum.MISSING_REQUEST_PARAM_ERROR.getMessage()); return CommonResult.error(SysErrorCodeEnum.MISSING_REQUEST_PARAM_ERROR.getCode(), SysErrorCodeEnum.MISSING_REQUEST_PARAM_ERROR.getMessage());
} }
// 返回 // 返回
return RestResult.error(SysErrorCodeEnum.SYS_ERROR.getCode(), SysErrorCodeEnum.SYS_ERROR.getMessage()); return CommonResult.error(SysErrorCodeEnum.SYS_ERROR.getCode(), SysErrorCodeEnum.SYS_ERROR.getMessage());
} }
} }

View File

@ -9,6 +9,7 @@ public enum SysErrorCodeEnum {
SYS_ERROR(2001001000, "服务端发生异常"), SYS_ERROR(2001001000, "服务端发生异常"),
MISSING_REQUEST_PARAM_ERROR(2001001001, "参数缺失"), MISSING_REQUEST_PARAM_ERROR(2001001001, "参数缺失"),
VALIDATION_REQUEST_PARAM_ERROR(2001001002, "参数校验不正确")
; ;
private final int code; private final int code;

View File

@ -2,6 +2,7 @@ package cn.iocoder.common.framework.util;
import cn.iocoder.common.framework.exception.ServiceException; import cn.iocoder.common.framework.exception.ServiceException;
import javax.validation.ConstraintViolationException;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.UndeclaredThrowableException; import java.lang.reflect.UndeclaredThrowableException;
@ -31,4 +32,16 @@ public class ExceptionUtil {
return null; return null;
} }
public static ConstraintViolationException getConstraintViolationException(UndeclaredThrowableException e) {
Throwable undeclaredThrowable = e.getUndeclaredThrowable();
if (undeclaredThrowable instanceof InvocationTargetException) {
InvocationTargetException invocationTargetException = (InvocationTargetException) undeclaredThrowable;
Throwable targetException = invocationTargetException.getTargetException();
if (targetException != null && targetException instanceof ConstraintViolationException) {
return (ConstraintViolationException) targetException;
}
}
return null;
}
} }

3
publish_admin.sh Normal file
View File

@ -0,0 +1,3 @@
#!/usr/bin/env bash
sh build_admin.sh
scp admin/admin-application/target/admin-application-1.0-SNAPSHOT.jar runner@192.168.88.10:/work2/project/admin