瑞吉外卖总体来说挺简单的(crud部分), 但是用了一些以前没用过的技术和技巧, 所以做完之后做个复盘, 避免遗忘
员工后台部分
登录控制
使用 过滤器 接管全部的请求, 确保只有已登录用户才可以使用功能
@WebFilter(filterName = "LoginCheckFilter", urlPatterns = "/*")//这个注解就可以起到接管所有请求的作用
public class LoginCheckFilter implements Filter {
定义出不需要过滤器管理的路径(一般是静态资源和登录要用的东西)
//2. 定义不需要不需要过滤的请求
String[] uris = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**",
"/common/**",
"/user/sendMsg",//移动端发送邮件
"/user/login"//移动端登录
};
使用springframework中自带的路径比较器检查有没有匹配上路径
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
//使用方法
PATH_MATCHER.match(url, requestURI)//会返回一个布尔值
当员工登录的时候, 在后端需要存入对应session
HttpSession session = request.getSession();
session.setAttribute("employee", emp.getId());
这样就可以通过检查当前客户端在后端对应的session是否存在, 判断员工是否登录了!
request.getSession().getAttribute("employee") != null即为已经登录
综上所述, 只要符合 访问的是白名单 或者 已经登录 , 都可以放行
filterChain.doFilter(request, response);
反之返回未登录的json, 这里又涉及到一个知识点:阿里巴巴的fastjson
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
JSON.toJSONString(R.error("NOTLOGIN")//这样可以生成一个json字符串
扩展json消息转换器
要扩展mvc框架的消息转换器, 我们需要在springMVC的配置类中重写extendMessageConverters方法:
- 创建消息转换器对象
- 把创建出来的消息转换器的对象转换器设置成jackson
- 把自己创建出来的消息转换器对象添加到mvc框架自带的转换器集合, 优先度设置为0
实操代码:
@Slf4j
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
/**
* 扩展mvc框架的消息转换器
* @param converters
*/
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
//创建消息转换器对象
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
//设置对象转换器, 底层使用Jackson转换Java对象到json
messageConverter.setObjectMapper(new JacksonObjectMapper());
//添加到mvc自带的转换器集合, 并且设置为T0
converters.add(0, messageConverter);
}
}
JacksonObjectMapper 的代码如下:
package com.itheima.reggie.common;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
/**
* 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
* 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
* 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
*/
public class JacksonObjectMapper extends ObjectMapper {
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
public JacksonObjectMapper() {
super();
//收到未知属性时不报异常
this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
//反序列化时,属性不存在的兼容处理
this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
SimpleModule simpleModule = new SimpleModule()
.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
.addSerializer(BigInteger.class, ToStringSerializer.instance)
.addSerializer(Long.class, ToStringSerializer.instance)
.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
//注册功能模块 例如,可以添加自定义序列化器和反序列化器
this.registerModule(simpleModule);
}
}