spring mvc Interceptor 返回json数据

本文介绍了一种在一卡通接口权限检查拦截器中使用SpringMVC返回JSON数据的方法。该方法通过直接利用HttpServletResponse来实现,适用于拦截器中进行签名校验失败时的反馈。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

spring mvc Interceptor 返回json数据

今天在使用springmvc的拦截器做签名校验时需要在拦截器中返回校验失败的提示信息,刚开始因为代码逻辑的问题,一直不能返回json数据,后来才发现直接使用HttpServletResponse就可以返回,再此记录下这个低级错误:

package com.app.ws.card.util;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.app.ws.card.service.CardClientService;
import com.app.ws.card.web.CardControllerFlagInterface;

/**
 * 一卡通接口权限检查拦截器
 * 
 * @author wanxing
 * @createTime 2017-08-01
 */
public class CardApiInterceptor extends HandlerInterceptorAdapter {

    private static Log logger = LogFactory.getLog(CardApiInterceptor.class);

    /** 30分钟 */
    protected static final long THIRTY_MINU_MSEC = 30 * 60 * 1000;// 半个小时

    @Autowired
    private CardClientService clientService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Object bean = handlerMethod.getBean();
        /**
         * 如果不是一卡通的Controller则直接放过
         */
        if (!(bean instanceof CardControllerFlagInterface)) {
            return true;
        }
        // 将请求参数转化为map,以便后续校验签名
        Map<String, String[]> parameterMap = request.getParameterMap();
        Map<String, Object> param = new HashMap<String, Object>();
        buildParamMap(parameterMap, param);

        String appId = (String) param.get("appId");
        String timestampStr = (String) param.get("timestamp");
        String sign = (String) param.get("sign");

        // 校验参数完整性
        if (StringUtils.isBlank(appId) || StringUtils.isBlank(timestampStr) || StringUtils.isBlank(sign)) {
            if (logger.isDebugEnabled()) {
                logger.debug(String.format("请求参数不完整[appId:%s][timestamp:%s][sign:%s]", appId, timestampStr, sign));
            }

            SendMsgUtil.sendJsonMessage(response, CardResult.instance().build(ResultStatus.PARAM_IMPERFECT));
            return false;
        }

        // 校验接口调用是否超时
        long timestamp = Long.valueOf(timestampStr);
        long currTimestamp = new Date().getTime();
        if (currTimestamp - timestamp > THIRTY_MINU_MSEC) {
            if (logger.isDebugEnabled()) {
                logger.debug(String.format("接口调用超时[%s,%s]",
                        DateFormatUtils.format(new Date(currTimestamp), "yyyy-MM-dd HH:mm:ss"),
                        DateFormatUtils.format(new Date(timestamp), "yyyy-MM-dd HH:mm:ss")));
            }
            SendMsgUtil.sendJsonMessage(response, CardResult.instance().build(ResultStatus.SIGN_OVERTIME));
            return false;
        }

        // 查询appId对应的accessKey
        String accessKey = clientService.getAccessKeyByAppId(appId);
        if (StringUtils.isBlank(accessKey)) {
            if (logger.isDebugEnabled()) {
                logger.debug(String.format("没有找到[%s]对应的accessKey", appId));
            }
            SendMsgUtil.sendJsonMessage(response, CardResult.instance().build(ResultStatus.APPID_NOT_FOUND));
            return false;
        }

        // 校验签名
        String otherSign = TencentSignUtil.buildSign(param, accessKey);
        if (!StringUtils.equals(sign, otherSign)) {
            if (logger.isDebugEnabled()) {
                logger.debug(String.format("用户签名错误[用户签名:%s][服务器生成签名:%s]", sign, otherSign));
            }
            SendMsgUtil.sendJsonMessage(response, CardResult.instance().build(ResultStatus.SIGN_ERROR));
            return false;
        }
        return true;
    }

    private void buildParamMap(Map<String, String[]> parameterMap, Map<String, Object> param) {
        for (Entry<String, String[]> entry : parameterMap.entrySet()) {
            String key = entry.getKey();
            String[] value = entry.getValue();
            if (!ArrayUtils.isEmpty(value)) {
                if (StringUtils.isNotBlank(value[0])) {
                    param.put(key, value[0]);
                }
            } else {
                continue;
            }
        }
    }

    public CardClientService getClientService() {
        return clientService;
    }

    public void setClientService(CardClientService clientService) {
        this.clientService = clientService;
    }

}
public class SendMsgUtil {

    /**
     * 发送消息 text/html;charset=utf-8
     * @param response
     * @param str
     * @throws Exception
     */
    public static void sendMessage(HttpServletResponse response, String str) throws Exception {
        response.setContentType("text/html; charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.print(str);
        writer.close();
        response.flushBuffer(); 
    }

    /**
     * 将某个对象转换成json格式并发送到客户端
     * @param response
     * @param obj
     * @throws Exception
     */
    public static void sendJsonMessage(HttpServletResponse response, Object obj) throws Exception {
        response.setContentType("application/json; charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.print(JSONObject.toJSONString(obj, SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteDateUseDateFormat));
        writer.close();
        response.flushBuffer();
    }
}
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值