java开发中常用功能汇总

图片上传功能
 public ApiRestResponse uploadFile(HttpServletRequest request, @RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            throw new K100Exception(HatuExceptionEnum.UPLOAD_NO_PICK);
        }
        //获取文件名
        String filename = file.getOriginalFilename();
        //获取文件的扩展名
        String extension = filename.substring(filename.lastIndexOf("."));
        //生成新的文件名,使用UUID保证文件名的唯一性
        String newFileName = UUID.randomUUID().toString() + extension;
        //设置文件的保存路径
        String filePath = Constant.FILE_UPLOAD_PATH;
        //创建目标文件对象
        File destFile = new File(filePath + newFileName);
        //检查父目录是否存在,不存在则创建
        if (!destFile.getParentFile().exists()) {
            if (!destFile.getParentFile().mkdirs()) {
                throw new K100Exception(HatuExceptionEnum.MKDIR_FAILED);
            }
        }
        //保存文件
        try {
            file.transferTo(destFile);
        } catch (IOException ex) {
            throw new K100Exception(HatuExceptionEnum.UPLOAD_FAILED);
        }
        try {
            //获取文件路径(ip+端口+文件名),返回给前端
            String url = getHost(new URI(request.getRequestURL()+""))+"/img/"+newFileName;
            return ApiRestResponse.success(url);
        } catch (URISyntaxException e) {
            //返回失败信息
            return ApiRestResponse.error(HatuExceptionEnum.UPLOAD_FAILED);
        }
    }

    /**
     * 获取自定义URI
     */
    private URI getHost(URI uri) {
        URI effectiveUri;
        try {
            effectiveUri = new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), null, null, null);
        } catch (URISyntaxException e) {
            effectiveUri = null;
        }
        return effectiveUri;
    }

配置映射文件,从而使保存到数据库中的路径可以访问


静态资源映射
@Configuration
public class K100WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
       registry.addResourceHandler("/img/**").addResourceLocations("file:" + Constant.FILE_UPLOAD_PATH);
    }

log4j2日志组件

首先在pom.xml中排除自带日志组件,再引入新的log4j2组件,不需要指定版本号

  <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>

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-log4j2</artifactId>
 </dependency>

接着需要对log4j2进行配置

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="fatal">
    <Properties>
        <!--    <Property name="baseDir" value="${sys:user.home}/logs"/>-->
        <Property name="baseDir" value="S:\book\e-commerce\logs"/>
    </Properties>

    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
            <ThresholdFilter level="info" onMatch="ACCEPT"
                             onMismatch="DENY"/>
            <PatternLayoutd
                    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>

统一的相应接口
public class ApiRestResponse<T> {
    private static final int OK_STATUS = 10000;
    private static final String OK_MSG = "success";
    private Integer statusCode;
    private String msg;
    private T data;

    public ApiRestResponse(Integer statusCode, String msg, T data) {
        this.statusCode = statusCode;
        this.msg = msg;
        this.data = data;
    }

    public ApiRestResponse(Integer statusCode, String msg) {
        this.statusCode = statusCode;
        this.msg = msg;
    }

    public ApiRestResponse() {
        this(OK_STATUS, OK_MSG);
    }

    public static <T> ApiRestResponse<T> success() {
        return new ApiRestResponse<>();
    }

    /**
     * 成功带参
     */
    public static <T> ApiRestResponse<T> success(T data) {
        ApiRestResponse<T> response = new ApiRestResponse<>();
        response.setData(data);
        return response;
    }

    /**
     * 处理失败
     */
    public static <T> ApiRestResponse<T> error(Integer errorCode, String msg) {
        return new ApiRestResponse<>(errorCode,msg);
    }

    public static <T> ApiRestResponse<T> error(HatuExceptionEnum exception) {
        return new ApiRestResponse<>(exception.getCode(), exception.getMsg());
    }
    public Integer getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(Integer statusCode) {
        this.statusCode = statusCode;
    }

    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;
    }

    @Override
    public String toString() {
        return "ApiRestResponse{" +
                "statusCode=" + statusCode +
                ", msg='" + msg + '\'' +
                ", data=" + data +
                '}';
    }
}

自定义异常
public class K100Exception extends RuntimeException{
    private final Integer code;
    private final String msg;


    public K100Exception(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public K100Exception(HatuExceptionEnum hatuException) {
        this(hatuException.getCode(),hatuException.getMsg());
    }

    public Integer getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

统一处理异常

统一异常处理,分别打印相关的日志文件

@ControllerAdvice
public class GlobalExceptionHandler {
    private final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Object handleException(Exception e) {
        log.error("Default Exception:", e);
        return ApiRestResponse.error(HatuExceptionEnum.SYSTEM_EXCEPTION);
    }

    @ExceptionHandler(K100Exception.class)
    @ResponseBody
    public Object handleK100Exception(K100Exception e) {
        log.error("K100Exception", e);
        return ApiRestResponse.error(e.getCode(), e.getMsg());
    }
    //参数不合法异常
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ApiRestResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
            log.error("MethodArgumentNotValidException:", e);
            return handleBindResult(e.getBindingResult());
        }

    /**
     * 把异常处理为对外暴露的提示
     */
    private ApiRestResponse handleBindResult(BindingResult result) {
        List<String> list = new ArrayList<>();
        if (result.hasErrors()) {
            for (ObjectError allError : result.getAllErrors()) {
                list.add(allError.getDefaultMessage());
            }
        }
        if (list.size() == 0) {
            return ApiRestResponse.error(HatuExceptionEnum.REQUEST_PARAM_ERROR);
        }
        return ApiRestResponse.error(HatuExceptionEnum.REQUEST_PARAM_ERROR.getCode(), list.toString());
    }
}

Md5加密处理工具类
public class Md5Utils {
    public static String getMD5(String str, Integer salt) throws NoSuchAlgorithmException {
       char[] cArr = str.toCharArray();
        for (char c : cArr) {
            c = (char) (c + salt);
        }
        String s = new String(cArr);
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        return Base64.encodeBase64String(md5.digest(s.getBytes()));
    }
}

参数校验

"@Valid"注解是在Java中使用的一种验证注解,用于标识一个对象需要进行有效性验证。它通常与数据验证框架(如Hibernate Validator)一起使用,以确保数据的合法性和有效性。

"@Valid"注解可以应用于以下场景:

  1. 方法参数验证:

    public void saveUser(@Valid User user) {
        // 保存用户信息
    }
    

    在方法参数上添加"@Valid"注解,表示需要对传入的"user"对象进行验证。

  2. 方法返回值验证:

    public @Valid User getUser() {
        // 获取用户信息
    }
    

    在方法返回值前添加"@Valid"注解,表示返回的"user"对象需要进行验证。

  3. 验证嵌套对象:

    public class Order {
        private String id;
        @Valid
        private List<@Valid Item> items;
        // ...
    }
    public class Item {
        private String id;
        @NotNull
        private String name;
        // ...
    }
    

    在嵌套对象上添加"@Valid"注解,表示需要对嵌套对象进行验证。

处理参数校验后,要对相应的异常进行处理,方便统一处理,在上文的统一异常处理中已经做了相关处理MethodArgumentNotValidException.class


统一校验管理员

设置过滤器对用户进行统一验证,判断是否进行了登录,是否有管理员权限

public class AdminFilter implements Filter {
    @Autowired
    UserService userService;

    @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;
        HttpSession session = request.getSession();
        User currentUser = (User) session.getAttribute(Constant.HATU_MALL_USER);
        if (currentUser == null) {
            PrintWriter out = new HttpServletResponseWrapper(
                    (HttpServletResponse) servletResponse).getWriter();
            out.write("{\n"
                    + "    \"status\": 10007,\n"
                    + "    \"msg\": \"用户未登录\",\n"
                    + "    \"data\": null\n"
                    + "}");
            out.flush();
            out.close();
            return;
        }
        //校验是否是管理员
        boolean adminRole = userService.checkAdminRole(currentUser);
        if (adminRole) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            PrintWriter out = new HttpServletResponseWrapper(
                    (HttpServletResponse) servletResponse).getWriter();
            out.write("{\n"
                    + "    \"status\": 10009,\n"
                    + "    \"msg\": \"当前用户没有管理员权限\",\n"
                    + "    \"data\": null\n"
                    + "}");
            out.flush();
            out.close();
        }
    }

    @Override
    public void destroy() {

    }
}

之后要对过滤器进行相应的配置

@Configuration
public class AdminFilterConfig {
    @Bean
    public AdminFilter adminFilter() {
        return new AdminFilter();
    }

    @Bean(name = "adminFilterConf")
    public FilterRegistrationBean adminFilterConfig() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(adminFilter());
        filterRegistrationBean.addUrlPatterns("/admin/list/*");
        filterRegistrationBean.setName("adminFilterConf");
        return filterRegistrationBean;
    }
}

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值