/* * Copyright 2015-2016 http://hsweb.me * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.hsweb.web.controller; import com.alibaba.fastjson.JSON; import org.hsweb.commons.ClassUtils; import org.hsweb.web.bean.common.QueryParam; import org.hsweb.web.bean.po.GenericPo; import org.hsweb.web.core.authorize.annotation.Authorize; import org.hsweb.web.core.exception.BusinessException; import org.hsweb.web.core.exception.NotFoundException; import org.hsweb.web.core.logger.annotation.AccessLogger; import org.hsweb.web.core.message.ResponseMessage; import org.hsweb.web.service.GenericService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; import java.util.Arrays; import static org.hsweb.web.core.message.ResponseMessage.*; /** * 通用控制器,此控制器实现了通用的增删改查功能 * 需要提供一个实现了{@link GenericService}接口的实现类 */ public abstract class GenericController<PO, PK> { protected Logger logger = LoggerFactory.getLogger(this.getClass()); /** * 获取此Controller需要的服务类,由子类实现 * * @return 通用服务类 */ protected abstract GenericService<PO, PK> getService(); /** * 获取PO的类型 * * @return PO类型 */ protected final Class<PO> getPOType() { return (Class<PO>) ClassUtils.getGenericType(this.getClass(), 0); } /** * 获取PK(主键)的类型 * * @return PK(主键)类型 */ protected final Class<PK> getPKType() { return (Class<PK>) ClassUtils.getGenericType(this.getClass(), 1); } /** * 查询列表,并返回查询结果 * * @param param 查询参数 {@link QueryParam} * @return 查询结果, 如果参数指定了分页(默认指定)将返回格式如:{total:数据总数,data:[{}]}的数据. * 否则返回格式[{}] */ @RequestMapping(method = RequestMethod.GET) @AccessLogger("查询列表") @Authorize(action = "R") public ResponseMessage list(QueryParam param) { // 获取条件查询 Object data; if (!param.isPaging())//不分页 data = getService().select(param); else data = getService().selectPager(param); return ok(data) .include(getPOType(), param.getIncludes()) .exclude(getPOType(), param.getExcludes()) .onlyData(); } /** * 根据id(主键)查询数据 * * @param id 主键 * @return 请求结果 * @throws NotFoundException 要查询的数据不存在 */ @RequestMapping(value = "/{id}", method = RequestMethod.GET) @AccessLogger("查询明细") @Authorize(action = "R") public ResponseMessage info(@PathVariable("id") PK id) { PO po = getService().selectByPk(id); if (po == null) throw new NotFoundException("data is not found!"); return ok(po); } /** * 根据查询条件,查询数据数量 * * @param param 查询条件 * @return 请求结果 */ @RequestMapping(value = "/total", method = RequestMethod.GET) @AccessLogger("查询总数") @Authorize(action = "R") public ResponseMessage total(QueryParam param) { // 获取条件查询 return ok(getService().total(param)); } /** * 请求添加数据,请求必须以POST方式 * * @param object 请求添加的对象 * @return 被添加数据的主键值 * @throws javax.validation.ValidationException 验证数据格式错误 */ @RequestMapping(method = RequestMethod.POST) @AccessLogger("新增") @Authorize(action = "C") @ResponseStatus(HttpStatus.CREATED) public ResponseMessage add(@RequestBody PO object) { PK pk = getService().insert(object); return created(pk); } /** * 请求删除指定id的数据,请求方式为DELETE,使用rest风格,如请求 /delete/1 ,将删除id为1的数据 * * @param id 要删除的id标识 * @return 删除结果 * @throws NotFoundException 要删除的数据不存在 */ @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) @AccessLogger("删除") @Authorize(action = "D") public ResponseMessage delete(@PathVariable("id") PK id) { PO old = getService().selectByPk(id); assertFound(old, "data is not found!"); getService().delete(id); return ok(); } /** * 根据主键修改数据 * * @param id 要修改数据的主键值 * @param object 要修改的数据 * @return 请求结果 * @throws NotFoundException 要修改的数据不存在 */ @RequestMapping(value = "/{id}", method = RequestMethod.PUT) @AccessLogger("修改") @Authorize(action = "U") public ResponseMessage update(@PathVariable("id") PK id, @RequestBody PO object) { PO old = getService().selectByPk(id); assertFound(old, "data is not found!"); if (object instanceof GenericPo) { ((GenericPo) object).setId(id); } int number = getService().update(object); return ok(number); } /** * 批量修改数据. * * @param json 请求修改的数据 json格式 * @return 被修改数据的条数 * @throws BusinessException 请求的数据格式错误 */ @RequestMapping(method = RequestMethod.PUT) @AccessLogger("批量修改") @Authorize(action = "U") public ResponseMessage update(@RequestBody String json) { int number; if (json.startsWith("[")) { number = getService().update(JSON.parseArray(json, getPOType())); } else if (json.startsWith("{")) { number = getService().update(Arrays.asList(JSON.parseObject(json, getPOType()))); } else { throw new BusinessException("请求数据格式错误!"); } return ok(number); } /** * 判断对象是否为空,如果为空将抛出 {@link NotFoundException} * * @param obj 要判断的对象 * @param msg 为null时异常消息 */ public void assertFound(Object obj, String msg) { if (obj == null) throw new NotFoundException(msg); } }