BaseRestEndPoint.java 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. package com.yihu.ehr.controller;
  2. import com.fasterxml.jackson.core.JsonProcessingException;
  3. import com.fasterxml.jackson.databind.ObjectMapper;
  4. import com.yihu.ehr.constants.PageArg;
  5. import com.yihu.ehr.util.datetime.DateTimeUtil;
  6. import org.apache.commons.lang3.StringUtils;
  7. import org.springframework.beans.BeanUtils;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.http.ResponseEntity;
  10. import org.springframework.web.servlet.ModelAndView;
  11. import org.springframework.web.servlet.mvc.AbstractController;
  12. import javax.servlet.http.HttpServletRequest;
  13. import javax.servlet.http.HttpServletResponse;
  14. import java.beans.PropertyDescriptor;
  15. import java.io.IOException;
  16. import java.lang.reflect.Method;
  17. import java.text.SimpleDateFormat;
  18. import java.util.*;
  19. /**
  20. * 控制器基类。提供模型转换,分页规范实现。
  21. *
  22. * @author Sand
  23. * @version 1.0
  24. * @created 2016.04.07 17:01
  25. */
  26. public class BaseRestEndPoint extends AbstractController {
  27. protected final static String ResourceCount = "X-Total-Count";
  28. protected final static String ResourceLink = "Link";
  29. @Autowired
  30. protected ObjectMapper objectMapper;
  31. @Override
  32. protected ModelAndView handleRequestInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
  33. return null;
  34. }
  35. /**
  36. * 字符串转实体
  37. *
  38. * @param json
  39. * @param entityCls
  40. * @param <T>
  41. * @return
  42. * @throws IOException
  43. */
  44. protected <T> T toEntity(String json, Class<T> entityCls) throws IOException {
  45. objectMapper.setDateFormat(new SimpleDateFormat(DateTimeUtil.simpleDateTimePattern));
  46. T entity = objectMapper.readValue(json, entityCls);
  47. return entity;
  48. }
  49. /**
  50. * 实体转字符串
  51. *
  52. * @param obj
  53. * @return
  54. * @throws JsonProcessingException
  55. */
  56. protected String toJson(Object obj) throws JsonProcessingException {
  57. return objectMapper.writeValueAsString(obj);
  58. }
  59. /**
  60. * 将实体转换为模型
  61. *
  62. * @param source
  63. * @param targetCls
  64. * @param properties
  65. * @param <T>
  66. * @return
  67. */
  68. protected <T> T convertToModel(Object source, Class<T> targetCls, String... properties) {
  69. if (source == null) {
  70. return null;
  71. }
  72. T target = BeanUtils.instantiate(targetCls);
  73. BeanUtils.copyProperties(source, target, propertyDiffer(properties, targetCls));
  74. return target;
  75. }
  76. /**
  77. * 将实体集合转换为模型集合
  78. *
  79. * @param sources
  80. * @param targets
  81. * @param properties
  82. * @param <T>
  83. * @return
  84. */
  85. protected <T> Collection<T> convertToModels(Collection sources, Collection<T> targets, Class<T> targetCls, String properties) {
  86. if (sources == null) {
  87. return null;
  88. }
  89. Iterator iterator = sources.iterator();
  90. while (iterator.hasNext()) {
  91. Object source = iterator.next();
  92. T target = BeanUtils.instantiate(targetCls);
  93. BeanUtils.copyProperties(source, target, propertyDiffer(StringUtils.isEmpty(properties) ? null : properties.split(","), targetCls));
  94. targets.add(target);
  95. }
  96. return targets;
  97. }
  98. /**
  99. * 计算不在类中的属性。
  100. *
  101. * @return
  102. */
  103. protected String[] propertyDiffer(String[] properties, Class targetCls) {
  104. if (properties == null || properties.length == 0) return null;
  105. PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(targetCls);
  106. List<String> propertiesList = Arrays.asList(properties);
  107. List<String> arrayList = new ArrayList<>();
  108. for (PropertyDescriptor targetPd : targetPds) {
  109. Method writeMethod = targetPd.getWriteMethod();
  110. if (writeMethod != null && !propertiesList.contains(targetPd.getName())) {
  111. arrayList.add(targetPd.getName());
  112. }
  113. }
  114. return arrayList.toArray(new String[arrayList.size()]);
  115. }
  116. /**
  117. * 客户端调用REST接口时,若返回的是分页结果,则需要在响应头中添加资源的总数量及其他资源的分页导航。
  118. * EHR平台使用响应头中的 X-Total-Count 字段记录资源的总数量,link header作为其他资源的分页导航。
  119. *
  120. * @return
  121. */
  122. protected void pagedResponse(
  123. HttpServletRequest request,
  124. HttpServletResponse response,
  125. Long resourceCount, Integer currentPage, Integer pageSize) {
  126. if (request == null || response == null) return;
  127. response.setHeader(ResourceCount, Long.toString(resourceCount));
  128. if (resourceCount == 0) return;
  129. if (currentPage == null) currentPage = new Integer(PageArg.DefaultPage);
  130. if (pageSize == null) pageSize = new Integer(PageArg.DefaultSize);
  131. String baseUri = "<" + request.getRequestURL().append("?").toString() + request.getQueryString() + ">";
  132. long firstPage = currentPage == 1 ? -1 : 1;
  133. long prevPage = currentPage == 1 ? -1 : currentPage - 1;
  134. long lastPage = resourceCount % pageSize == 0 ? resourceCount / pageSize : resourceCount / pageSize + 1;
  135. long nextPage = currentPage == lastPage ? -1 : currentPage + 1;
  136. lastPage = currentPage == lastPage ? -1 : lastPage;
  137. Map<String, String> map = new HashMap<>();
  138. if (firstPage != -1)
  139. map.put("rel='first',", baseUri.replaceAll("page=\\d+", "page=" + Long.toString(firstPage)));
  140. if (prevPage != -1) map.put("rel='prev',", baseUri.replaceAll("page=\\d+", "page=" + Long.toString(prevPage)));
  141. if (nextPage != -1) map.put("rel='next',", baseUri.replaceAll("page=\\d+", "page=" + Long.toString(nextPage)));
  142. if (lastPage != -1) map.put("rel='last',", baseUri.replaceAll("page=\\d+", "page=" + Long.toString(lastPage)));
  143. response.setHeader(ResourceLink, linkMap(map));
  144. }
  145. protected Integer reducePage(Integer page) {
  146. if (page != null || page > 0) {
  147. page = page - 1;
  148. return page;
  149. }
  150. return 1;
  151. }
  152. protected String getClientId(HttpServletRequest request){
  153. String userAgent = "";
  154. Enumeration<String> headers = request.getHeaders("User-Agent");
  155. while (headers.hasMoreElements()){
  156. String s = headers.nextElement();
  157. if (!s.contains("jetty")){
  158. userAgent = s;
  159. }
  160. }
  161. return StringUtils.isEmpty(userAgent) ? "" : userAgent.split(" ").length > 1 ? userAgent.split(" ")[1] : userAgent.split(" ")[0];
  162. }
  163. protected int getTotalCount(ResponseEntity responseEntity) {
  164. return Integer.parseInt(responseEntity.getHeaders().get(ResourceCount).get(0));
  165. }
  166. private String linkMap(Map<String, String> map) {
  167. StringBuffer links = new StringBuffer("");
  168. for (String key : map.keySet()) {
  169. links.append(map.get(key)).append("; ").append(key);
  170. }
  171. return links.toString();
  172. }
  173. }