/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
*
* 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.springblade.core.base.controller;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springblade.core.annotation.Json;
import org.springblade.core.constant.Const;
import org.springblade.core.constant.ConstShiro;
import org.springblade.core.exception.NoPermissionException;
import org.springblade.core.exception.NoUserException;
import org.springblade.core.meta.IQuery;
import org.springblade.core.toolbox.CMap;
import org.springblade.core.toolbox.Func;
import org.springblade.core.toolbox.ajax.AjaxResult;
import org.springblade.core.toolbox.captcha.CaptchaMaker;
import org.springblade.core.toolbox.file.BladeFile;
import org.springblade.core.toolbox.file.BladeFileKit;
import org.springblade.core.toolbox.file.FileMaker;
import org.springblade.core.toolbox.grid.GridManager;
import org.springblade.core.toolbox.kit.*;
import org.springblade.core.toolbox.log.BladeLogManager;
import org.springblade.core.toolbox.qrcode.QrCodeMaker;
import org.springblade.core.toolbox.support.BeanInjector;
import org.springblade.core.toolbox.support.Convert;
import org.springblade.core.toolbox.support.WafRequestWrapper;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
* Blade控制器封装类
* @author zhuangqian
*/
public class BladeController {
protected Logger LOGGER = LogManager.getLogger(this.getClass());
/** ============================ requset ================================================= */
@Resource
private HttpServletRequest request;
/**
* 获取request
*/
public HttpServletRequest getRequest() {
return new WafRequestWrapper(this.request);
}
/**
* 是否ajax
*/
public boolean isAjax() {
String header = getRequest().getHeader("X-Requested-With");
boolean isAjax = "XMLHttpRequest".equalsIgnoreCase(header);
return isAjax;
}
/**
* 是否post
*/
public boolean isPost() {
String method = getRequest().getMethod();
return StrKit.equalsIgnoreCase("POST", method);
}
/**
* 获取String参数
*/
public String getParameter(String name) {
return getRequest().getParameter(name);
}
/**
* 获取String参数
*/
public String getParameter(String name, String defaultValue) {
return Convert.toStr(getRequest().getParameter(name), defaultValue);
}
/**
* 获取Integer参数
*/
public Integer getParameterToInt(String name) {
return Convert.toInt(getRequest().getParameter(name));
}
/**
* 获取Integer参数
*/
public Integer getParameterToInt(String name, Integer defaultValue) {
return Convert.toInt(getRequest().getParameter(name), defaultValue);
}
/**
* 获取Long参数
*/
public Long getParameterToLong(String name) {
return Convert.toLong(getRequest().getParameter(name));
}
/**
* 获取Long参数
*/
public Long getParameterToLong(String name, Long defaultValue) {
return Convert.toLong(getRequest().getParameter(name), defaultValue);
}
/**
* 获取Float参数
*/
public Float getParameterToFloat(String name) {
return Convert.toFloat(getRequest().getParameter(name));
}
/**
* 获取Float参数
*/
public Float getParameterToFloat(String name, Float defaultValue) {
return Convert.toFloat(getRequest().getParameter(name), defaultValue);
}
/**
* 获取BigDecimal参数
*/
public BigDecimal getParameterToBigDecimal(String name) {
return Convert.toBigDecimal(getRequest().getParameter(name));
}
/**
* 获取BigDecimal参数
*/
public BigDecimal getParameterToBigDecimal(String name, BigDecimal defaultValue) {
return Convert.toBigDecimal(getRequest().getParameter(name), defaultValue);
}
/**
* 获取Encode参数
*/
public String getParameterToEncode(String para) {
return URLKit.encode(getRequest().getParameter(para), CharsetKit.UTF_8);
}
/**
* 获取Decode参数
*/
public String getParameterToDecode(String para) {
return URLKit.decode(getRequest().getParameter(para), CharsetKit.UTF_8);
}
/**
* 获取ContextPath
*/
public String getContextPath() {
return getRequest().getContextPath();
}
/**
* 页面跳转
* @param url
*/
public String redirect(String url) {
return StrKit.format("redirect:{}", url);
}
/**
* 对象是否为空
*
* @param obj String,List,Map,Object[],int[],long[]
* @return
*/
public boolean isEmpty(Object obj) {
return Func.isEmpty(obj);
}
/**
* 对象是否不为空
*
* @param obj String,List,Map,Object[],int[],long[]
* @return
*/
public boolean notEmpty(Object obj) {
return !isEmpty(obj);
}
/**
* 字符串是否为空白 空白的定义如下:
* 1、为null
* 2、为不可见字符(如空格)
* 3、""
*
* @param str 被检测的字符串
* @return 是否为空
*/
public boolean isBlank(String str) {
return StrKit.isBlank(str);
}
/**
* 字符串是否为非空白 空白的定义如下:
* 1、不为null
* 2、不为不可见字符(如空格)
* 3、不为""
*
* @param str 被检测的字符串
* @return 是否为非空
*/
public boolean notBlank(String str) {
return StrKit.notBlank(str);
}
/**
* 格式化文本, {} 表示占位符
* 此方法只是简单将占位符 {} 按照顺序替换为参数
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
* 例:
* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
* 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a
* 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
*
* @param template 文本模板,被替换的部分用 {} 表示
* @param params 参数值
* @return 格式化后的文本
*/
public String format(String template, Object... params) {
return StrKit.format(template, params);
}
/**
* 格式化文本,使用 {varName} 占位
* map = {a: "aValue", b: "bValue"}
* format("{a} and {b}", map) ----> aValue and bValue
*
* @param template 文本模板,被替换的部分用 {key} 表示
* @param map 参数值对
* @return 格式化后的文本
*/
public String format(String template, Map, ?> map) {
return StrKit.format(template, map);
}
/**
* 创建StringBuilder对象
*/
public StringBuilder builder() {
return StrKit.builder();
}
/**
* 创建StringBuilder对象
*/
public StringBuilder builder(int capacity) {
return StrKit.builder(capacity);
}
/**
* 创建StringBuilder对象
*/
public StringBuilder build(String... strs) {
return StrKit.builder(strs);
}
/**
* 克隆对象
* 对象必须实现Serializable接口
*
* @param obj 被克隆对象
* @return 克隆后的对象
* @throws IOException
* @throws ClassNotFoundException
*/
public T clone(T obj) {
return ObjectKit.clone(obj);
}
/**
* 克隆对象
* 对象必须实现Serializable接口
*
* @param obj 被克隆对象
* @return 克隆后的对象
* @throws IOException
* @throws ClassNotFoundException
*/
public T clone(T obj) {
return ObjectKit.clone(obj);
}
/** ============================ mapping ================================================= */
/**
* 表单值映射为javabean
*
* @param beanClass javabean.class
* @return T
*/
public T mapping(Class beanClass) {
return (T) BeanInjector.inject(beanClass, getRequest());
}
/**
* 表单值映射为javabean
*
* @param prefix name前缀
* @param beanClass javabean.class
* @return T
*/
public T mapping(String prefix, Class beanClass) {
return (T) BeanInjector.inject(beanClass, prefix, getRequest());
}
/**
* 表单值映射为CMap
*
* @return CMap
*/
public CMap getCMap() {
return BeanInjector.injectMaps(getRequest());
}
/**
* 表单值映射为CMap
*
* @param prefix name前缀
* @return CMap
*/
public CMap getCMap(String prefix) {
return BeanInjector.injectMaps(prefix, getRequest());
}
/**=========================== convert =============================================== */
/**
* 强转String
*/
public String toStr(Object value) {
return Convert.toStr(value);
}
/**
* 强转String
*/
public String toStr(Object value, String defaultValue) {
return Convert.toStr(value, defaultValue);
}
/**
* 强转Integer
*/
public Integer toInt(Object value) {
return Convert.toInt(value);
}
/**
* 强转Integer
*/
public Integer toInt(Object value, Integer defaultValue) {
return Convert.toInt(value, defaultValue);
}
/**
* 强转Long
*/
public Long toLong(Object value) {
return Convert.toLong(value);
}
/**
* 强转Long
*/
public Long toLong(Object value, Long defaultValue) {
return Convert.toLong(value, defaultValue);
}
/**
* 强转Float
*/
public Float toFloat(Object value) {
return Convert.toFloat(value);
}
/**
* 强转Float
*/
public Float toFloat(Object value, Float defaultValue) {
return Convert.toFloat(value, defaultValue);
}
/**
* 强转BigDecimal
*/
public BigDecimal toBigDecimal(Object value) {
return Convert.toBigDecimal(value);
}
/**
* 强转BigDecimal
*/
public BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) {
return Convert.toBigDecimal(value, defaultValue);
}
/**
* 强转String数组
*/
public String[] toArray(String str) {
return Convert.toStrArray(str);
}
/**
* 强转String数组
*/
public String[] toArray(String split, String str) {
return Convert.toStrArray(split, str);
}
/**
* 强转Integer数组
*/
public Integer[] toIntArray(String str) {
return Convert.toIntArray(str);
}
/**
* 强转Integer数组
*/
public Integer[] toIntArray(String split, String str) {
return Convert.toIntArray(split, str);
}
/**
* encode
*/
public String encode(String value) {
return URLKit.encode(value, CharsetKit.UTF_8);
}
/**
* decode
*/
public String decode(String value) {
return URLKit.decode(value, CharsetKit.UTF_8);
}
/**============================ file ================================================= */
/**
* 获取BladeFile封装类
* @param file
* @return
*/
public BladeFile getFile(MultipartFile file){
return BladeFileKit.getFile(file);
}
/**
* 获取BladeFile封装类
* @param file
* @param dir
* @return
*/
public BladeFile getFile(MultipartFile file, String dir){
return BladeFileKit.getFile(file, dir);
}
/**
* 获取BladeFile封装类
* @param file
* @param dir
* @param path
* @param virtualPath
* @return
*/
public BladeFile getFile(MultipartFile file, String dir, String path, String virtualPath){
return BladeFileKit.getFile(file, dir, path, virtualPath);
}
/**
* 获取BladeFile封装类
* @param files
* @return
*/
public List getFiles(List files){
return BladeFileKit.getFiles(files);
}
/**
* 获取BladeFile封装类
* @param files
* @param dir
* @return
*/
public List getFiles(List files, String dir){
return BladeFileKit.getFiles(files, dir);
}
/**
* 获取BladeFile封装类
* @param files
* @param path
* @param virtualPath
* @return
*/
public List getFiles(List files, String dir, String path, String virtualPath){
return BladeFileKit.getFiles(files, dir, path, virtualPath);
}
/** ============================ ajax ================================================= */
/**
* 返回ajaxresult
* @param data
* @return AjaxResult
*/
public AjaxResult json(Object data) {
return new AjaxResult().success(data);
}
/**
* 返回ajaxresult
* @param data
* @param message
* @return AjaxResult
*/
public AjaxResult json(Object data, String message) {
return json(data).setMessage(message);
}
/**
* 返回ajaxresult
* @param data
* @param message
* @param code
* @return AjaxResult
*/
public AjaxResult json(Object data, String message, int code) {
return json(data, message).setCode(code);
}
/**
* 返回ajaxresult
* @param message
* @return AjaxResult
*/
public AjaxResult success(String message) {
return new AjaxResult().addSuccess(message);
}
/**
* 返回ajaxresult
* @param message
* @return AjaxResult
*/
public AjaxResult error(String message) {
return new AjaxResult().addError(message);
}
/**
* 返回ajaxresult
* @param message
* @return AjaxResult
*/
public AjaxResult warn(String message) {
return new AjaxResult().addWarn(message);
}
/**
* 返回ajaxresult
* @param message
* @return AjaxResult
*/
public AjaxResult fail(String message) {
return new AjaxResult().addFail(message);
}
/** ============================ paginate ================================================= */
/**
* 分页
* @param dbName 数据库别名
* @param source 数据源
* @param intercept 分页拦截器
* @return Object
*/
private Object basepage(String dbName, String source, IQuery intercept){
Integer page = getParameterToInt("page", 1);
Integer rows = getParameterToInt("rows", 10);
String where = getParameter("where", StrKit.EMPTY);
String sidx = getParameter("sidx", StrKit.EMPTY);
String sord = getParameter("sord", StrKit.EMPTY);
String sort = getParameter("sort", StrKit.EMPTY);
String order = getParameter("order", StrKit.EMPTY);
if (StrKit.notBlank(sidx)) {
sort = sidx + " " + sord + (StrKit.notBlank(sort) ? ("," + sort) : StrKit.EMPTY);
}
Object grid = GridManager.paginate(dbName, page, rows, source, where, sort, order, intercept, this);
return grid;
}
/**
* 分页
* @param source 数据源
* @return Object
*/
public Object paginate(String source){
return basepage(null, source, null);
}
/**
* 分页
* @param source 数据源
* @param intercept 分页拦截器
* @return Object
*/
public Object paginate(String source, IQuery intercept){
return basepage(null, source, intercept);
}
/**
* 分页
* @param dbName 数据库别名
* @param source 数据源
* @return Object
*/
public Object paginate(String dbName, String source){
return basepage(dbName, source, null);
}
/**
* 分页
* @param dbName 数据库别名
* @param source 数据源
* @param intercept 分页拦截器
* @return Object
*/
public Object paginate(String dbName, String source, IQuery intercept){
return basepage(dbName, source, intercept);
}
/** ============================ maker =================================================== */
/**
* 返回验证码
*/
public void makeCaptcha(HttpServletResponse response) {
CaptchaMaker.init(response).start();
}
/**
* 校验验证码
*/
public boolean validateCaptcha(HttpServletResponse response, String value) {
return CaptchaMaker.validate(getRequest(), response, value);
}
/**
* 返回二维码
*
* @param content 二维码携带内容
* @param width 二维码宽度
* @param height 二维码高度
*/
public void makeQRCode(HttpServletResponse response, String content, int width, int height) {
QrCodeMaker.init(response, content, width, height).start();
}
/**
* 返回二维码
*
* @param content 二维码携带内容
* @param width 二维码宽度
* @param height 二维码高度
* @param errorCorrectionLevel 带有纠错级别参数的构造方法,纠错能力从高到低共有四个级别:'H'、'Q'、'M'、'L'
*/
public void makeQRCode(HttpServletResponse response, String content, int width, int height, ErrorCorrectionLevel errorCorrectionLevel) {
QrCodeMaker.init(response, content, width, height, errorCorrectionLevel).start();
}
/**
* 返回二维码
*
* @param content 二维码携带内容
* @param width 二维码宽度
* @param height 二维码高度
* @param errorCorrectionLevel 带有纠错级别参数的构造方法,纠错能力从高到低共有四个级别:'H'、'Q'、'M'、'L'
*/
public void makeQRCode(HttpServletResponse response, String content, int width, int height, char errorCorrectionLevel) {
QrCodeMaker.init(response, content, width, height, errorCorrectionLevel).start();
}
/**
* 返回文件
*/
public void makeFile(HttpServletResponse response, File file) {
FileMaker.init(getRequest(), response, file).start();
}
/** ============================ exception ================================================= */
@Json
@ExceptionHandler(Exception.class)
public Object exceptionHandler(Exception ex, HttpServletResponse response, HttpServletRequest request) throws IOException {
AjaxResult result = new AjaxResult();
String url = Const.ERROR_500;
String msg = ex.getMessage();
Object resultModel = null;
try {
if (ex.getClass() == HttpRequestMethodNotSupportedException.class) {
/**
* 请求方式不允许抛出的异常,后面可自定义页面
*/
url = Const.ERROR_500;
} else if (ex.getClass() == NoPermissionException.class) {
/**
* 无权限抛出的异常
*/
url = Const.NOPERMISSION_PATH;
msg = ConstShiro.NO_PERMISSION;
} else if (ex.getClass() == NoUserException.class) {
/**
* session过期抛出的异常
*/
url = Const.LOGIN_REALPATH;
msg = ConstShiro.NO_USER;
}
if (isAjax() || isPost()) {
result.addFail(msg);
resultModel = result;
} else {
ModelAndView view = new ModelAndView(url);
view.addObject("error", msg);
view.addObject("class", ex.getClass());
view.addObject("method", request.getRequestURI());
resultModel = view;
}
try {
if(StrKit.notBlank(msg)){
BladeLogManager.doLog("异常日志", msg, false);
}
} catch (Exception logex) {
LogKit.logNothing(logex);
}
return resultModel;
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return resultModel;
} finally {
LOGGER.error(msg, ex);
}
}
}