文章目录
1返回的状态吗不对?1.1自定义返回状态码的方式1.1.1 用ResponseEntity1.1.2@ResponseStatus定义在异常类1.1.3@ResponseStatus定义在方法上1.1.4@RestControllerAdvice
2时间序列化与反序列化2.1 @DateTimeFormat2.2@JsonFormat2.3@JsonDeserialize 局部2.4定义一个全局配置类
3日志到底放在拦截器,还是过滤器?3.1 过滤器3.2 拦截器3.3 上述代码中过滤器和拦截器的比较
4获取不到数据?
1返回的状态吗不对?
1.1自定义返回状态码的方式
1.1.1 用ResponseEntity
1.1.2@ResponseStatus定义在异常类
1.1.3@ResponseStatus定义在方法上
一般重定向时候用,比如重定向到response404
1.1.4@RestControllerAdvice
public class CustomException extends Exception {
public CustomException(String message
) {
super(message
);
}
}
@RestControllerAdvice
public class GlobalExceptionAdvice {
@ExceptionHandler(value
= CustomException
.class)
public ResponseEntity
<GeneralResponse
<String>> handleCustomException(
HttpServletRequest request
, CustomException ex
) {
GeneralResponse
<String> result
= new GeneralResponse<>(0, "");
result
.setData(ex
.getMessage());
return new ResponseEntity<>(result
, HttpStatus
.BAD_REQUEST
);
}
}
@GetMapping("/fourth")
public GeneralResponse
<String> fourth() throws CustomException
{
throw new CustomException("some error");
}
2时间序列化与反序列化
例子:
2.1 @DateTimeFormat
测试: get方法可以接收到时间参数 post 方法报错 原因: 一般都是使用@DateTimeFormat把传给后台的时间字符串转成Date,使用@JsonFormat把后台传出的Date转成时间字符串,但是@DateTimeFormat只会在类似@RequestParam的请求参数(url拼接的参数才生效,如果是放到RequestBody中的form-data也是无效的)上生效,如果@DateTimeFormat放到@RequestBody下是无效的。
在@RequestBody中则可以使用@JsonFormat把传给后台的时间字符串转成Date,也就是说@JsonFormat其实既可以把传给后台的时间字符串转成Date也可以把后台传出的Date转成时间字符串。
2.2@JsonFormat
@JsonFormat(pattern = “yyyy-MM-dd HH:mm:ss”, timezone = “GMT+8”) private Date time;
缺点:只支持这一种格式;yyyy-MM-dd HH:mm:ss,兼容性不好 改进:写一个通用转化器,自定义一个反序列化器
2.3@JsonDeserialize 局部
package com
.imooc
.spring
.escape
.date_se_de
;
import com
.fasterxml
.jackson
.core
.JsonParser
;
import com
.fasterxml
.jackson
.core
.JsonProcessingException
;
import com
.fasterxml
.jackson
.databind
.DeserializationContext
;
import com
.fasterxml
.jackson
.databind
.JsonDeserializer
;
import lombok
.extern
.slf4j
.Slf4j
;
import org
.apache
.commons
.lang3
.StringUtils
;
import org
.apache
.commons
.lang3
.time
.DateUtils
;
import java
.io
.IOException
;
import java
.text
.ParseException
;
import java
.util
.Date
;
@Slf4j
public class DateJacksonConverter extends JsonDeserializer<Date> {
private static final String
[] pattern
= new String[] {
"yyyy-MM-dd HH:mm:ss", "yyyy/MM/dd"
};
@Override
public Date
deserialize(JsonParser jsonParser
, DeserializationContext context
)
throws IOException
, JsonProcessingException
{
Date targetDate
= null
;
String originDate
= jsonParser
.getText();
if (StringUtils
.isNotEmpty(originDate
)) {
try {
long longDate
= Long
.parseLong(originDate
.trim());
targetDate
= new Date(longDate
);
} catch (NumberFormatException pe
) {
try {
targetDate
= DateUtils
.parseDate(
originDate
, DateJacksonConverter
.pattern
);
} catch (ParseException ex
) {
log
.error("parse error: {}", ex
.getMessage());
throw new IOException("parse error");
}
}
}
return targetDate
;
}
}
使用: 缺点:是一个局部处理,侵入性强,代码维护性差
2.4定义一个全局配置类
package com
.imooc
.spring
.escape
.date_se_de
;
import com
.fasterxml
.jackson
.core
.JsonParser
;
import com
.fasterxml
.jackson
.core
.JsonProcessingException
;
import com
.fasterxml
.jackson
.databind
.DeserializationContext
;
import com
.fasterxml
.jackson
.databind
.JsonDeserializer
;
import lombok
.extern
.slf4j
.Slf4j
;
import org
.apache
.commons
.lang3
.StringUtils
;
import org
.apache
.commons
.lang3
.time
.DateUtils
;
import java
.io
.IOException
;
import java
.text
.ParseException
;
import java
.util
.Date
;
@Slf4j
public class DateJacksonConverter extends JsonDeserializer<Date> {
private static final String
[] pattern
= new String[] {
"yyyy-MM-dd HH:mm:ss", "yyyy/MM/dd"
};
@Override
public Date
deserialize(JsonParser jsonParser
, DeserializationContext context
)
throws IOException
, JsonProcessingException
{
Date targetDate
= null
;
String originDate
= jsonParser
.getText();
if (StringUtils
.isNotEmpty(originDate
)) {
try {
long longDate
= Long
.parseLong(originDate
.trim());
targetDate
= new Date(longDate
);
} catch (NumberFormatException pe
) {
try {
targetDate
= DateUtils
.parseDate(
originDate
, DateJacksonConverter
.pattern
);
} catch (ParseException ex
) {
log
.error("parse error: {}", ex
.getMessage());
throw new IOException("parse error");
}
}
}
return targetDate
;
}
@Override
public Class
<?> handledType() {
return Date
.class;
}
}
@Configuration
public class DateConverterConfig {
@Bean
public DateJacksonConverter
dateJacksonConverter() {
return new DateJacksonConverter();
}
@Bean
public Jackson2ObjectMapperFactoryBean
jackson2ObjectMapperFactoryBean(
@Autowired DateJacksonConverter dateJacksonConverter
) {
Jackson2ObjectMapperFactoryBean jackson2ObjectMapperFactoryBean
=
new Jackson2ObjectMapperFactoryBean();
jackson2ObjectMapperFactoryBean
.setDeserializers(dateJacksonConverter
);
return jackson2ObjectMapperFactoryBean
;
}
}
使用:
3日志到底放在拦截器,还是过滤器?
3.1 过滤器
package com
.imooc
.spring
.escape
.filter_and_interceptor
;
import lombok
.extern
.slf4j
.Slf4j
;
import javax
.servlet
.Filter
;
import javax
.servlet
.FilterChain
;
import javax
.servlet
.FilterConfig
;
import javax
.servlet
.ServletException
;
import javax
.servlet
.ServletRequest
;
import javax
.servlet
.ServletResponse
;
import javax
.servlet
.annotation
.WebFilter
;
import javax
.servlet
.http
.HttpServletRequest
;
import java
.io
.IOException
;
@Slf4j
@WebFilter(urlPatterns
= "/*", filterName
= "LogFilter")
public class LogFilter implements Filter {
@Override
public void init(FilterConfig filterConfig
) throws ServletException
{
}
@Override
public void doFilter(ServletRequest request
, ServletResponse response
,
FilterChain chain
) throws IOException
, ServletException
{
long start
= System
.currentTimeMillis();
chain
.doFilter(request
, response
);
log
.info("LogFilter Print Log: {} -> {}",
((HttpServletRequest
) request
).getRequestURI(),
System
.currentTimeMillis() - start
);
}
@Override
public void destroy() {
}
}
3.2 拦截器
package com
.imooc
.spring
.escape
.filter_and_interceptor
;
import lombok
.extern
.slf4j
.Slf4j
;
import org
.springframework
.stereotype
.Component
;
import org
.springframework
.web
.method
.HandlerMethod
;
import org
.springframework
.web
.servlet
.HandlerInterceptor
;
import org
.springframework
.web
.servlet
.ModelAndView
;
import javax
.servlet
.http
.HttpServletRequest
;
import javax
.servlet
.http
.HttpServletResponse
;
@Slf4j
@Component
public class LogInterceptor implements HandlerInterceptor {
long start
= System
.currentTimeMillis();
@Override
public boolean preHandle(HttpServletRequest request
,
HttpServletResponse response
, Object handler
)
throws Exception
{
start
= System
.currentTimeMillis();
HandlerMethod handlerMethod
= (HandlerMethod
) handler
;
log
.info("LogInterceptor: {}", ((HandlerMethod
) handler
).getBean()
.getClass().getName());
log
.info("LogInterceptor: {}", handlerMethod
.getMethod().getName());
return true;
}
@Override
public void postHandle(HttpServletRequest request
,
HttpServletResponse response
, Object handler
,
ModelAndView modelAndView
) throws Exception
{
log
.info("LogInterceptor Print Log: {} -> {}",
request
.getRequestURI(),
System
.currentTimeMillis() - start
);
}
@Override
public void afterCompletion(HttpServletRequest request
,
HttpServletResponse response
, Object handler
,
Exception ex
) throws Exception
{
}
}
拦截器中定义啦一个全局变量 long start = System.currentTimeMillis(); 是线程不安全的 改进:
package com
.imooc
.spring
.escape
.filter_and_interceptor
;
import lombok
.extern
.slf4j
.Slf4j
;
import org
.springframework
.stereotype
.Component
;
import org
.springframework
.web
.servlet
.HandlerInterceptor
;
import org
.springframework
.web
.servlet
.ModelAndView
;
import javax
.servlet
.http
.HttpServletRequest
;
import javax
.servlet
.http
.HttpServletResponse
;
@Slf4j
@Component
public class UpdateLogInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request
,
HttpServletResponse response
,
Object handler
) throws Exception
{
request
.setAttribute("startTime", System
.currentTimeMillis());
return true;
}
@Override
public void postHandle(HttpServletRequest request
,
HttpServletResponse response
, Object handler
,
ModelAndView modelAndView
) throws Exception
{
log
.info("UpdateLogInterceptor Print Log: {} -> {}",
request
.getRequestURI(),
System
.currentTimeMillis() - (long) request
.getAttribute("startTime"));
}
@Override
public void afterCompletion(HttpServletRequest request
,
HttpServletResponse response
,
Object handler
, Exception ex
) throws Exception
{
}
}
package com
.imooc
.spring
.escape
.filter_and_interceptor
;
import com
.imooc
.spring
.escape
.http_request_response
.User
;
import com
.imooc
.spring
.escape
.http_request_response
.UserIdInterceptor
;
import org
.springframework
.context
.annotation
.Configuration
;
import org
.springframework
.stereotype
.Component
;
import org
.springframework
.web
.servlet
.config
.annotation
.InterceptorRegistry
;
import org
.springframework
.web
.servlet
.config
.annotation
.WebMvcConfigurer
;
@Component
@Configuration
public class WebInterceptorAdapter implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry
) {
registry
.addInterceptor(new LogInterceptor()).addPathPatterns("/**").order(0);
registry
.addInterceptor(new UpdateLogInterceptor())
.addPathPatterns("/**").order(1);
registry
.addInterceptor(new UserIdInterceptor()).addPathPatterns("/**")
.order(3);
}
}
3.3 上述代码中过滤器和拦截器的比较
4获取不到数据?