IDEA+连接数据库+Easy Code逆向工程

 

1、在IDEA界面选择选择如下

2、配置数据库驱动

3、配置数据库账户和URL信息

URL说明(只需要修改数据库地址和库名即可):jdbc:mysql://localhost:3306/dolabor?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

4、连接数据库成功,右击选择数据库需要使用的库、表

5、搜索插件EasyCode数据库逆向插件

6、修改EasyCode的插件模板去除表名前缀

7、将需要的模板加上去前缀代码即可(内容如下)

## 去掉t_表前缀
$!init

8、由于当前下载插件带的service模板存在异常故修改备份于此(修改成自己开发习惯)

 注意去表头配置:


##去掉表的t_前缀
$!tableInfo.setName($tool.getClassName($tableInfo.obj.name.replaceFirst("t_","")))

 图片如下:

 

entity.java 模板

##引入宏定义
## 去掉t_表前缀
$!init
$!define

##使用宏定义设置回调(保存位置与文件后缀)
#save("/entity", ".java")

##使用宏定义设置包后缀
#setPackageSuffix("entity")

##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0).name)
#end
import $!{tableInfo.savePackageName}.util.QueryRequest;
##使用全局变量实现默认包导入
$!autoImport
import java.io.Serializable;
import io.swagger.annotations.*;
import lombok.Data;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
 
##使用宏定义实现类注释信息
#tableComment("实体类")
@Data
@Table(name = "$!tableInfo.obj.name")
@ApiModel("$tableInfo.comment")
public class $!{tableInfo.name} extends QueryRequest implements Serializable {
 
    private static final long serialVersionUID = $!tool.serial();
    
#foreach($column in $tableInfo.fullColumn)
    #if(${column.comment})/**
    * ${column.comment}
    */#end
    ##给主键标识和新增返回主键
    #if(${column.name.equals($pk)})
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)#end
    
    @ApiModelProperty("$column.comment")
    private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
    
#end
}

dao.java 模板

## 去掉t_表前缀
$!init
##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Mapper"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/dao/mapper"))

##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}dao.mapper;
 
import $!{tableInfo.savePackageName}.base.TkBaseMapper;
import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};
 
/**
 * $!{tableInfo.comment}($!{tableInfo.name})表数据库访问层
 *
 * @author $!author
 * @since $!time.currTime()
 */
public interface $!{tableName} extends TkBaseMapper<$!{tableInfo.name}> {
 
}

service.java

## 去掉t_表前缀
$!init
##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Service"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/service"))

##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service;
 
import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};
 
/**
 * $!{tableInfo.comment}($!{tableInfo.name})表服务实现类
 *
 * @author $!author
 * @since $!time.currTime()
 */
public interface $!{tableName} {
 
    /**
     * 保存数据
     *
     * @param userId 用户ID
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 是否成功
     */
    int save(Integer userId, $!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));
 
    /**
     * 新增数据
     *
     * @param userId 用户ID
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 是否成功
     */
    int insert(Integer userId, $!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));
 
    /**
     * 通过主键删除数据
     *
     * @param userId 用户ID
     * @param $!pk.name 主键
     * @return 是否成功
     */
    int delete(Integer userId, $!pk.shortType $!pk.name);
 
    /**
     * 修改数据
     *
     * @param userId 用户ID
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 是否成功
     */
    int update(Integer userId, $!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));
 
    /**
     * 通过ID查询单条数据
     *
     * @param $!pk.name 主键
     * @return 实例对象
     */
    $!{tableInfo.name} queryById($!pk.shortType $!pk.name);
 
    /**
     * 查询多条数据
     *
     * @param userId 用户ID
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 查询条数
     * @return 对象列表
     */
    PageWrapper<$!{tableInfo.name}> list(Integer userId, $!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));
}

serviceImpl.java模板

## 去掉t_表前缀
$!init
##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "ServiceImpl"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/service/impl"))

##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

##拿到createBy其它
#if(!$tableInfo.otherColumn.isEmpty())
    #foreach($column in $tableInfo.otherColumn)
        #if($column.name.equals("createBy"))
            #set($createBy = $column.name)
        #end
        #if($column.name.equals("updateBy"))
            #set($updateBy = $column.name)
        #end
        #if($column.name.equals("updateTime"))
            #set($updateTime = $column.name)
        #end
        #if($column.name.equals("flag"))
            #set($flag = $column.name)
        #end
    #end
#end

## 截取对象名的第一个字符串
#set($length1 = $tool.firstLowerCase($!{tableInfo.name}).substring(0, 1))

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service.impl;
 
import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};
import $!{tableInfo.savePackageName}.enums.DataEnum;
import $!{tableInfo.savePackageName}.dao.mapper.$!{tableInfo.name}Mapper;
import $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service;
import org.springframework.stereotype.Service;
import java.util.Date;
 
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import javax.annotation.Resource;
 
/**
 * $!{tableInfo.comment}($!{tableInfo.name})表服务实现类
 *
 * @author $!author
 * @since $!time.currTime()
 */
@Service("$!tool.firstLowerCase($!{tableInfo.name})Service")
public class $!{tableName} implements $!{tableInfo.name}Service {
 
    /**
     * 服务对象
     */
    @Resource
    private $!{tableInfo.name}Mapper $!tool.firstLowerCase($!{tableInfo.name})Mapper;
 
    /**
     * 保存数据
     *
     * @param userId 用户ID
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 是否成功
     */
    @Override
    public int save(Integer userId, $!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {
        if($!{tool.firstLowerCase($!{tableInfo.name})}.get$!{tool.firstUpperCase($!{pk.name})}() == null){
            return insert(userId, $!tool.firstLowerCase($!{tableInfo.name}));
        } else {
            return update(userId,$!tool.firstLowerCase($!{tableInfo.name}));
        }
    }
 
    /**
     * 新增数据
     *
     * @param userId 用户ID
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 是否成功
     */
    @Override
    public int insert(Integer userId, $!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {
        $!{tool.firstLowerCase($!{tableInfo.name})}.set$!{tool.firstUpperCase($!{createBy})}(userId);
        return $!{tool.firstLowerCase($!{tableInfo.name})}Mapper.insertSelective($!tool.firstLowerCase($!{tableInfo.name}));
    }
 
    /**
     * 通过主键删除数据
     *
     * @param userId 用户ID
     * @param $!pk.name 主键
     * @return 是否成功
     */
    @Override
    public int delete(Integer userId, $!pk.shortType $!pk.name) {
		$!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}) = $!{tool.firstLowerCase($!{tableInfo.name})}Mapper.selectByPrimaryKey($!pk.name);
        $!{tool.firstLowerCase($!{tableInfo.name})}.set$!{tool.firstUpperCase($!{updateBy})}(userId);
        $!{tool.firstLowerCase($!{tableInfo.name})}.set$!{tool.firstUpperCase($!{updateTime})}(new Date());
        $!{tool.firstLowerCase($!{tableInfo.name})}.set$!{tool.firstUpperCase($!{flag})}(DataEnum.FLAG_STATUS_INVALID.getCode());
        return $!{tool.firstLowerCase($!{tableInfo.name})}Mapper.updateByPrimaryKeySelective($!tool.firstLowerCase($!{tableInfo.name}));
    }
 
    /**
     * 修改数据
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 是否成功
     */
    @Override
    public int update(Integer userId, $!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})){
		$!{tableInfo.name} $!{length1} = $!{tool.firstLowerCase($!{tableInfo.name})}Mapper.selectByPrimaryKey($!{tool.firstLowerCase($!{tableInfo.name})}.get$!{tool.firstUpperCase($!{pk.name})}());
		// FIXME 待完善
        return $!{tool.firstLowerCase($!{tableInfo.name})}Mapper.updateByPrimaryKeySelective($!{length1});
	}
 
    /**
     * 通过ID查询单条数据
     *
     * @param $!pk.name 主键
     * @return 实例对象
     */
    @Override
    public $!{tableInfo.name} queryById($!pk.shortType $!pk.name){
		return $!{tool.firstLowerCase($!{tableInfo.name})}Mapper.selectByPrimaryKey($!pk.name);
	}
 
    /**
     * 查询多条数据
     *
     * @param userId 用户ID
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 查询条数
     * @return 对象列表
     */
    @Override
    public PageWrapper<$!{tableInfo.name}> list(Integer userId, $!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {
        PageHelper.startPage($!{tool.firstLowerCase($!{tableInfo.name})}.getPageNum(), $!{tool.firstLowerCase($!{tableInfo.name})}.getPageSize());
        $!{tool.firstLowerCase($!{tableInfo.name})}.set$!{tool.firstUpperCase($!{flag})}(DataEnum.FLAG_STATUS_VALID.getCode());
        PageInfo<$!{tableInfo.name}> page = new PageInfo<>($!{tool.firstLowerCase($!{tableInfo.name})}Mapper.select($!{tool.firstLowerCase($!{tableInfo.name})}));
        PageHelper.clearPage();
        return new PageWrapper<>(page);
    }
}

controller.java模板

## 去掉t_表前缀
$!init
##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Controller"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/controller"))
##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}controller;
 
import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};
import $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import javax.annotation.Resource;
import $!{tableInfo.savePackageName}.vo.ResponseHelper;
import $!{tableInfo.savePackageName}.vo.ResponseModel;
 
/**
 * $!{tableInfo.comment}($!{tableInfo.name})表控制层
 *
 * @author $!author
 * @since $!time.currTime()
 */
@Api(tags = "$!{tableInfo.comment}($!{tableInfo.name})") 
@RestController
@RequestMapping("$!tool.firstLowerCase($tableInfo.name)")
public class $!{tableName} {
 
    /**
     * 服务对象
     */
    @Resource
    private $!{tableInfo.name}Service $!tool.firstLowerCase($tableInfo.name)Service;
 
    /**
     * 新增/修改数据
     *
     * @param userId 用户ID
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 是否成功
     */
    @PostMapping("save")
    @ApiOperation(value = "新增/修改", notes = "新增/修改$!{tableInfo.comment}的一条数据")
    @RequiresPermissions(logical = Logical.OR, value = {"$!tool.firstLowerCase($!{tableInfo.name}):insert", "$!tool.firstLowerCase($!{tableInfo.name}):edit"})
    public ResponseModel save(@ApiParam(value = "用户ID", required = false) @UserId String userId, @ApiParam(value = "$!{tableInfo.comment}对象", required = true) @RequestBody @Validated $!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {
            return ResponseHelper.success($!{tool.firstLowerCase($!{tableInfo.name})}Service.save(Integer.valueOf(userId), $!tool.firstLowerCase($!{tableInfo.name})));
    }
 
    /**
     * 通过主键删除数据
     *
     * @param userId 用户ID
     * @param $!pk.name 主键
     * @return 是否成功
     */
    @DeleteMapping("delete/{$!{pk.name}}")
    @ApiOperation(value = "删除单条数据", notes = "删除主键$!{pk.name}的单条数据")
    @RequiresPermissions(logical = Logical.OR, value = {"$!tool.firstLowerCase($!{tableInfo.name}):delete"})
    public ResponseModel delete(@ApiParam(value = "用户ID", required = false) @UserId String userId, @ApiParam(value = "$!{tableInfo.comment}主键$!{pk.name}", required = true) @PathVariable("$!{pk.name}") $!pk.shortType $!pk.name) {
            return ResponseHelper.success($!{tool.firstLowerCase($!{tableInfo.name})}Service.delete(Integer.valueOf(userId), $!pk.name));
    }

    /**
     * 通过ID查询单条数据
     *
     * @param $!{pk.name} 主键
     * @return 实例对象
     */
    @GetMapping("queryById/{$!{pk.name}}")
    @ApiOperation(value = "查询单条数据", notes = "通过$!{pk.name}查询单条数据}")
    public ResponseModel queryById(@ApiParam(value = "$!{tableInfo.comment}主键$!{pk.name}", required = true) @PathVariable("$!{pk.name}") $!pk.shortType $!{pk.name}){
        return ResponseHelper.success($!{tool.firstLowerCase($!{tableInfo.name})}Service.queryById($!{pk.name}));
    }
 
    /**
     * 查询多条数据
     *
     * @param userId 用户ID
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 查询条数
     * @return 对象列表
     */
    @PostMapping("list")
    @ApiOperation(value = "列表", notes = "查询$!{tableInfo.comment}的多条数据")
    public ResponseModel list(@ApiParam(value = "用户ID", required = false) @UserId String userId, @ApiParam(value = "$!{tableInfo.comment}对象", required = true) @RequestBody $!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {
        return ResponseHelper.success($!{tool.firstLowerCase($!{tableInfo.name})}Service.list(Integer.valueOf(userId), $!tool.firstLowerCase($!{tableInfo.name})));
    }
 
}

mapper.xml模板

## 去掉t_表前缀
$!init
##引入mybatis支持
$!mybatisSupport

##设置保存名称与保存位置
$!callback.setFileName($tool.append($!{tableInfo.name}, "Dao.xml"))
$!callback.setSavePath($tool.append($modulePath, "/src/main/resources/mapping"))

##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="$!{tableInfo.savePackageName}.dao.mapper.$!{tableInfo.name}Mapper">

    <resultMap type="$!{tableInfo.savePackageName}.entity.$!{tableInfo.name}" id="$!{tableInfo.name}Map">
#foreach($column in $tableInfo.fullColumn)
        <result property="$!column.name" column="$!column.obj.name" jdbcType="$!column.ext.jdbcType"/>
#end
    </resultMap>

    <!--查询单个-->
    <select id="queryById" resultMap="$!{tableInfo.name}Map">
        select
          #allSqlColumn()

        from $!{tableInfo.obj.parent.name}.$!tableInfo.obj.name
        where $!pk.obj.name = #{$!pk.name}
    </select>

    <!--查询指定行数据-->
    <select id="queryAllByLimit" resultMap="$!{tableInfo.name}Map">
        select
          #allSqlColumn()

        from $!{tableInfo.obj.parent.name}.$!tableInfo.obj.name
        limit #{offset}, #{limit}
    </select>

    <!--通过实体作为筛选条件查询-->
    <select id="queryAll" resultMap="$!{tableInfo.name}Map">
        select
          #allSqlColumn()

        from $!{tableInfo.obj.parent.name}.$!tableInfo.obj.name
        <where>
#foreach($column in $tableInfo.fullColumn)
            <if test="$!column.name != null#if($column.type.equals("java.lang.String")) and $!column.name != ''#end">
                and $!column.obj.name = #{$!column.name}
            </if>
#end
        </where>
    </select>

    <!--新增所有列-->
    <insert id="insert" keyProperty="$!pk.name" useGeneratedKeys="true">
        insert into $!{tableInfo.obj.parent.name}.$!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($velocityHasNext), #end#end)
        values (#foreach($column in $tableInfo.otherColumn)#{$!{column.name}}#if($velocityHasNext), #end#end)
    </insert>

    <!--通过主键修改数据-->
    <update id="update">
        update $!{tableInfo.obj.parent.name}.$!{tableInfo.obj.name}
        <set>
#foreach($column in $tableInfo.otherColumn)
            <if test="$!column.name != null#if($column.type.equals("java.lang.String")) and $!column.name != ''#end">
                $!column.obj.name = #{$!column.name},
            </if>
#end
        </set>
        where $!pk.obj.name = #{$!pk.name}
    </update>

    <!--通过主键删除-->
    <delete id="deleteById">
        delete from $!{tableInfo.obj.parent.name}.$!{tableInfo.obj.name} where $!pk.obj.name = #{$!pk.name}
    </delete>

</mapper>

9、选择对应的表文件右击创建所需的文件

10、在弹出的对话框操作即可

 

Tips:引入jar包 (版本号自己选择)


        <!-- swagger2 s -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!-- swagger-ui e -->

        <!-- knife4j s -->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <version>2.0.3</version>
        </dependency>
        <!-- knife4j e -->

        <!-- TK Mapper s -->
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.1.5</version>
        </dependency>
        <!-- TK Mapper e -->

        <!-- 分页插件 s -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.5</version>
        </dependency>
        <!-- 分页插件 e -->

        <!-- shiro 安全框架  s -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>
        <!-- shiro 安全框架  e -->

        <!-- commons工具包 s -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <!-- commons工具包 e -->

        <!-- jwt 跨域认证  s -->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.8.1</version>
        </dependency>
        <!-- jwt 跨域认证  e -->

 

实体base类:

package com.automatically.create.project.util;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import javax.persistence.Transient;
import java.io.Serializable;
 
/**
 * @author pc
 */
@Data
@ApiModel("base类")
public class QueryRequest implements Serializable {

    @Transient
    private static final long serialVersionUID = -32472298260769753L;
 
    @Transient
    @ApiModelProperty("页码数")
    private int pageSize = 10;
    
    @Transient
    @ApiModelProperty("页码号")
    private int pageNum = 1;
}

封装PageWrapper分页文件:

import com.github.pagehelper.PageInfo;
import lombok.Data;

import java.io.Serializable;
import java.util.List;

/**
 * @author pc
 */
@Data
public class PageWrapper<T> implements Serializable {

    private List<T> list;
    private int total;

    public PageWrapper(PageInfo<T> pageInfo) {
        this.list = pageInfo.getList();
        this.total = (int) pageInfo.getTotal();
    }
}

 

DataEnum:

package com.example.wosen.enums;

import lombok.Getter;

/**
 * @author pc
 */
@Getter
public enum DataEnum {

    FLAG_STATUS_INVALID(1, "数据无效"),
    FLAG_STATUS_VALID(0, "数据有效");

    /**
     * 请求响应码
     */
    private Integer code;

    /**
     * 请求响应说明
     */
    private String desc;

    DataEnum(Integer code, String desc) {
        this.code = code;
        this.desc = desc;
    }
}

 

application启动类加上:

import tk.mybatis.spring.annotation.MapperScan;
@MapperScan("com.***.***.dao.mapper")

TkBaseMapper基类:

package com.automatically.create.project.base;

import tk.mybatis.mapper.common.BaseMapper;
import tk.mybatis.mapper.common.ExampleMapper;
import tk.mybatis.mapper.common.MySqlMapper;

/**
 * TK 泛型
 * @author pc
 * @param <T>
 */
public interface TkBaseMapper<T> extends BaseMapper<T>, ExampleMapper<T>, MySqlMapper<T> {
}

ResponseModel统一返回类:



import com.earn.money.enums.ResultCode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;

/**
 * @author pc
 * 统一返回相应参数实体类
 */
@Data
@ApiModel("统一返回相应参数实体类")
public class ResponseModel<T> implements Serializable {

    private static final long serialVersionUID = -1241360949457314497L;

    @ApiModelProperty("返回实体")
    private T data;

    @ApiModelProperty("响应消息")
    private String message;

    @ApiModelProperty("响应码")
    private Integer code;

    public ResponseModel(T data) {
        this.data = data;
        this.code = ResultCode.SUCCESS.getCode();
        this.message = ResultCode.SUCCESS.getMessage();
    }

    public ResponseModel(Integer code, String message) {
        this.message = message;
        this.code = code;
    }

    public ResponseModel(T data, ResultCode resultCode) {
        this.data = data;
        this.message = resultCode.getMessage();
        this.code = resultCode.getCode();
    }

    public ResponseModel(T data, Integer code, String message) {
        this.data = data;
        this.code = code;
        this.message = message;
    }
}

ResponseHelper统一返回类:



import com.earn.money.enums.ResultCode;

import java.io.Serializable;

/**
 * 统一返回相应参数
 * @author pc
 */
public class ResponseHelper<T> implements Serializable {

    /**
     * 操作成功默认: code + msg
     * @param model
     * @param <T>
     * @return
     */
    public static <T> ResponseModel<T> success(T model) {
        return successWith(model, ResultCode.SUCCESS);
    }

    /**
     * 作成功自定义错误: code + msg
     * @param t
     * @param resultCode
     * @param <T>
     * @return
     */
    public static <T> ResponseModel<T> successWith(T t, ResultCode resultCode) {
        return new ResponseModel<T>(t, resultCode);
    }

    /**
     * 操作失败默认: code + msg
     * @param model
     * @param <T>
     * @return
     */
    public static <T> ResponseModel<T> failed(T model) {
        return failedWith(model, ResultCode.ERROR);
    }

    /**
     * 操作失败自定义错误: code + msg
     * @param t
     * @param resultCode
     * @param <T>
     * @return
     */
    public static <T> ResponseModel<T> failedWith(T t, ResultCode resultCode) {
        return new ResponseModel<>(t, resultCode);
    }

    /**
     * 操作失败自定义错误: code + msg
     * @param message
     * @param <T>
     * @return
     */
    public static <T> ResponseModel<T> failedWith(String message) {
        return new ResponseModel<>(ResultCode.VALIDATE_FAILED.getCode(), message);
    }
}

ResultCode枚举类:


import lombok.Getter;

/**
 * @author BaoBao
 */
@Getter
public enum ResultCode {

    // 请求信息
    SUCCESS(10000, "操作成功"),
    FAILED(10001, "响应失败"),
    VALIDATE_FAILED(10002, "参数校验失败"),

    // 系统信息
    ERROR(50000, "未知错误");

    /**
     * 请求响应码
     */
    private Integer code;

    /**
     * 请求响应说明
     */
    private String message;

    ResultCode(int code, String message){
        this.code = code;
        this.message = message;
    }
}

userId注解:

package com.automatically.create.project.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * userId注解
 * @author pc
 */
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface UserId {
}

webMvc配置:


import com.example.wosen.annotation.support.UserIdHandlerMethodArgumentResolver;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

/**
 * userId注解
 * @author pc
 */
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new UserIdHandlerMethodArgumentResolver());
    }
}

处理程序方法参数解析器:

package com.automatically.create.project.annotation.support;

import com.automatically.create.project.annotation.UserId;
import com.automatically.create.project.shiro.JwtUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
 * userId注解
 * @author pc
 * 接口说明:
 * supportsParameter:用于判定是否需要处理该参数分解,返回true为需要,并会去调用下面的方法resolveArgument。
 * resolveArgument:真正用于处理参数分解的方法,返回的Object就是controller方法上的形参对象。
 */
public class UserIdHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

    /**
     * 获取header中的key
     */
    public static final String LOGIN_TOKEN_KEY = "Authorization";

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {

        Class<?> class1 = methodParameter.getParameterType();
        // class1.isAssignableFrom(Class<?>2) 判定此 Class1 对象所表示的类或接口与指定的 Class<?>2 参数所表示的类或接口是否相同,或是否是其超类或超接口。如果是则返回 true;否则返回 false。
        return methodParameter.hasParameterAnnotation(UserId.class) && class1.isAssignableFrom(String.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) {

        String token = nativeWebRequest.getHeader(LOGIN_TOKEN_KEY);
        if (StringUtils.isBlank(token)) {
            return null;
        }
        if (methodParameter.getParameterType().isAssignableFrom(String.class)) {
            String userId = JwtUtil.getUserId(token);
            return userId;
        }
        return null;
    }
}
JwtUtil认证中心:
package com.automatically.create.project.shiro;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;

/**
 * JWT工具类
 * @author pc
 */
@Slf4j
public class JwtUtil {

    /**
     *  过期毫秒数
     */
    private static final long EXPIRE_TIME = 1 * 24 * 60 * 60 * 1000;

    /**
     * JWT中保存的用户名键
     */
    private static final String USER_ID = "id";

    /**
     * 生成签名
     * @param userId 用户id
     * @param secret 用户的密码
     * @return 加密的token
     */
    public static String sign(String userId, String secret) {
        Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
        Algorithm algorithm = Algorithm.HMAC256(secret);
        // 附带username信息
        return JWT.create()
                .withClaim(USER_ID, userId)
                .withExpiresAt(date)
                .sign(algorithm);
    }

    /**
     * 校验token是否正确
     * @param token  密钥
     * @param userId 用户ID
     * @param secret 用户的密码
     * @return 是否正确
     */
    public static boolean verifyToKen(String token, String userId, String secret) {
        try {
            //根据密码生成JWT效验器
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withClaim(USER_ID, userId)
                    .build();
            //效验TOKEN
            verifier.verify(token);
            return true;
        } catch (Exception e) {
            log.error("token验证失败", e);
            return false;
        }
    }

    /**
     * token验证token
     * @param token
     * @return
     */
    public static boolean verifyToKen(String token) {
        try {
            JWT.decode(token);
            return true;
        } catch (Exception e) {
            log.error("token验证失败", e);
            return false;
        }
    }

    /**
     * 获取token中的用户ID
     *
     * @param token
     * @return
     */
    public static String getUserId(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim(USER_ID).asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }
}

swagger2config配置:

package com.example.wosen.config;

import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import com.google.common.collect.Lists;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.List;


/**
 * @author BaoBao
 */
@Configuration
@EnableSwagger2
@EnableKnife4j
public class Swagger2 {

    /**
     * 多模块配置 是否渲染控制台
     */
    private boolean enable = true;

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("woSen猎头")
                .description("寻找发光的你")
                .termsOfServiceUrl("http://192.168.110.76/")
                .version("1.0")
                .contact("我是你嘉哥哦~")
                .build();
    }

    @Bean(value = "controllerApi")
    public Docket controllerApi() {
        ParameterBuilder pb = new ParameterBuilder();
        List<Parameter> lp = Lists.newArrayList();
        pb.name("Authorization")
                .description("User Authorization")
                .modelRef(new ModelRef("String"))
                .parameterType("header")
                .required(true)
                .build();
        // 根据每个方法名也知道当前方法在设置什么参数
        lp.add(pb.build());
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("controllerApi")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.example.wosen.controller"))
                .build()
                .apiInfo(apiInfo())
                .enable(enable);
    }
}

跨域文件处理:

package com.example.wosen.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
 * CorsConfig TODO(处理跨域)
 * @author pc
 */
@Configuration
public class CorsConfig {
    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        // 1 设置访问源地址
        corsConfiguration.addAllowedOrigin("*");
        // 2 设置访问源请求头
        corsConfiguration.addAllowedHeader("*");
        // 3 设置访问源请求方法
        corsConfiguration.addAllowedMethod("*");
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        //4 对接口配置跨域设置
        source.registerCorsConfiguration("/**", buildConfig());
        return new CorsFilter(source);
    }
}

全局异常处理:



import com.earn.money.enums.ResultCode;
import com.earn.money.vo.ResponseHelper;
import com.earn.money.vo.ResponseModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.ShiroException;
import org.apache.shiro.authc.AuthenticationException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.io.IOException;

/**
 * 针对单个指定异常捕获,并且定义错误的返回体
 *
 * @author BaoBao
 */
@Slf4j
@RestControllerAdvice
public class ExceptionControllerAdvice {

    /**
     * 捕捉shiro的异常
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(ShiroException.class)
    public ResponseModel<String> handleShiRoException(ShiroException e) {
        log.error("handleShiRoException异常错误信息:", e);
        return ResponseHelper.failedWith(e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(AuthenticationException.class)
    public ResponseModel<String> handleAuthenticationException(AuthenticationException e) {
        log.error("handleAuthenticationException异常错误信息:{}", e);
        return ResponseHelper.failedWith(e.getMessage());
    }

    /**
     * 全局API异常处理
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(ApiException.class)
    public ResponseModel<String> APIGlobalExceptionHandler(ApiException e) {
        log.error("APIGlobalExceptionHandler异常错误信息:{}", e);
        return ResponseHelper.failedWith(e.getMessage());
    }

    /**
     * Http消息不可读异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = HttpMessageNotReadableException.class)
    @ResponseBody
    public ResponseModel<String> handleParamJsonException(HttpMessageNotReadableException e) {
        log.error("handleParamJsonException异常错误信息:", e);
        return ResponseHelper.failedWith(e.getMessage());
    }

    /**
     * 全局实体属性验证异常处理
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseModel MethodArgumentNotValidGlobalExceptionHandler(MethodArgumentNotValidException e) {
        log.error("MethodArgumentNotValidGlobalExceptionHandler异常错误信息:", e);
        return ResponseHelper.failedWith(e.getMessage());
    }

    /**
     * 空指针异常处理
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(NullPointerException.class)
    public ResponseModel NullPointerGlobalExceptionHandler(NullPointerException e) {
        log.error("NullPointerException:{}", e);
        StackTraceElement stackTraceElement = e.getStackTrace()[0];
        return ResponseHelper.failedWith("具体文件. " + stackTraceElement.getClassName() + ". 所属行号. " + stackTraceElement.getLineNumber());
    }

    /**
     * jackson取值异常处理
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(IOException.class)
    public ResponseModel IOEGlobalExceptionHandler(IOException e) {
        log.error("IOEGlobalExceptionHandler异常错误信息:{}", e);
        StackTraceElement stackTraceElement = e.getStackTrace()[0];
        return ResponseHelper.failedWith("具体文件. " + stackTraceElement.getClassName() + ". 所属行号. " + stackTraceElement.getLineNumber());
    }

    /**
     * 索引越界异常处理
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(IndexOutOfBoundsException.class)
    public ResponseModel IndexOutOfBoundsGlobalExceptionHandler(IndexOutOfBoundsException e) {
        log.error("IndexOutOfBoundsGlobalExceptionHandler异常错误信息:{}", e);
        StackTraceElement stackTraceElement = e.getStackTrace()[3];
        return ResponseHelper.failedWith("具体文件. " + stackTraceElement.getClassName() + ". 所属行号. " + stackTraceElement.getLineNumber(), ResultCode.INDEX_OUT_OF_BOUNDS);
    }

    /**
     * 全局异常捕捉处理
     */
    @ResponseBody
    @ExceptionHandler(Exception.class)
    public ResponseModel<String> errorHandler(Exception e) {
        log.error("errorHandler异常错误信息:", e);
        return ResponseHelper.failedWith(e.getMessage(), ResultCode.ERROR);
    }
}

全局返回处理:



import com.earn.money.vo.ResponseModel;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * 全局数据响应处理
 * 加上需要扫描的包
 * @author BaoBao
 */
@RestControllerAdvice(basePackages = {"com.earn.money.app.controller", "com.earn.money.admin.controller", "com.earn.money.public.controller"})
public class ResponseControllerAdvice implements ResponseBodyAdvice<Object> {

    /**
     * 重写的这两个方法是用来在controller将数据进行返回前进行增强操作,
     * supports方法要返回为true才会执行beforeBodyWrite方法,
     * 所以如果有些情况不需要进行增强操作可以在supports方法里进行判断。
     * 对返回数据进行真正的操作还是在beforeBodyWrite方法中,
     * 我们可以直接在该方法里包装数据,这样就不需要每个接口都进行数据包装
     * 错误情况可包装,正常返回不用包装
     */

    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        // 如果接口返回的类型本身就是 ResponseModel 那就没有必要进行额外的操作,返回false
        boolean result = methodParameter.getGenericParameterType().equals(ResponseModel.class);
        return !result;
    }

    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {

        // String类型不能直接包装,所以要进行些特别的处理
        if (methodParameter.getGenericParameterType().equals(String.class)) {
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                // 将数据包装在ResultVO里后,再转换为json字符串响应给前端
                return objectMapper.writeValueAsString(new ResponseModel<>(o));
            } catch (JsonProcessingException e) {

                throw new ApiException("返回String类型错误");
            }
        }

        // 将原本的数据包装在ResultVO里
        return new ResponseModel<>(o);
    }
}

API异常处理:



import com.earn.money.enums.ResultCode;
import lombok.Getter;

/**
 * 针对继承的异常封装响应码和响应信息
 * @author BaoBao
 */
@Getter
public class ApiException extends RuntimeException{

    private static final long serialVersionUID = 3455708526465670030L;

    public int code;
    public String msg;

    /**
     * 指定响应码和其它响应信息
     * @param msg
     */
    public ApiException(String msg){

        this(ResultCode.ERROR.getCode(), msg);
    }

    /**
     * 其它响应码和响应信息
     * @param code
     * @param msg
     */
    public ApiException(int code, String msg){

        super(msg);
        this.code = code;
        this.msg = msg;
    }
}

log切面日志




import java.lang.annotation.*;

/**
 * 在Controller方法上加入改注解会自动记录日志
 *
 * @author pc
 */
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {

    /**
     * 描述. 执行
     */
    String description() default "";
}

Log切面注解实现类



/**
 * 日志方面
 *
 * @author pc
 */
@Slf4j
@Aspect
@Component
public class LogAspect {

    @Resource
    private UserLogMapper userLogMapper;

    /**
     * 获取header中的key
     */
    public static final String LOGIN_TOKEN_KEY = "Authorization";

    /**
     * 切入点
     */
    @Pointcut("@annotation(com.rhwlkj.firefly20200330.annotation.Log)")
    public void pointcut() {
    }

    /**
     * 周围
     *
     * @param point
     * @return
     */
    @Around(value = "pointcut()")
    public Object around(ProceedingJoinPoint point) {

        // 定义注解处的方法结果对象
        Object result;
        // 执行
        int executeStatus;
        long beginTime = System.currentTimeMillis();

        try {

            // 执行注解处方法并返回结果
            // 执行成功
            executeStatus = 1;
            result = point.proceed();
        } catch (Throwable throwable) {

            // 将异常信息包装返回
            // 执行失败
            executeStatus = 0;
            System.err.println(throwable.getMessage());
            result = RespResult.error(throwable.getMessage());
        }

        // 计算执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;

        // 保存日志
        saveLog(point, time, result, executeStatus);

        // 返回执行结果
        return result;
    }

    /**
     * 注解处方法执行结果-再保存日志
     *
     * @param joinPoint
     * @param time
     * @param result
     */
    private void saveLog(ProceedingJoinPoint joinPoint, long time, Object result, int executeStatus) {

        // 获取HttpServletRequest请求对象
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        // 从切面织入点处通过反射机制获取织入点处的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 获取切入点所在的方法
        Method method = signature.getMethod();
        // 获取操作
        Log logAnnotation = method.getAnnotation(Log.class);

        UserLog userLog = new UserLog();
        String token = request.getHeader(LOGIN_TOKEN_KEY);
        if (StringUtils.isNotBlank(token)) {

            String userId = JwtUtil.getUserId(token);
            userLog.setUserId(Integer.valueOf(userId));
        }

        // 模块名称
        userLog.setModelName(joinPoint.getTarget().getClass().getName());

        // 请求的方法参数值
        Object[] args = joinPoint.getArgs();
        // 请求的方法参数名称 局部变量表参数名称发现器
        LocalVariableTableParameterNameDiscoverer localVariableTableParameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
        // 请求方式:["request","body"]
        String[] paramNames = localVariableTableParameterNameDiscoverer.getParameterNames(method);

        try{

            String paramNamesStr = new ObjectMapper().writeValueAsString(paramNames);
            String argsStr = new ObjectMapper().writeValueAsString(args);
            // 设置原始请求参数
            userLog.setOriginalParams(paramNamesStr + " - " + argsStr);
        } catch(IOException e){
            log.error(e.getMessage());
        }

        if (args != null && paramNames != null) {
            String params = "";
            for (int i = 0; i < args.length; i++) {

                params += "  " + paramNames[i] + ":" + args[i];
            }
            // 设置处理后的请求参数
            userLog.setParams(params.trim());
        }

        // 操作名称
        userLog.setActionName(signature.getName() + "()");
        // 请求地址
        userLog.setRequestUrl(request.getRequestURL().toString());
        // 接口描述
        userLog.setDescription(logAnnotation.description());
        // 设置IP地址
        userLog.setIp(IpUtil.getIpAddr(request));
        userLog.setExecuteTime((double) time);

        // 请求结果
        try {
            // 请求的结果
            String resultStr = new ObjectMapper().writeValueAsString(result);
            userLog.setResponseResult(resultStr);
        } catch (IOException e) {
            System.err.println(e);
        }
        userLog.setExecuteStatus(executeStatus);

        // 保存系统日志
        userLogMapper.insert(userLog);
    }
}

获取真实IP

package com.know.also.util;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * 获取请求端的IP
 * @author pc
 */
public class IpUtil {

    private static final String UNKNOWN = "unknown";
    private static final String LOCALHOST = "127.0.0.1";
    private static final String SEPARATOR = ",";

    public static String getIpAddr(HttpServletRequest request) {
        String ipAddress;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (LOCALHOST.equals(ipAddress)) {
                    InetAddress inet = null;
                    try {
                        inet = InetAddress.getLocalHost();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                    ipAddress = inet.getHostAddress();
                }
            }
            // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
            // "***.***.***.***".length()
            if (ipAddress != null && ipAddress.length() > 15) {
                if (ipAddress.indexOf(SEPARATOR) > 0) {
                    ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
                }
            }
        } catch (Exception e) {
            ipAddress = "";
        }
        return ipAddress;

    }
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
想要通过 Maven 和 Servlet 实现查询数据库表并将结果显示在网页上,可以按照以下步骤进行操作: 1. 首先,确保已经在项目中配置了 Maven 依赖管理工具。在 pom.xml 文件中添加相应的依赖,包括 Servlet API、数据库驱动程序和其他必要的库。 2. 在项目中创建一个 Servlet 类。在该类的 doGet() 方法中实现数据库查询的逻辑。可以使用 Java 的 JDBC API 来连接数据库,并编写 SQL 查询语句来获取所需的数据。执行查询后,将结果保存在适当的数据结构中。 3. 创建一个 JSP 文件,用于显示查询结果。在 JSP 文件中,可以使用 Java 代码片段和 JSP 标签来获取并显示查询结果。使用 JSTL(JSP 标准标签库)可以更方便地处理数据。根据需要,可以使用 HTML 和 CSS 来美化页面。 4. 在 Servlet 类中的 doGet() 方法中,使用 request.getRequestDispatcher() 方法获取 JSP 文件的请求分派器。然后,将查询结果作为属性(attribute)设置在请求中,并将请求分派到 JSP 页面。 5. 在 JSP 页面中,使用 JSTL 标签和 Java 代码片段来获取查询结果,并将其在网页上显示出来。可以根据需要使用循环、条件和其他功能来处理和展示数据。 6. 运行项目并访问相应的 URL,即可看到从数据库中查询到的数据在网页上的显示。 总结来说,通过 Maven 管理依赖,使用 Servlet 连接数据库并编写SQL查询语句,然后将查询到的结果通过 JSP 页面展示出来,就可以实现在网页上显示数据库表的功能。通过合理利用 Java、HTML、CSS 和 JSTL 等技术,可以实现更灵活、美观的数据展示效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值