1、spring-mvc.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/websocket
http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd">
<bean class="com.smartprint.biztrip.swagger.config.MySwaggerConfig" />
<!-- <bean class="com.linkage.zhenlv.core.StringHttpMessageConverterUseUTF8BeanPostProcessor"/> -->
<!-- 启用控制器映射注解 -->
<!--<mvc:annotation-driven />-->
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" validator="validator" >
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8" />
</bean>
<ref bean="jacksonMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="jacksonMessageConverter" 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>
<property name="objectMapper" ref="objectMapper" />
</bean>
<bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="timeZone">
<bean class="java.util.TimeZone" factory-method="getTimeZone" >
<constructor-arg value="GMT+08"/>
</bean>
</property>
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd"/>
</bean>
</property>
</bean>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
</bean>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
<property name="favorParameter" value="false" />
<property name="ignoreAcceptHeader" value="false" />
<property name="mediaTypes" >
<value>
atom=application/atom+xml
html=text/html
plain=text/plain
json=application/json
*=*/*
</value>
</property>
</bean>
<!-- 启用权限方法级注解 -->
<bean id="proxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true"/>
</bean>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
<!-- 启用权限方法级注解 -->
<mvc:resources mapping="/swagger/**" location="/WEB-INF/swagger/"/>
<!-- 启用控制器映射注解 <mvc:resources location="/resources/" mapping="/resources/**"/> -->
<mvc:default-servlet-handler/>
<bean class="org.springframework.ui.context.support.ResourceBundleThemeSource" id="themeSource"/>
<bean class="org.springframework.web.servlet.theme.CookieThemeResolver" id="themeResolver" p:cookieName="theme" p:defaultThemeName="standard"/>
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.Throwable">/error/500</prop>
</props>
</property>
</bean>
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="jspViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value=""/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 自动扫描且只扫描@Controller -->
<context:component-scan base-package="com.smartprint.biztrip"
use-default-filters="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
<context:include-filter type="annotation"
expression="org.springframework.web.bind.annotation.ControllerAdvice" />
</context:component-scan>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/api/v1/**" />
*******以下三处不作拦截
<mvc:exclude-mapping path="/api/v1/stat"/>
<mvc:exclude-mapping path="/api/v1/getStat"/>
<mvc:exclude-mapping path="/api/v1/login"/>
<ref bean="requestValidationInterceptor" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/api/v1/**" />
*******以下二处不作拦截
<mvc:exclude-mapping path="/api/v1/login"/>
<ref bean="apiStatInterceptor" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/api/v1/login" />
<ref bean="loginInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
<bean id="requestValidationInterceptor"
class="com.smartprint.biztrip.api.controller.v1.interceptor.RequestValidationInterceptor">
</bean>
<bean id="apiStatInterceptor"
class="com.smartprint.biztrip.api.controller.v1.interceptor.ApiStatInterceptor">
<property name="apiStatService" ref="apiStatService"/>
</bean>
<bean id="loginInterceptor"
class="com.smartprint.biztrip.api.controller.v1.interceptor.LoginInterceptor">
</bean>
</beans>
2、登录拦截器在com.smartprint.biztrip.api.controller.v1.interceptor目录下:
public class LoginInterceptor implements HandlerInterceptor {
private static Logger log = LoggerFactory.getLogger(LoginInterceptor.class);
private static final String ERROR_MSG = "errorMsg";
private JsonMapper map = new JsonMapper();
@Autowired
private IUserService userService;
@Autowired
private ObsUserDbService obsUserDbService;
@Override//该方法是拦截器里最先执行的方法体,只有所有的拦截器里这个方法返回true了,才会把数据传到controller层。而今天在这里遇到一个问题,在request请求里面,有一个requestBody,在这里采用读取输入流的方式拿到,如果不作特殊处理,controller层里拿不到这个requestBody。
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String requestContent = getRequestBody(request);
log.debug("requestContent:{}", requestContent);
LoginParam param = map.fromJson(requestContent, LoginParam.class);
log.debug("param:{}", param);
request.setAttribute("loginParam",param);//给controller层
HttpStatus status = isValidUser(request, param);
if (HttpStatus.OK.equals(status)) {
log.debug("OK");
return true;
}
log.debug("Error");
response.sendError(status.value());
return false;
}
private String getRequestBody(HttpServletRequest request) {
int size = request.getContentLength();
System.out.println(size);
ServletInputStream is = null;
try {
is = request.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
byte[] reqBodyBytes = readBytes(is, size);
String res = new String(reqBodyBytes);
return res;
}
public static final byte[] readBytes(InputStream is, int contentLen) {
if (contentLen > 0) {
int readLen = 0;
int readLengthThisTime = 0;
byte[] message = new byte[contentLen];
try {
while (readLen != contentLen) {
readLengthThisTime = is.read(message, readLen, contentLen
- readLen);
if (readLengthThisTime == -1) {// Should not happen.
break;
}
readLen += readLengthThisTime;
}
return message;
} catch (IOException e) {
}
}
return new byte[]{};
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
3、controller
@Controller
@RequestMapping(value = "/api/v1")
public class LoginController {
private static Logger log = LoggerFactory.getLogger(LoginController.class);
@Autowired
private IUserService userService;
@RequestMapping(value = "/login")
public ResponseEntity<Response<String>> login(HttpServletRequest request, HttpServletResponse response){
log.debug("mobile login success");
LoginParam loginParam = (LoginParam) request.getAttribute("loginParam");//从拦截器那边拿到
log.debug("loginParam:{}",loginParam);
Response<String> resp = new Response<>();
String userName = loginParam.getUserName();
// String password = loginParam.getPassword();
resp.setResult(Result.SUCCESS_RESULT);
String token = System.currentTimeMillis()+"_"+ MD5Util.MD5Encrypt(userName);
resp.setData(token);
// TODO save token in memcached,userDTO
// key:value=token:{userDTO{companyDTO,costCenter,xxx}}
return new ResponseEntity<>(resp, HttpStatus.OK);
}
4、controller的测试代码
public class LoginControllerST extends BaseControllerTestCase {
private final RestTemplate restTemplate = getRestTemplate(baseUrl);
private static String url;
@BeforeClass
public static void initUrl() {
// url="http://localhost:8886/mobileapi/api/v1/login";
}
@Test
public void testLogin() throws Exception{
LoginParam param = new LoginParam();
param.setUserName("tf_jackey");
// param.setPassword("CA4B7574D489718DF1D699EE55156BC0");
param.setPassword("123456");
param.setCode("3333");
String password = MD5Util.MD5Encrypt(param.getPassword());
HttpEntity<LoginParam> requestEntity = new HttpEntity<>(param, null);
System.out.print( jsonMapper.toJson(param));
Response<?> response = restTemplate.postForObject(url, requestEntity, Response.class);
formatHttpInfoPrint(HttpMethod.POST, url, null, "创建记录, 成功", jsonMapper.toJson(param),jsonMapper.toJson(response));
}
}