Commit b29c8358 authored by 胡小根's avatar 胡小根

完成了controller和service的获取列表的构建

parent 916b0400
# 集成Swagger
## 参考:
1. http://shildon.leanote.com/post/Springfox%E9%9B%86%E6%88%90%E5%88%B0%E9%A1%B9%E7%9B%AE
2. http://yukinami.github.io/2015/07/07/%E4%BD%BF%E7%94%A8springfox%E7%94%9F%E6%88%90springmvc%E9%A1%B9%E7%9B%AE%E7%9A%84swagger%E7%9A%84%E6%96%87%E6%A1%A3/
3. http://www.jianshu.com/p/0465a2b837d2
......@@ -43,6 +43,7 @@
<java.version>1.8</java.version>
<poi.version>3.7</poi.version>
<cglib.version>2.2.2</cglib.version>
<springfox.version>2.4.0</springfox.version>
<mybatis.generator.configurationFile>
${basedir}/web/src/main/resources/mysqlGeneratorConfig.xml
......@@ -343,6 +344,33 @@
<artifactId>jpush-client</artifactId>
<version>3.2.9</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.4.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.4</version>
</dependency>
</dependencies>
<build>
......
package com.haomostudio.SpringMVCProjectTemplate.service;
import com.haomostudio.SpringMVCProjectTemplate.dao.ActivityMapper;
import com.haomostudio.SpringMVCProjectTemplate.domain.Activity;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/**
* Created by hxgqh on 2016/10/6.
*/
public interface ActivitiService {
/**
* 获取列表(含翻页\过滤功能)
* @param pageNo
* @param pageSize
* @param sortItem
* @param sortOrder
* @param filters
* @return
*/
List<Activity> getListWithPagingAndFilter(
Integer pageNo, Integer pageSize,
String sortItem, String sortOrder,
String filters);
}
package com.haomostudio.SpringMVCProjectTemplate.service;
import com.haomostudio.SpringMVCProjectTemplate.dao.ActivityMapper;
import com.haomostudio.SpringMVCProjectTemplate.domain.Activity;
import com.haomostudio.SpringMVCProjectTemplate.domain.ActivityExample;
import com.haomostudio.SpringMVCProjectTemplate.service.ActivitiService;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.List;
/**
* Created by hxgqh on 2016/10/6.
*/
public class ActivitiServiceImpl implements ActivitiService{
@Autowired
ActivityMapper activityMapper;
@Override
public List<Activity> getListWithPagingAndFilter(
Integer pageNo, Integer pageSize,
String sortItem, String sortOrder,
String filters){
ActivityExample exampleObj = new ActivityExample();
RowBounds rowBounds = new RowBounds((pageNo - 1) * pageSize, pageSize);
// 转换filters, 将其转换为mybatis-generator的exampleObj对象支持的过滤
// exampleObj.or()
return activityMapper.selectByExampleWithRowbounds(
exampleObj, rowBounds);
}
}
package com.haomostudio.SpringMVCProjectTemplate.service;
import com.haomostudio.SpringMVCProjectTemplate.domain.Country;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* Created by hxgqh on 2016/10/6.
*/
public interface CountryService {
/**
* 获取列表(含翻页\过滤功能)
* @param pageNo
* @param pageSize
* @param sortItem
* @param sortOrder
* @param filters
* @return
*/
List<Country> getListWithPagingAndFilter(
Integer pageNo, Integer pageSize,
String sortItem, String sortOrder,
String filters);
}
package com.haomostudio.SpringMVCProjectTemplate.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.CaseFormat;
import com.haomostudio.SpringMVCProjectTemplate.dao.CountryMapper;
import com.haomostudio.SpringMVCProjectTemplate.domain.Country;
import com.haomostudio.SpringMVCProjectTemplate.domain.CountryExample;
import com.haomostudio.SpringMVCProjectTemplate.service.HmUtils.MybatisExampleHelper;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.lang.reflect.Method;
import java.util.*;
/**
* Created by hxgqh on 2016/10/6.
*/
@Service("countryService")
public class CountryServiceImpl implements CountryService{
@Autowired
CountryMapper countryMapper;
@Override
public List<Country> getListWithPagingAndFilter(
Integer pageNo, Integer pageSize,
String sortItem, String sortOrder,
String filters){
CountryExample exampleObj = new CountryExample();
RowBounds rowBounds = new RowBounds((pageNo - 1) * pageSize, pageSize);
MybatisExampleHelper.assignWhereClause(exampleObj, exampleObj.or(), "Country", filters);
exampleObj.setOrderByClause(MybatisExampleHelper.createOrderClause(sortItem, sortOrder));
return countryMapper.selectByExampleWithRowbounds(
exampleObj, rowBounds);
}
}
package com.haomostudio.SpringMVCProjectTemplate.service.HmUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.CaseFormat;
import com.google.common.util.concurrent.ExecutionError;
import com.haomostudio.SpringMVCProjectTemplate.domain.ActivityExample;
import java.lang.reflect.Method;
import java.util.*;
/**
* Created by hxgqh on 2016/10/7.
*/
public class MybatisExampleHelper {
/**
* 创建mybatis的函数setOrderByClause支持的排序格式
* @param sortItem 格式为: 'id, name'
* @param sortOrder 格式为: 'asc, desc'
* @return
*/
public static String createOrderClause(String sortItem, String sortOrder){
List<String> items = Arrays.asList(sortItem.split(",\\s*"));
List<String> orders = Arrays.asList(sortOrder.split(",\\s*"));
if(items.size() != orders.size()){
return null;
}
else{
List<String> itemOrder = new ArrayList<>();
for(int i=0;i<items.size();i++){
itemOrder.add(items.get(i) + " " + orders.get(i));
}
return String.join(", ", itemOrder);
}
}
/**
* 获取mybatis generator自动生成的过滤函数的名称
* @param column
* @param condition
* @return
*/
public static String getFilterFuncName(String column, String condition){
return "and"
+ column.substring(0,1).toUpperCase() + column.substring(1)
+ CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, condition);
};
public static Method getMethod(Object obj, String methodName){
for(Method m: obj.getClass().getDeclaredMethods()){
if(m.getName().equals(methodName)){
return m;
}
}
return null;
}
/**
* 给mybatis附加上某个字段的条件过滤
* @param exampleObj
* @param exampleObjCriteria
* @param column
* @param condition
* @param value
* @return
*/
public static Object assignCondition(Object exampleObj, Object exampleObjCriteria,
String column ,String condition, Object value){
String funcName = getFilterFuncName(column, condition);
Method m = MybatisExampleHelper.getMethod(exampleObjCriteria, funcName);
switch (condition){
case "isNull":
case "isNotNull":
try{
m.invoke(exampleObjCriteria);
}
catch (ReflectiveOperationException e){
throw new RuntimeException(e);
}
break;
case "between":
case "notBetween":
try{
m.invoke(exampleObjCriteria,
((List<String>) value).get(0),
((List<String>) value).get(1));
}
catch (ReflectiveOperationException e){
throw new RuntimeException(e);
}
break;
default:
try{
m.invoke(exampleObjCriteria, value);
}
catch (ReflectiveOperationException e){
throw new RuntimeException(e);
}
break;
}
return exampleObj;
}
/**
* 给mybatis的Example对象附加上
* @param exampleObj
* @param exampleObjCriteria
* @param filters JSON字符串,格式为
* {
* table:
* {
* column1: {
* like: '%abc%',
* notLike: ''
* between: [1, 10],
* notBetween: [1, 10]
* isNull: true, // 只能为true
* isNotNull: true, // 只能为true
* equalTo: "abc",
* notEqualTo: "abc",
* greaterThan: 10,
* greaterThanOrEqualTo: 10,
* lessThan: 10,
* lessThanOrEqualTo: 10,
* in: [],
* notIn: []
* }
* }
*
* }
* @return
*/
public static Object assignWhereClause (Object exampleObj,
Object exampleObjCriteria,
String className,
String filters){
JSONObject filterObj = JSON.parseObject(filters);
if(!filterObj.containsKey(
CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, className)
)){
return exampleObjCriteria;
}
JSONObject columnCondition = filterObj.getJSONObject(
CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, className));
Set<Map.Entry<String, Object>> entrySet = columnCondition.entrySet();
for(Map.Entry<String, Object> entry: entrySet){
String column = entry.getKey();
JSONObject conditionObj = (JSONObject) entry.getValue();
Set<Map.Entry<String, Object>> conditionObjEntrySet
= conditionObj.entrySet();
for(Map.Entry<String, Object> coes: conditionObjEntrySet){
exampleObj = assignCondition(
exampleObj, exampleObjCriteria,
column, coes.getKey(), coes.getValue());
}
}
return exampleObjCriteria;
}
}
package com.haomostudio.SpringMVCProjectTemplate.common;
import java.util.HashMap;
import java.util.Map;
public class Resp {
public static final int SUCCESS = 0;
public static final int FAIL = -1;
public static final int WARN = 1;
public static final String CODE = "code";
public static final String MSG = "message";
public static final String FIELDS = "fields";
public static Map<String, Object> succ(String message) {
return result(SUCCESS, message, null);
}
public static Map<String, Object> succ(String message, Object fields) {
return result(SUCCESS, message, fields);
}
public static Map<String, Object> fail(String message) {
return result(FAIL, message, null);
}
public static Map<String, Object> warn(String message) {
return result(WARN, message, null);
}
public static Map<String, Object> fail(int code, String message) {
return result(code, message, null);
}
public static Map<String, Object> fail(String message, Object fields) {
return result(FAIL, message, fields);
}
public static Map<String, Object> result(int code, String message, Object fields) {
Map<String, Object> map = new HashMap<>();
map.put(CODE, code);
map.put(MSG, message);
map.put(FIELDS, fields);
return map;
}
}
package com.haomostudio.SpringMVCProjectTemplate.controller;
import com.haomostudio.SpringMVCProjectTemplate.service.ActivitiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
/**
* Created by hxgqh on 2016/10/6.
*/
public class ActivitiController {
@Autowired
ActivitiService activitiService;
@Autowired
HttpServletResponse response;
@RequestMapping(value = "/activities", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
@ResponseBody
public Object getActivities(
@RequestHeader(value = "X-Auth-Token") String token,
@RequestHeader(value = "page_no") Integer pageNo,
@RequestHeader(value = "page_size") Integer pageSize,
@RequestHeader(value = "sort_item") String sortItem,
@RequestHeader(value = "sort_order") String sortOrder,
@RequestHeader(value = "filters") String filters
) {
return activitiService.getListWithPagingAndFilter(
pageNo, pageSize, sortItem, sortOrder, filters);
}
}
package com.haomostudio.SpringMVCProjectTemplate.controller;
import com.haomostudio.SpringMVCProjectTemplate.service.ActivitiService;
import com.haomostudio.SpringMVCProjectTemplate.service.CountryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
/**
* Created by hxgqh on 2016/10/6.
*/
@Controller
public class CountryController {
@Autowired
CountryService countryService;
@Autowired
HttpServletResponse response;
@RequestMapping(value = "/countries",
method = RequestMethod.GET,
produces = "application/json;charset=UTF-8")
@ResponseBody
public Object getCountries(
@RequestHeader(value = "page_no") Integer pageNo,
@RequestHeader(value = "page_size") Integer pageSize,
@RequestHeader(value = "sort_item") String sortItem,
@RequestHeader(value = "sort_order") String sortOrder,
@RequestHeader(value = "filters") String filters
) {
return countryService.getListWithPagingAndFilter(
pageNo, pageSize, sortItem, sortOrder, filters);
}
}
package com.haomostudio.SpringMVCProjectTemplate.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
@Controller
public class EndpointDocController {
private final RequestMappingHandlerMapping handlerMapping;
@Autowired
public EndpointDocController(RequestMappingHandlerMapping handlerMapping) {
this.handlerMapping = handlerMapping;
}
@RequestMapping(value="/endpointdoc", method=RequestMethod.GET)
public void show(Model model) {
model.addAttribute("handlerMethods", this.handlerMapping.getHandlerMethods());
}
}
package com.haomostudio.SpringMVCProjectTemplate.servlet;
import com.haomostudio.SpringMVCProjectTemplate.common.Resp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import javax.naming.AuthenticationException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
/**
* Output error/exception as JSON and also can be used a global error logger.
* Created by Stevie on 2015/12/22.
*/
public class DefaultHandlerExceptionResolver implements HandlerExceptionResolver {
private final static Logger LOG = LoggerFactory.getLogger(DefaultHandlerExceptionResolver.class.getName());
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handlerMethod, Exception e) {
if (e.getMessage() != null && !e.getMessage().contains("Authentication Failed. Please Login.")
&& !e.getMessage().contains("Missing request header 'X-Auth-Token'")
&& !(e instanceof org.springframework.web.bind.MissingServletRequestParameterException)) {
LOG.error(request.getRequestURI(), e);
e.printStackTrace();
}
if (e instanceof AuthenticationException) {
response.setStatus(403);
} else {
response.setStatus(500);
}
ModelAndView mv = new ModelAndView();
//set data
Map<String, Object> result = Resp.fail(e.getMessage());
mv.addAllObjects(result);
//set view
MappingJackson2JsonView view = new MappingJackson2JsonView();
mv.setView(view);
return mv;
}
}
package com.haomostudio.SpringMVCProjectTemplate.servlet;
import org.springframework.core.MethodParameter;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
/**
* Created by Stevie on 2015/12/22.
*/
public class EmptyRequestParamResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return (parameter.getParameterType().isAssignableFrom(String.class)) && (null != parameter.getParameterAnnotation(RequestParam.class));
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
RequestParam ann = parameter.getParameterAnnotation(RequestParam.class);
Object arg = webRequest.getParameter(ann.value());
if (StringUtils.isEmpty(arg)) {
throw new MissingServletRequestParameterException(ann.value(), parameter.getParameterType().getSimpleName());
}
return arg;
}
}
......@@ -3,8 +3,8 @@
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.xsd">
<bean id="redisServer" class="com.haomostudio.redis.RedisServiceImpl" init-method="init">
<property name="redisIp" value="${redis.ip}"></property>
<property name="redisPort" value="${redis.port}"></property>
</bean>
<!--<bean id="redisServer" class="com.haomostudio.redis.RedisServiceImpl" init-method="init">-->
<!--<property name="redisIp" value="${redis.ip}"></property>-->
<!--<property name="redisPort" value="${redis.port}"></property>-->
<!--</bean>-->
</beans>
......@@ -19,9 +19,9 @@
expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
<mvc:interceptors>
<bean class="com.haomostudio.SpringMVCProjectTemplate.web.servlet.AuthenticationInterceptor"/>
</mvc:interceptors>
<!--<mvc:interceptors>-->
<!--<bean class="com.haomostudio.SpringMVCProjectTemplate.web.servlet.AuthenticationInterceptor"/>-->
<!--</mvc:interceptors>-->
<!-- 定义首页 -->
<!--
......@@ -43,7 +43,7 @@
<!-- 支持上传文件 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
<bean id="handlerExceptionResolver" class="com.haomostudio.SpringMVCProjectTemplate.web.servlet.DefaultHandlerExceptionResolver"/>
<bean id="handlerExceptionResolver" class="com.haomostudio.SpringMVCProjectTemplate.servlet.DefaultHandlerExceptionResolver"/>
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>
......@@ -83,4 +83,8 @@
</property>
</bean>
<bean name="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<!-- add your properties here property name="..." value="..."></property-->
</bean>
</beans>
......@@ -8,9 +8,9 @@
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.github.miemiedev.mybatis.paginator.CleanupMybatisPaginatorListener</listener-class>
</listener>
<!--<listener>-->
<!--<listener-class>com.github.miemiedev.mybatis.paginator.CleanupMybatisPaginatorListener</listener-class>-->
<!--</listener>-->
<context-param>
<param-name>contextConfigLocation</param-name>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment