springMvc杂记(2)--统一返回消息格式并且进行base64编码

在SpringMVC的开发过程中,返回给前端的消息一般都是固定格式的,这样也方便调用者解析,在springMVC中实现这一点,也是非常方便,

实例代码路径--https://github.com/wangjiuong/springstudy/tree/master/SpringMvcRequestBody

1、定义一个注解类

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseJsonBody {

}

  

2、定义类实现HandlerMethodReturnValueHandler。

package com.nuaa.handler;

import com.alibaba.fastjson.JSON;
import com.nuaa.annotation.ResponseJsonBody;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by wangjiuyong on 2017/7/5.
 */
public class ReponseJsonBodyMethodReturnValueHandler implements HandlerMethodReturnValueHandler {

    private List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();

    public void setMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
        this.messageConverters.addAll(messageConverters);
    }

    @Override public boolean supportsReturnType(MethodParameter returnType) {
        return returnType.getMethodAnnotation(ResponseJsonBody.class)!=null;
    }

    @Override public void handleReturnValue(Object returnValue, MethodParameter returnType,
        ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
        HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
        JsonResult result = buildJsonResult(returnValue);
        if(null!=messageConverters && !messageConverters.isEmpty()){
            ServletServerHttpResponse outputMessage = new ServletServerHttpResponse(response);
            for( HttpMessageConverter messageConverter:messageConverters){
                messageConverter.write(result, MediaType.APPLICATION_JSON,outputMessage);
            }
        }else {
            response.getWriter().write(result.toString());
        }
        response.flushBuffer();
    }

    public JsonResult buildJsonResult(Object returnValue){
        JsonResult jsonResult=new JsonResult();
        if (returnValue != null) {
            jsonResult.setData(JSON.toJSON(returnValue));
            jsonResult.setErrorCode(ResultEnum.success.getCode());
            jsonResult.setMsg(ResultEnum.success.getMsg());
            jsonResult.setSuccess(true);
        }
        else{
            jsonResult.setErrorCode(ResultEnum.unknown.getCode());
            jsonResult.setMsg(ResultEnum.unknown.getMsg());
            jsonResult.setSuccess(false);
        }
        return jsonResult;
    }
}

  

supportsReturnType用来判断该类是用于解析那个注解。

handleReturnValue方法用来封装返回的消息格式,

在类中增加了messageConverters,可以再封装好的消息上,做进一步的处理,譬如base64编码等处理,避免消息的明文传输。

其他的辅助类如下:

JsonResult定义了返回的消息体格式:

package com.nuaa.handler;

import com.alibaba.fastjson.JSON;

/**
 * Created by wangjiuyong on 2017/7/5.
 */
public class JsonResult {

    private boolean success;
    private String msg;
    private String errorCode;
    private Object data;

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    @Override
    public String toString(){
        return JSON.toJSONString(this);
    }
}

  

ResultEnum定义了一些返回码和消息的对应值:

package com.nuaa.handler;

import org.apache.commons.lang3.StringUtils;

/**
 * Created by wangjiuyong on 2017/7/5.
 */
public enum ResultEnum {
    success("10000", "success"), sqlerror("60001", "sql error"), internalerror("70001",
        "internal error"), unknown("90001", "unkown error");

    private final String code;

    private final String msg;

    ResultEnum(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public static ResultEnum getCityCodeById(String statusCode) {
        if (StringUtils.isEmpty(statusCode)) {
            return unknown;
        }
        for (ResultEnum resule : ResultEnum.values()) {
            if (resule.getCode().equals(statusCode)) {
                return resule;
            }
        }
        return unknown;
    }

    public String getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}
Base64JsonHttpMessageConverter用于对JsonResult的值进行base64编码后返回
package com.nuaa.handler;

import org.apache.commons.codec.binary.Base64;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.util.FileCopyUtils;

import java.io.IOException;
import java.util.List;

/**
 * Created by wangjiuyong on 2017/7/5.
 */
public class Base64JsonHttpMessageConverter implements HttpMessageConverter {
    @Override public boolean canRead(Class clazz, MediaType mediaType) {
        return false;
    }

    @Override public boolean canWrite(Class clazz, MediaType mediaType) {
        return false;
    }

    @Override public List<MediaType> getSupportedMediaTypes() {
        return null;
    }

    @Override public Object read(Class clazz, HttpInputMessage inputMessage)
        throws IOException, HttpMessageNotReadableException {
        return null;
    }

    @Override
    public void write(Object object, MediaType contentType, HttpOutputMessage outputMessage)
        throws IOException, HttpMessageNotWritableException {
        byte[] bytes = object.toString().getBytes();
        FileCopyUtils.copy(Base64.encodeBase64(bytes), outputMessage.getBody());
    }
}

  最后在spring配置文件中将类装配进去就OK了

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <!-- 注解的映射器 -->
    <bean
        class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />

    <!-- 注解的适配器 -->
    <bean
        class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean
                    class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                            <value>text/html;charset=UTF-8</value>
                            <value>application/json;charset=UTF-8</value>
                        </list>
                    </property>
                </bean>
            </list>
        </property>
        <property name="returnValueHandlers">
            <list>
                <bean class="com.nuaa.handler.ReponseJsonBodyMethodReturnValueHandler">
                     <property name="messageConverters">
                         <list>
                             <bean class="com.nuaa.handler.Base64JsonHttpMessageConverter"/>
                         </list>
                     </property>
                </bean>
            </list>
        </property>
    </bean>
</beans>

 

在Controller中将注解配置下,就可以实现,统一格式的消息返回并且进行base64编码。

	@RequestMapping(value="/helloworld", method = RequestMethod.POST,produces="application/json")
	@ResponseJsonBody
	@ResponseBody
	public Student helloWorld(@RequestBody Student student){
		student.setName(student.getName()+(new Date()));
		return student;
	}

  

  

 

posted @ 2017-07-13 19:05  王久勇  阅读(1107)  评论(0编辑  收藏  举报