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;
}

浙公网安备 33010602011771号