这篇文章是无关业务逻辑代码的基础配置
目录
最近学习java项目开发,对springboot项目进行总结,该文章是对于非业务代码的总结
一、相关配置
1. 数据库相关配置
根据Mybatis-generator插件生成对应的实体类与Mapper
pom.xml配置
<plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.7</version> <configuration> <verbose>true</verbose> <overwrite>true</overwrite> </configuration> </plugin>
首先得有配置文件generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <!-- 配置文件,放在resource目录下即可 --> <!--数据库驱动个人配置,此处遵循mvn的下载地址--> <classPathEntry location="maven-repo\mysql\mysql-connector-java\8.0.18\mysql-connector-java-8.0.18.jar"/> <context id="MysqlTables" targetRuntime="MyBatis3"> <property name="autoDelimitKeywords" value="true"/> <!--可以使用``包括字段名,避免字段名与sql保留字冲突报错--> <property name="beginningDelimiter" value="`"/> <property name="endingDelimiter" value="`"/> <!-- optional,旨在创建class时,对注释进行控制 --> <commentGenerator> <property name="suppressDate" value="true"/> <property name="suppressAllComments" value="true"/> </commentGenerator <!--数据库链接地址账号密码--> <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3306/imooc_mall?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull" userId="root" password="123456"> <property name="nullCatalogMeansCurrent" value="true"/> </jdbcConnection> <!-- 非必需,类型处理器,在数据库类型和java类型之间的转换控制--> <javaTypeResolver> <property name="forceBigDecimals" value="false"/> </javaTypeResolver> <!--生成Model类存放位置--> <javaModelGenerator targetPackage="com.imooc.mall.model.pojo" targetProject="src/main/java"> <!-- 是否允许子包,即targetPackage.schemaName.tableName --> <property name="enableSubPackages" value="true"/> <!-- 是否对类CHAR类型的列的数据进行trim操作 --> <property name="trimStrings" value="true"/> <!-- 建立的Model对象是否 不可改变 即生成的Model对象不会有 setter方法,只有构造方法 --> <property name="immutable" value="false"/> </javaModelGenerator> <!--生成mapper映射文件存放位置--> <sqlMapGenerator targetPackage="mappers" targetProject="src/main/resources"> <property name="enableSubPackages" value="true"/> </sqlMapGenerator> <!--生成Dao类存放位置--> <javaClientGenerator type="XMLMAPPER" targetPackage="com.imooc.mall.model.dao" targetProject="src/main/java"> <property name="enableSubPackages" value="true"/> </javaClientGenerator> <!--生成对应表及类名--> <table schema="root" tableName="imooc_mall_cart" domainObjectName="Cart" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"> </table> <table tableName="imooc_mall_category" domainObjectName="Category" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"> </table> <table tableName="imooc_mall_order" domainObjectName="Order" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"> </table> <table tableName="imooc_mall_order_item" domainObjectName="OrderItem" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"> </table> <table tableName="imooc_mall_product" domainObjectName="Product" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"> </table> <table tableName="imooc_mall_user" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"> </table> </context> </generatorConfiguration>
然后如下图双击生成实体类型以及xml和DAO接口
在application.properties中配置数据库
指明mappers的位置
spring.datasource.name=imooc_mall_datasource spring.datasource.url=jdbc:mysql://127.0.0.1:3306/imooc_mall?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.username=root spring.datasource.password=123456 mybatis.mapper-locations=classpath:mappers/*.xml
打通Controller到service到DAO层(测试)
需要在主函数上配置basePackages说明DAO在那里
如果测试正确就代表数据库配置完成。
2.日志系统相关配置
移除logback 使用log4j配置pom.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <!--log4j2日志依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
引入log4j包后需要配置log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="fatal">
<Properties>
<!-- value中是所包含存储日志的地方-->
<Property name="baseDir" value="D:/logs/mallLog"/>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout
pattern="[%d{MM:dd HH:mm:ss.SSS}] [%level] [%logger{36}] - %msg%n"/>
</Console>
<!--debug级别日志文件输出-->
<RollingFile name="debug_appender" fileName="${baseDir}/debug.log"
filePattern="${baseDir}/debug_%i.log.%d{yyyy-MM-dd}">
<!-- 过滤器 -->
<Filters>
<!-- 限制日志级别在debug及以上在info以下 -->
<ThresholdFilter level="debug"/>
<ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL"/>
</Filters>
<!-- 日志格式 -->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<!-- 策略 -->
<Policies>
<!-- 每隔一天转存 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<!-- 文件大小 -->
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<!-- info级别日志文件输出 -->
<RollingFile name="info_appender" fileName="${baseDir}/info.log"
filePattern="${baseDir}/info_%i.log.%d{yyyy-MM-dd}">
<!-- 过滤器 -->
<Filters>
<!-- 限制日志级别在info及以上在error以下 -->
<ThresholdFilter level="info"/>
<ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
</Filters>
<!-- 日志格式 -->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<!-- 策略 -->
<Policies>
<!-- 每隔一天转存 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<!-- 文件大小 -->
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<!-- error级别日志文件输出 -->
<RollingFile name="error_appender" fileName="${baseDir}/error.log"
filePattern="${baseDir}/error_%i.log.%d{yyyy-MM-dd}">
<!-- 过滤器 -->
<Filters>
<!-- 限制日志级别在error及以上 -->
<ThresholdFilter level="error"/>
</Filters>
<!-- 日志格式 -->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<!-- 每隔一天转存 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<!-- 文件大小 -->
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console"/>
<AppenderRef ref="debug_appender"/>
<AppenderRef ref="info_appender"/>
<AppenderRef ref="error_appender"/>
</Root>
</Loggers>
</Configuration>
然后配置截断器,也就是一切流量都会经过日志,新建Filter目录下WebLogAspect.xml
package com.imooc.mall.Filter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
@Aspect
@Component
public class WebLogAspect {
private final Logger log = LoggerFactory.getLogger(WebLogAspect.class);
//经过控制器的所有流量
@Pointcut("execution(public * com.imooc.mall.Controller.*.*(..))")
public void webLog() {
}
@Before("webLog()")
//请求发生之前
public void doBefore(JoinPoint joinPoint)
{
ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
log.info("URL: "+request.getRequestURI().toString());
log.info("HTTP_METHOD: "+request.getMethod());
log.info("IP: "+request.getRemoteAddr());
log.info("CLASS_METHOD" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
log.info("ARGS :" + Arrays.toString(joinPoint.getArgs()));
}
//请求发生以后
@AfterReturning(returning = "res", pointcut = "webLog()")
public void doAfterReturning(Object res) throws JsonProcessingException {
//处理完请求,返回内容
log.info("RESPONSE :" + new ObjectMapper().writeValueAsString(res));
}
}
二、开发框架搭建
1.设置返回接口标准类
接口需要返回状态代码code,以及返回成功与否msg,成功时需要携带得数据data:
由于data得类型不确定所
package com.imooc.mall.common;
import com.imooc.mall.Exception.MallExceptionEnum;
public class ApiRestResponse<T> {
private Integer status;
private String msg;
private T data;
private static final int OK_CODE = 1000;
private static final String OK_MSG="success";
/*不返回data时,使用的构造函数*/
ApiRestResponse(Integer status,String msg)
{
this.status = status;
this.msg = msg;
}
ApiRestResponse(Integer status,String msg,T data)
{
this.status = status;
this.msg = msg;
this.data = data;
}
public ApiRestResponse() {
this(OK_CODE, OK_MSG);
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
/**
* 请求成功 data=null
* @return
*/
public static <T> ApiRestResponse<T> success()
{
return new ApiRestResponse<>();
}
/**
* 请求成功
* @param result data数据
* @param <T>
* @return
*/
public static <T> ApiRestResponse<T> success(T result)
{
ApiRestResponse<T> arr = new ApiRestResponse<>();
arr.setData(result);
return arr;
}
/**
* 请求失败
* @param status
* @param msg
* @param <T>
* @return
*/
public static <T> ApiRestResponse<T> fail(Integer status ,String msg)
{
return new ApiRestResponse<>(status,msg);
}
/*与自定义的异常搭配使用*/
public static <T> ApiRestResponse<T> error(MallExceptionEnum ex)
{
return new ApiRestResponse<>(ex.getCode(),ex.getMsg());
}
}
2.自定义异常枚举类
异常枚举类是定义在程序运行过程中需要处理的异常类型
package com.imooc.mall.Exception;
public enum MallExceptionEnum {
NEED_USER_NAME(10001,"用户名不能空"),
NEED_PASSWORD(10002,"密码不能为空"),
PASSWORD_TOO_SHORT(10003,"密码长度不能小于8位"),
NAME_EXIST(10004,"名称已经存在"),
INSERT_FAIL(10005,"用户注册失败"),
LOGIN_FAIL(10007,"用户名或者密码错误"),
NEED_LOGIN(10008,"用户未登录"),
UPDATE_FAILED(10009,"更新失败"),
NEED_ADMIN(10010,"非管理员用户"),
NAME_NOT_NULL(10011,"参数不能为空"),
PARAM_ERROR(10012,"参数不合法"),
DELETE_ERROR(10013,"删除失败"),
PARAM_NOT_EXIST(10014,"缺失参数"),
MKDIR_FAILED(10015,"文件夹创建失败"),
UPLOAD_FAIL(10016,"文件上传失败"),
PRODUCT_NOT_EXISTED(10017,"该商品不可售出"),
NOT_ENOUGH(10018,"商品库存不足"),
CART_SELECTED_EMPTY(10019,"购物车勾选商品为空"),
ORDER_NOT_EXISTED(10020,"订单不存在"),
NOT_YOU(10021,"未授权访问"),
NOT_ENUM(10022,"不存在此代码"),
WRONG_ORDER_STATUS(10023,"当前订单状态不为未支付"),
USERNAME_NOT_EXISTED(10024,"用户名不能更改"),
SYSTEM_ERROR(20001,"系统错误");
/*
code 是API接口返回的code
msg 是API接口返回的msg
*/
Integer code;
String msg;
MallExceptionEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
3. 自定义异常处理类
Service层在进行操作时会产生各种异常,我们需要将异常统一归类,方便全局处理
package com.imooc.mall.Exception;
public class MallException extends Exception{
private Integer code;
private String msg;
public MallException(Integer code,String msg)
{
this.code =code;
this.msg = msg;
}
public MallException(MallExceptionEnum exceptionEnum)
{
this.code =exceptionEnum.getCode();
this.msg = exceptionEnum.getMsg();
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
这里存在两种初始化,实际上用得多的是第二种类型。
4. 全局异常处理类
package com.imooc.mall.Exception;
import com.imooc.mall.Annotation.OperationLogAnnotation;
import com.imooc.mall.common.ApiRestResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.ArrayList;
import java.util.List;
/*ControllerAdvice 全局Controller异常接受*/
@ControllerAdvice
public class GlobalExceptionHandler {
private final Logger log=LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(Exception.class)
@ResponseBody
public ApiRestResponse handleException(Exception e){
log.error("System Exception:",e);
return ApiRestResponse.error(MallExceptionEnum.SYSTEM_ERROR);
}
@ExceptionHandler(MallException.class)
@ResponseBody
public ApiRestResponse handleMallException(MallException e){
log.error("Projection Exception:",e);
return ApiRestResponse.fail(e.getCode(),e.getMsg());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ApiRestResponse handleVaildException(MethodArgumentNotValidException e)
{
log.error("MethodArgumentNotValidException:",e);
return handleBindingResult(e.getBindingResult());
}
private ApiRestResponse handleBindingResult(BindingResult result) {
List<String> list = new ArrayList<>();
if (result.hasErrors()) {//如果BindingResult中,包含错误,就获取其中所有的错误信息;
List<ObjectError> allErrors = result.getAllErrors();
//遍历所有的错误信息;
for (int i = 0; i < allErrors.size(); i++) {
ObjectError objectError = allErrors.get(i);
//提取具体的错误信息;
String message = objectError.getDefaultMessage();
//将错误信息,添加到list集合中
list.add(message);
}
}
if (list.size() == 0) {
return ApiRestResponse.error(MallExceptionEnum.PARAM_ERROR);
}
//根据MethodArgumentNotValidException异常的具体错误信息,构建ApiRestResponse统一返回对象;
return ApiRestResponse.fail(MallExceptionEnum.PARAM_ERROR.getCode(), list.toString());
}
@ExceptionHandler(MissingServletRequestParameterException.class)
@ResponseBody
public ApiRestResponse handleParamException(MissingServletRequestParameterException e)
{
log.error("MissingServletRequestParameterException:",e);
return ApiRestResponse.error(MallExceptionEnum.PARAM_NOT_EXIST);
}
}
@ControllerAdvice注解,用于对Controller层抛出的异常处理
我们这里处理了4种类型的异常
- 系统异常
- 自定义异常
- 参数输入步骤缺,入如参数确实,参数为空
- 参数有特定的范围时,输入不在此范围之类会抛出异常
三、全局校验
1. 全局常量参数
package com.imooc.mall.common;
import com.google.common.collect.Sets;
import com.imooc.mall.Exception.MallException;
import com.imooc.mall.Exception.MallExceptionEnum;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Set;
@Component
public class Constant {
public static final String salt = "hasu9fhdsiofjiosa}{x";
public static final String MALL_USER = "mall_user";
public static String FILE_UPLOAD_DIR;
@Value("${file.upload.dir}")
public void setFileUploadDir(String fileUploadDir){FILE_UPLOAD_DIR = fileUploadDir;}
public interface ProductListOrderBy
{
Set<String> PRICE_ASC_DESC = Sets.newHashSet("price desc","price asc");
}
public enum OrderStatusEnum
{
CANCELED(0, "用户已取消"),
NOT_PAY(10, "未付款"),
PAID(20,"已付款"),
DELIVERED(30,"已发货"),
FINISHED(40,"交易完成");
private int code;
private String value;
OrderStatusEnum(int code, String value) {
this.code = code;
this.value = value;
}
public static String codeOf(int code) throws MallException{
for(OrderStatusEnum ose:values())
{
if(ose.getCode()==code)
{
return ose.getValue();
}
}
throw new MallException(MallExceptionEnum.NOT_YOU);
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
全局参数包括:
- 盐值
- session存储参数
- 文件上传存储位置
- order by 排序类型
- 订单状态枚举
2. 用户身份校验
package com.imooc.mall.Filter;
import com.imooc.mall.common.Constant;
import com.imooc.mall.model.pojo.User;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;
import java.io.PrintWriter;
public class UserFilter implements Filter {
public static User currentuser;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request= (HttpServletRequest)servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
currentuser = (User)request.getSession().getAttribute(Constant.MALL_USER);
if(currentuser==null){
PrintWriter out = new HttpServletResponseWrapper(response).getWriter();
out.write(
"{\n" +
" \"status\": 10008,\n" +
" \"msg\": \"NEED LOGIN\",\n" +
" \"data\": null\n" +
"}"
);
out.flush();
out.close();
return;
}
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
其中Constant类是用来定义常量的,会话管理的方法是利用java原生的session
3. 管理员权限校验
package com.imooc.mall.Filter;
import com.imooc.mall.common.Constant;
import com.imooc.mall.model.pojo.User;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;
import java.io.PrintWriter;
public class AdminFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* 统一身份认证接口
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request= (HttpServletRequest)servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
User currentuser = (User)request.getSession().getAttribute(Constant.MALL_USER);
if(currentuser==null){
PrintWriter out = new HttpServletResponseWrapper(response).getWriter();
out.write(
"{\n" +
" \"status\": 10008,\n" +
" \"msg\": \"NEED LOGIN\",\n" +
" \"data\": null\n" +
"}"
);
out.flush();
out.close();
}
if(currentuser.getRole().equals(2))
{
filterChain.doFilter(servletRequest,servletResponse);
}
else
{
PrintWriter out = new HttpServletResponseWrapper(response).getWriter();
out.write("{\n" +
" \"status\": 10010,\n" +
" \"msg\": \"ADMIN NEED\",\n" +
" \"data\": null\n" +
"}");
out.flush();
out.close();
return;
}
}
@Override
public void destroy() {
}
}
四、全局校验配置
我们在(三)中设置了过滤器,必须在有相应的配置才能让spring知晓
1. 用户校验配置
package com.imooc.mall.Config;
import com.imooc.mall.Filter.UserFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class UserFilterConfig {
@Bean
public UserFilter userFilter()
{
return new UserFilter();
}
@Bean(name="userFilterConf")
public FilterRegistrationBean adminFilterConifg()
{
FilterRegistrationBean frb = new FilterRegistrationBean();
frb.setFilter(userFilter());
frb.addUrlPatterns("/user/*");
frb.addUrlPatterns("/cart/*");
frb.addUrlPatterns("/order/*");
frb.setName("userFilterConf");
return frb;
}
}
2. 管理员校验配置
package com.imooc.mall.Config;
import com.imooc.mall.Filter.AdminFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AdminFilterConfig {
@Bean
public AdminFilter adminFilter()
{
return new AdminFilter();
}
@Bean(name="adminFilterConf")
public FilterRegistrationBean adminFilterConifg()
{
FilterRegistrationBean frb = new FilterRegistrationBean();
frb.setFilter(adminFilter());
frb.addUrlPatterns("/admin/*");
frb.setName("adminFilterConf");
return frb;
}
}
3. 文件存储实际位置与虚拟位置转化
package com.imooc.mall.Config;
import com.imooc.mall.common.Constant;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MallWebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/images/**").addResourceLocations("file:"+ Constant.FILE_UPLOAD_DIR);
}
}
总结