Restful后台系统搭建(四)
来源:互联网 发布:安纳金·天行者知乎 编辑:程序博客网 时间:2024/05/22 14:26
上篇文章介绍简单启动Jetty+Jersey服务,并可以通过Jmeter进行简单测试。本章再深入搭建一个Service+Action的框架,还会引入JSON解析工具。
请求的执行流程:
web前端 -> Service接口(通过@Path(xxx)访问) -> AbstractAction -> json解析成请求体req -> Action中的校验validate -> Action中的doAction -> 将返回体转换成json字符串 -> 转换成Response -> 返回给Web前端
包以及类分布:
各个类源码:
FrameworkErrorCode:
/** * 2017年4月29日 黑苹果 */package com.black.apple.framework.exception;/** * @author 黑苹果 2017年4月29日 */public enum FrameworkErrorCode{ /** * 成功 */ OK(0), /** * Jersey服务启动失败 */ JERSEY_SERVICE_START_FAILED(1), /** * JSON解析异常 */ JSON_DECODE_EXCEPTION(2), /** * 参数非法 */ PARAM_INVALID(3), /** * 未知异常 */ UNKNOW_EXCEPTION(9999); private int errorCode; /** * 错误码范围为:10000000~10009999 */ private static final int ERROR_CODE_PREFIX = 1000_0000; private FrameworkErrorCode(int errorCode) { this.errorCode = ERROR_CODE_PREFIX + errorCode; } public String toString() { return String.valueOf(errorCode); }}
AbstractAction:
/** * 2017年4月29日 黑苹果 */package com.black.apple.framework.jersey.rest.action.abs;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;import javax.ws.rs.core.MediaType;import javax.ws.rs.core.Response;import javax.ws.rs.core.Response.Status;import org.apache.commons.lang3.StringUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.black.apple.framework.exception.FrameworkErrorCode;import com.black.apple.framework.exception.FrameworkException;import com.black.apple.framework.jersey.utils.JsonDecodeUtil;/** * @author 黑苹果 2017年4月29日 */public abstract class AbstractAction<S, T>{ private static final Logger LOGGER = LoggerFactory.getLogger(AbstractAction.class); /** * Action主方法 * * @param content * json串 * @return Response */ public Response execute(String content) { Response response; try { S s = decodeJson(content); validateParam(s); T t = doAction(s); String responseJson = encodeJson(t); response = buildSuccessResponse(responseJson); } catch (FrameworkException e) { LOGGER.error("FrameworkException.", e); response = buildErrorResponse(e); } catch (Exception e) { LOGGER.error("Exception.", e); response = buildErrorResponse(e); } return response; } private Response buildErrorResponse(Exception e) { return Response .status(Status.SERVICE_UNAVAILABLE) .type(MediaType.APPLICATION_JSON) .entity(encodeJson(new ErrorResp(FrameworkErrorCode.UNKNOW_EXCEPTION.toString(), FrameworkErrorCode.UNKNOW_EXCEPTION.toString()))).build(); } private Response buildErrorResponse(FrameworkException e) { return Response.status(Status.SERVICE_UNAVAILABLE).type(MediaType.APPLICATION_JSON) .entity(encodeJson(new ErrorResp(e.getErrorCode(), e.getErrorCode()))).build(); } private Response buildSuccessResponse(String responseJson) { return Response.ok(responseJson, MediaType.APPLICATION_JSON).build(); } private S decodeJson(String json) throws FrameworkException { return JsonDecodeUtil.decode(json, getRequestClassType()); } @SuppressWarnings("unchecked") private Class<S> getRequestClassType() { Type genType = getClass().getGenericSuperclass(); Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); Class<S> sClass = (Class<S>) params[0]; return sClass; } private <O> String encodeJson(O obj) { try { String json = JsonDecodeUtil.encode(obj); return json; } catch (FrameworkException e) { LOGGER.error("json decode failed.obj={}", obj, e); } return StringUtils.EMPTY; } protected abstract T doAction(S request) throws FrameworkException; protected abstract void validateParam(S request) throws FrameworkException;}
ErrorResp:
/** * 2017年4月29日 黑苹果 */package com.black.apple.framework.jersey.rest.action.abs;import org.apache.commons.lang3.builder.ToStringBuilder;import org.apache.commons.lang3.builder.ToStringStyle;/** * @author 黑苹果 2017年4月29日 */public class ErrorResp{ private String errorCode; private String errorMsg; /** * @param errorCode * @param errorM */ public ErrorResp(String errorCode, String errorMsg) { super(); this.errorCode = errorCode; this.errorMsg = errorMsg; } /** * @return the errorCode */ public String getErrorCode() { return errorCode; } /** * @return the errorMsg */ public String getErrorMsg() { return errorMsg; } /* * (non-Javadoc) * * @see java.lang.Object#toString() */ @Override public String toString() { return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append("errorCode", errorCode) .append("errorMsg", errorMsg).build(); }}
TestAction:
/** * 2017年4月29日 黑苹果 */package com.black.apple.framework.jersey.rest.action;import java.util.HashMap;import java.util.Map;import com.black.apple.framework.exception.FrameworkErrorCode;import com.black.apple.framework.exception.FrameworkException;import com.black.apple.framework.jersey.rest.action.abs.AbstractAction;import com.black.apple.framework.jersey.rest.req.TestReq;import com.black.apple.framework.jersey.rest.resp.TestResp;/** * @author 黑苹果 2017年4月29日 */public class TestAction extends AbstractAction<TestReq, TestResp>{ private Map<String, String> valueMap = new HashMap<String, String>(); public TestAction() { valueMap.put("key1", "value1"); valueMap.put("key2", "value2"); valueMap.put("key3", "value3"); } /* * (non-Javadoc) * * @see * com.black.apple.framework.jersey.rest.action.abs.AbstractAction#doAction * (java.lang.Object) */ @Override protected TestResp doAction(TestReq request) throws FrameworkException { String key = request.getKey(); String value = valueMap.get(key); TestResp resp = new TestResp(); resp.setValue(value); return resp; } /* * (non-Javadoc) * * @see * com.black.apple.framework.jersey.rest.action.abs.AbstractAction#validateParam * (java.lang.Object) */ @Override protected void validateParam(TestReq request) throws FrameworkException { String key = request.getKey(); if (valueMap.containsKey(key)) { return; } throw new FrameworkException(FrameworkErrorCode.PARAM_INVALID); }}
TestReq:
/** * 2017年4月29日 黑苹果 */package com.black.apple.framework.jersey.rest.req;/** * @author 黑苹果 2017年4月29日 */public class TestReq{ private String key; /** * @return the key */ public String getKey() { return key; } /** * @param key * the key to set */ public void setKey(String key) { this.key = key; } /* * (non-Javadoc) * * @see java.lang.Object#toString() */ @Override public String toString() { return "TestReq [key=" + key + "]"; }}
TestResp:
/** * 2017年4月29日 * 黑苹果 */package com.black.apple.framework.jersey.rest.resp;/** * @author 黑苹果 * 2017年4月29日 */public class TestResp{ private String value; /** * @return the value */ public String getValue() { return value; } /** * @param value the value to set */ public void setValue(String value) { this.value = value; } /* (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { return "TestResp [value=" + value + "]"; } }
TestService:
/** * 2017年4月29日 黑苹果 */package com.black.apple.framework.jersey.rest.service;import javax.ws.rs.POST;import javax.ws.rs.Path;import javax.ws.rs.Produces;import javax.ws.rs.core.MediaType;import javax.ws.rs.core.Response;import com.black.apple.framework.jersey.rest.action.TestAction;/** * @author 黑苹果 2017年4月29日 */@Path("framework")public class TestService{ @POST @Path("test") @Produces(MediaType.APPLICATION_JSON) public Response test(String content) { return new TestAction().execute(content); }}
/** * */package com.black.apple.framework.jersey.utils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.black.apple.framework.exception.FrameworkErrorCode;import com.black.apple.framework.exception.FrameworkException;import com.fasterxml.jackson.core.JsonGenerator;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.ObjectMapper;/** * @author 黑苹果 * */public final class JsonDecodeUtil{ private static final Logger LOGGER = LoggerFactory.getLogger(JsonDecodeUtil.class); private static ObjectMapper mapper = null; static { mapper = new ObjectMapper(); mapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false); } /** * Json转换 * * @param object * 待转JSON的对象 * @return json串 * @throws TosException */ public static <T> String encode(T object) throws FrameworkException { try { String json = mapper.writeValueAsString(object); return json; } catch (JsonProcessingException e) { LOGGER.error("json encode failed.object={}", object, e); throw new FrameworkException(FrameworkErrorCode.JSON_DECODE_EXCEPTION, e); } } /** * Json解析 * * @param json * json串 * @param clazz * 目标类 * @return 目标实例 */ public static <T> T decode(String json, Class<T> clazz) throws FrameworkException { try { T result = mapper.readValue(json, clazz); return result; } catch (Exception e) { LOGGER.error("json decode failed. json={}, clazz={}", json, clazz, e); throw new FrameworkException(FrameworkErrorCode.JSON_DECODE_EXCEPTION, e); } }}
log4j.properties:
log4j.rootCategory=INFO, stdout ,R log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n log4j.appender.R=org.apache.log4j.DailyRollingFileAppenderlog4j.appender.R.File=logs/run.loglog4j.appender.R.layout=org.apache.log4j.PatternLayoutlog4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n
Jmeter测试:
0 0
- Restful后台系统搭建(四)
- Restful后台系统搭建(一)
- Restful后台系统搭建(二)
- Restful后台系统搭建(三)
- Restful后台系统搭建(五)【终章】提供源码
- 移动大脑-SpringMVc搭建RestFul后台服务(四)-添加Token过滤器
- 移动大脑-SpringMVc搭建RestFul后台服务(一)-环境搭建
- RESTful API后台系统架构设计(Java)
- 移动大脑-SpringMVc搭建RestFul后台服务(三)-RestFul接口编写(模拟用户注册登录)
- 移动大脑-SpringMVc搭建RestFul后台服务(六)-微信支付(Android)
- 移动大脑-SpringMVc搭建RestFul后台服务(二)-配置mysql数据库
- 移动大脑-SpringMVc搭建RestFul后台服务(五)-支付宝支付
- 移动大脑-SpringMVc搭建RestFul后台服务(七)-增量更新
- 物联网系统的搭建(四)
- 本地搭建管理后台系统
- 使用moy快速开发后台管理系统(四)
- 使用moy快速开发后台管理系统(四)
- 使用moy快速开发后台管理系统(四)
- Android--权限列表
- 中国日报、大众网等媒体报道 汪国新委员中国式接送有待解决
- 机器学习并没有那么深奥,它很有趣(3)
- web.py学习笔记
- 中国人民政治协商会议第十二届全国委员会第四次会议开幕
- Restful后台系统搭建(四)
- C语言中static变量的作用
- 两会花絮:各显神通拍两会
- 旧键盘打字(20)
- 锋利的Jquery(第二版)笔记(二)
- 关于使用QTcpSocket的一些总结
- 文章标题
- Java Map的底层实现
- 全国政协文史和学习委员会驻会副主任卞晋平莅临汪国新湖北诗书画院