技术标签: 过滤器 java xss攻击 拦截器 SQL注入 java信息安全
一、SQL注入简介
SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编程时的疏忽,通过SQL语句,实现无帐号登录,甚至篡改数据库。
二、SQL注入攻击的总体思路
1.寻找到SQL注入的位置
2.判断服务器类型和后台数据库类型
3.针对不通的服务器和数据库特点进行SQL注入攻击
三、SQL注入攻击实例
比如在一个登录界面,要求输入用户名和密码:
可以这样输入实现免帐号登录:
用户名: ‘or 1 = 1 –
密 码:
点登陆,如若没有做特殊处理,那么这个非法用户就很得意的登陆进去了.(当然现在的有些语言的数据库API已经处理了这些问题)
这是为什么呢? 下面我们分析一下:
从理论上说,后台认证程序中会有如下的SQL语句:
String sql = "select * from user_table where username=
' "+userName+" ' and password=' "+password+" '";
当输入了上面的用户名和密码,上面的SQL语句变成:
SELECT * FROM user_table WHERE username=
'’or 1 = 1 -- and password='’
分析SQL语句:
条件后面username=”or 1=1 用户名等于 ” 或1=1 那么这个条件一定会成功;
然后后面加两个-,这意味着注释,它将后面的语句注释,让他们不起作用,这样语句永远都能正确执行,用户轻易骗过系统,获取合法身份。
这还是比较温柔的,如果是执行
SELECT * FROM user_table WHERE
username='' ;DROP DATABASE (DB Name) --' and password=''
….其后果可想而知…
四、应对方法
下面我针对JSP,说一下应对方法:
1.(简单又有效的方法)PreparedStatement
采用预编译语句集,它内置了处理SQL注入的能力,只要使用它的setXXX方法传值即可。
使用好处:
(1).代码的可读性和可维护性.
(2).PreparedStatement尽最大可能提高性能.
(3).最重要的一点是极大地提高了安全性.
原理:
sql注入只对sql语句的准备(编译)过程有破坏作用
而PreparedStatement已经准备好了,执行阶段只是把输入串作为数据处理,
而不再对sql语句进行解析,准备,因此也就避免了sql注入问题.
2.使用正则表达式过滤传入的参数
要引入的包:
import java.util.regex.*;
正则表达式:
private String CHECKSQL = “^(.+)\\sand\\s(.+)|(.+)\\sor(.+)\\s$”;
判断是否匹配:
Pattern.matches(CHECKSQL,targerStr);
下面是具体的正则表达式:
检测SQL meta-characters的正则表达式 :
/(\%27)|(\’)|(\-\-)|(\%23)|(#)/ix
修正检测SQL meta-characters的正则表达式 :/((\%3D)|(=))[^\n]*((\%27)|(\’)|(\-\-)|(\%3B)|(:))/i
典型的SQL 注入攻击的正则表达式 :/\w*((\%27)|(\’))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix
检测SQL注入,UNION查询关键字的正则表达式 :/((\%27)|(\’))union/ix(\%27)|(\’)
检测MS SQL Server SQL注入攻击的正则表达式:
/exec(\s|\+)+(s|x)p\w+/ix
等等…..
3.字符串过滤
比较通用的一个方法:
(||之间的参数可以根据自己程序的需要添加)
public static boolean sql_inj(String str){
String inj_str = "'|and|exec|insert|select|delete|update|
count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";
String inj_stra[] = split(inj_str,"|");
for (int i=0 ; i < inj_stra.length ; i++ ){
if (str.indexOf(inj_stra[i])>=0){
return true;
}
}
return false;
}
4.jsp中调用该函数检查是否包函非法字符
防止SQL从URL注入:
sql_inj.java代码:
package sql_inj;
import java.net.*;
import java.io.*;
import java.sql.*;
import java.text.*;
import java.lang.String;
public class sql_inj{
public static boolean sql_inj(String str){
String inj_str = "'|and|exec|insert|select|delete|update|
count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";
//这里的东西还可以自己添加
String[] inj_stra=inj_str.split("\\|");
for (int i=0 ; i < inj_stra.length ; i++ ){
if (str.indexOf(inj_stra[i])>=0){
return true;
}
}
return false;
}
}
5.JSP页面判断代码:
使用javascript在客户端进行不安全字符屏蔽
功能介绍:检查是否含有”‘”,”\\”,”/”
参数说明:要检查的字符串
返回值:0:是1:不是
函数名是
function check(a){
return 1;
fibdn = new Array (”‘” ,”\\”,”/”);
i=fibdn.length;
j=a.length;
for (ii=0; ii<i; ii++)
{ for (jj=0; jj<j; jj++)
{ temp1=a.charAt(jj);
temp2=fibdn[ii];
if (tem’; p1==temp2)
{ return 0; }
}
}
return 1;
}
===================================
总的说来,防范一般的SQL注入只要在代码规范上下点功夫就可以了。
凡涉及到执行的SQL中有变量时,用JDBC(或者其他数据持久层)提供的如:PreparedStatement就可以 ,切记不要用拼接字符串的方法就可以了。
来源: https://www.cnblogs.com/baizhanshi/p/6002898.html
以上说明来源自网络,以下代码来源自公司实际使用的拦截器:
首先是加载类:
import java.util.Enumeration;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
/**
* add by hanchuang 安全漏洞检测
* create on 2018年8月3日
*/
public class Config {
// xss配置文件
private static final String CONFIG_NAME="xss";
// url白名单
private static final String CONFIG_URL_NAME="xssurl";
// 参数名称白名单
private static final String CONFIG_PARAMETER_NAME="parameterWhiteList";
public static boolean INFO = false;
//关闭日志
public static boolean DEBUG = false;
//true拦截
public static boolean MODE = false;
//关闭过滤器
public static boolean OPEN = false;
//sql过滤
public static boolean SQL = false;
//判断json
public static boolean JSON = true;
//是否校验select
public static boolean SELECT = true;
public static String DEFAULT_SQL_KEY = "(or.{1,20}=)+";
public static String DEFAULT_XSS_KEY = "(truncate|char|insert|select|delete|update|declare|drop|javascript|script|iframe|vbscript|frame|img|href|mid|onreadystatechange|alert|atestu|xss|eval|;//|alert\\()+";
public static String[] DEFAULT_XSSS = "truncate|char|insert|select|delete|update|declare|drop|javascript|script|iframe|vbscript|frame|img|href|mid|onreadystatechange|alert|atestu|xss|eval|;//|alert\\(".split("\\|");
public static String SQL_KEY = "";
public static String JSON_KEY = "{";
public static String XSS_KEY = "";
public static String[] XSSS = null;
public static Pattern replacePattern = Pattern.compile("(\\\\[a-zA-Z0-9]{1})|[\\s]|[`~!^*+:\\[\\].?~!@#¥()——+【】‘;:”“’。,、?]", Pattern.CASE_INSENSITIVE);
public static Pattern sqlPattern = null;
public static Pattern specialCharPattern = Pattern.compile("[|&;$%@'\"<>()+,\\n\\r\\\\]", Pattern.CASE_INSENSITIVE);
public static Pattern specialCharPatternByUrl = Pattern.compile("[<>]", Pattern.CASE_INSENSITIVE);
public static Pattern xssPattern = null;
public static Map<String,String> XSS_URL = new ConcurrentHashMap<String, String>(20);
public static Map<String,String> XSS_PARAMETERS = new ConcurrentHashMap<String, String>(20);
public static String RETURN_STRING = "";
private static void loadXss(){
try {
ResourceBundle.clearCache();
ResourceBundle prop = ResourceBundle.getBundle(CONFIG_NAME);
SELECT = "true".equals(prop.getString("select"));
DEBUG = "true".equals(prop.getString("debug"));
OPEN = "true".equals(prop.getString("open"));
MODE = "true".equals(prop.getString("mode"));
SQL = "true".equals(prop.getString("sql"));
JSON = "true".equals(prop.getString("json"));
JSON_KEY = prop.getString("json_key");
if (null == JSON_KEY || "".equals(JSON_KEY)){
JSON_KEY = "{";
}
RETURN_STRING = prop.getString("rtn_str");
if (null == RETURN_STRING || "".equals(RETURN_STRING)){
RETURN_STRING = "{root:{rtnCode:9999,rtnMsg:%s}}";
}
String str = prop.getString("sql_key");
if (str == null || "".equals(str)){
str = "2,10";
}
SQL_KEY = "(or.{"+str+"}=)+";//(or password =)
try {
sqlPattern = Pattern.compile(SQL_KEY, Pattern.CASE_INSENSITIVE);
}
catch(PatternSyntaxException e){
System.out.println("sql pattern syntax error : "+e.getMessage());
sqlPattern = Pattern.compile(DEFAULT_SQL_KEY, Pattern.CASE_INSENSITIVE);//启用不区分大小写的匹配
}
str = prop.getString("xss_key");
if (str == null || "".equals(str)){
str = "truncate|char|insert|select|delete|update|declare|drop|javascript|script|iframe|vbscript|frame|img|href|mid|onreadystatechange|alert|atestu|xss|eval|;//|alert\\(";
}
if(!SELECT){
str = "truncate|char|insert|delete|update|declare|drop|javascript|script|iframe|vbscript|frame|img|href|mid|onreadystatechange|alert|atestu|xss|eval|;//|alert\\(";
}
XSS_KEY = "("+str+")+";
try {
xssPattern = Pattern.compile(XSS_KEY, Pattern.CASE_INSENSITIVE);
XSSS = str.split("\\|");
}
catch(PatternSyntaxException e){
System.out.println("xss pattern syntax error : "+e.getMessage());
xssPattern = Pattern.compile(DEFAULT_XSS_KEY, Pattern.CASE_INSENSITIVE);
XSSS = DEFAULT_XSSS;
}
str = prop.getString("xss_char");
if (!(str == null || "".equals(str))){
specialCharPattern = Pattern.compile("["+str+"]", Pattern.CASE_INSENSITIVE);
}
debug("open="+OPEN+",info="+INFO+",debug="+DEBUG+",mode="+MODE+",sql="+SQL+",sql_key="+SQL_KEY);
debug("xss_key="+XSS_KEY);
}
catch(Exception e){
debug("load xss.properties error! "+e.getMessage());
e.printStackTrace();
}
}
private static void loadUrl(){
try {
ResourceBundle.clearCache();
ResourceBundle prop = ResourceBundle.getBundle(CONFIG_URL_NAME);
Enumeration<String> keys = prop.getKeys();
String key,jspUrl,doUrl,gvUrl;
while (keys.hasMoreElements()) {
key = keys.nextElement();
jspUrl = "/"+key.replaceAll("\\.","/")+".jsp";
XSS_URL.put(jspUrl,"1");
doUrl = "/"+key.replaceAll("\\.","/")+".do";
XSS_URL.put(doUrl,"1");
gvUrl = "/"+key.replaceAll("\\.","/")+".gv";
XSS_URL.put(gvUrl,"1");
}
// 一些特殊请求参数白名单
ResourceBundle.clearCache();
ResourceBundle rsb = ResourceBundle.getBundle(CONFIG_PARAMETER_NAME);
Enumeration<String> eKeys = rsb.getKeys();
String paraKey;
while (eKeys.hasMoreElements()) {
paraKey = keys.nextElement();
XSS_PARAMETERS.put(paraKey,"1");
}
}
catch(Exception e){
debug("load xssurl.properties error! "+e.getMessage());
e.printStackTrace();
}
}
private static void loadParameters(){
try {
// 一些特殊请求参数白名单
ResourceBundle.clearCache();
ResourceBundle rsb = ResourceBundle.getBundle(CONFIG_PARAMETER_NAME);
Enumeration<String> eKeys = rsb.getKeys();
String paraKey;
while (eKeys.hasMoreElements()) {
paraKey = eKeys.nextElement();
XSS_PARAMETERS.put(paraKey,"1");
}
}
catch(Exception e){
debug("load parameterWhiteList.properties error! "+e.getMessage());
e.printStackTrace();
}
}
public static void init(){
loadXss();
loadUrl();
loadParameters();
}
public static void debug(String msg){
if (!DEBUG) return;
System.out.println("xss_msg: "+msg);
}
// public static void main(String[] args){
// String xx = "12345734987492384";
// System.out.println(xx.substring(0,10));
// String xxx = "npage.evt.evt1075.evt1075";
// System.out.println("/"+xxx.replaceAll("\\.","/")+".jsp");
//
// Config.loadUrl();
// Config.loadXss();
//
// }
}
然后是核心源码:说白了就是使用了java的正则处理类
import com.sitech.crmtpd.common.bo.ResBo;
import com.sitech.crmtpd.common.util.StringUtil;
import com.sitech.crmtpd.common.util.web.ResponseUtil;
import net.sf.json.JSONObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.text.ParseException;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author hanchuang on 2018/8/3.
* @version 1.0
* xss过滤器
*/
public class XssSessionFilter implements Filter {
/**
* 日志记录工具
*/
private static final Log LOG = LogFactory.getLog(XssSessionFilter.class);
/**
* filter过滤器配置信息
*/
protected FilterConfig filterConfig = null;
@Override
public void init(FilterConfig servletConfig) throws ServletException {
this.filterConfig = servletConfig;
Config.init();
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain fc)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) srequest;
HttpServletResponse response = (HttpServletResponse) sresponse;
response.setHeader("Set-Cookie", "name=value; HttpOnly"); //向所有会话cookie中添加“HttpOnly”属性。
try {
if (Config.OPEN) {
String currentPage = request.getServletPath().trim();
if (!Config.XSS_URL.containsKey(currentPage)) {
Enumeration pNames = request.getParameterNames();
//检查url串
//例如http://10.95.242.153:11001/npage/login/link_kf.jsp?<javascript>alert('lll');</javascript>
String rs = "";
StringBuffer sb = null;
String queryStr = request.getQueryString();
// System.out.println("XssSessionFilter-----------------queryStr="+queryStr);
if (null != queryStr && !"".equals(queryStr)) {
rs = checkStr(queryStr, true);
// System.out.println("XssSessionFilter-----------------check result rs="+rs);
if (!"".equals(rs)) {
sb = new StringBuffer();
sb.append(rs)
.append("query_string=[")
.append(queryStr)
.append("]");
// System.out.println("XssSessionFilter------[get]页面: " + currentPage + " - 问题参数: " + sb.toString());
if (Config.MODE) {
String msg = "请求失败:含非法字符!" + (Config.DEBUG ? rs : "");
ResBo resBo = new ResBo();
resBo.setSuccess(false);
resBo.setErrMsg(msg);
resBo.setErrCd("9999");
resBo.setErrorType(1);
if(currentPage.endsWith(".do")){
ResponseUtil.printAjaxError(response, resBo);
}else {
ResponseUtil.printAjaxPack(response, resBo);
}
LOG.info("======================url=========="+currentPage);
return;
}
}
}
boolean valueSpeFlag = false;
String keyStr = "";
String valueStr = "";
sb = new StringBuffer();
while (pNames.hasMoreElements()) {
keyStr = pNames.nextElement().toString();
// 白名单参数跳过
if(Config.XSS_PARAMETERS.containsKey(keyStr)){
continue;
}
valueStr = request.getParameter(keyStr);
rs = checkStr(valueStr, false);
if (!"".equals(rs)) {
valueSpeFlag = true;
sb.append(rs);
sb.append(keyStr);
sb.append("=");
sb.append(valueStr);
if (Config.MODE) {
break;
}
}
}
if (valueSpeFlag) {
// System.out.println("XssSessionFilter------[post]页面: " + currentPage + " - 问题参数: " + sb.toString());
if (Config.MODE) {
String msg = "请求失败:含非法字符!" + (Config.DEBUG ? rs : "");
ResBo resBo = new ResBo();
resBo.setSuccess(false);
resBo.setErrMsg(msg);
resBo.setErrCd("9999");
resBo.setErrorType(1);
if(currentPage.endsWith(".do")){
ResponseUtil.printAjaxError(response, resBo);
}else {
ResponseUtil.printAjaxPack(response, resBo);
}
LOG.info("======================url=========="+currentPage);
return;
}
}
}
}
} catch (Throwable e) {
//忽略异常,不影响业务
System.out.println("xss filter error. " + e.getMessage());
e.printStackTrace();
}
fc.doFilter(request, response);
}
public String checkStr(final String str, boolean isUrl) {
String value = "";
String temp_val = "";
try {
temp_val = URLDecoder.decode(str);
value = new String(temp_val.getBytes("GBK"), "UTF-8");
value = value.toLowerCase().replaceAll("\u0000", "");//替换字符串中的\0 字符
} catch (Exception e) {
System.out.println("URLDecoderException:" + value);
value = str;
}
String lowValue = replaceSpecial(value);//去掉特殊字符
if (lowValue == null || lowValue.length() < 3) {
return "";
}
//判断是否为json串,或者是xml串
if (Config.JSON) {
if (lowValue.startsWith(Config.JSON_KEY)) {
return "";
}
if (lowValue.charAt(0) == '<') {
if (lowValue.startsWith("<xml") || lowValue.startsWith("<?xml")) {
return "";
}
} else if (lowValue.charAt(0) == '&') {
if (lowValue.startsWith("<xml") || lowValue.startsWith("<?xml")) {
return "";
}
}
}
Matcher matcher = null;
if (!isUrl) {
if (Config.SQL) {
matcher = Config.sqlPattern.matcher(lowValue);//检查sql关键字
if (matcher.find()) {
return " sql [|or =|] ";
}
}
}
if (isUrl) {//如果是url上面的query string 则只检查<>
matcher = Config.specialCharPatternByUrl.matcher(lowValue);
} else {
matcher = Config.specialCharPattern.matcher(lowValue);//特殊字符过滤
}
//有特殊字符,且有关键字时进行拦截
if (matcher.find()) {
matcher = Config.xssPattern.matcher(lowValue);//过滤关键字
if (matcher.find()) {
String result = "[xssKey] ";
if (Config.DEBUG) {
//如果为debug模式找出违反了哪个关键字
for (String key : Config.XSSS) {
if (lowValue.indexOf(key) >= 0) {
result = result + "[|" + key + "|] ";
System.out.println("=======被拦截请求串特殊字符======="+lowValue);
}
}
}
return result;
}
//拦截特殊字符
//else{
//return "[specialChar] ";
//}
}
// 因为有统一的分页查询的语句,包含特殊的select
//不管是否有特殊字符,都过滤XSS
matcher = Config.xssPattern.matcher(lowValue);//过滤关键字
if (matcher.find()) {
String result = "[xssKey] ";
if (Config.DEBUG){
//如果为debug模式找出违反了哪个关键字
for (String key : Config.XSSS){
if (lowValue.indexOf(key)>=0){
result = result + "[|"+key+"|] ";
System.out.println("=======被拦截请求串xss======="+lowValue);
}
}
}
return result;
}
return "";
}
/**
* 去掉字符串中的特殊字符和空白字符 包括 \\0 等有特殊含义的字符串
*
* @param str
* @return
*/
public static String replaceSpecial(String str) {
String dest = "";
if (str != null) {
Matcher m = Config.replacePattern.matcher(str);
dest = m.replaceAll("");
}
//System.out.println("dest="+dest);
return dest;
}
/**
* @param str
* @return
* @deprecated
*/
@Deprecated
private boolean checkStrOld(String str) {
String regEx = "[|&;$%@'\"\\'\\\"<>()+,\\n\\r\\\\]";
String urlde = str;
try {
urlde = URLDecoder.decode(str);
} catch (Exception e) {
System.out.println("URLDecoderException:" + urlde);
}
Pattern pattern = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(urlde);
return matcher.find();
}
/**
* @return
* @deprecated
*/
@Deprecated
private boolean ifNotCheck(String notCheckUrl, String obj) {
String[] urls = notCheckUrl.split(",");
for (int i = 0; i < urls.length; i++) {
if ((obj != null) && (obj.equals(urls[i]))) {
return true;
}
}
return false;
}
// public static void main(String[] args)
// throws IOException, ParseException {
// XssSessionFilter xss = new XssSessionFilter();
// Config.init();
//
//
// System.out.println("特殊字符 < 测试:"+xss.checkStr("< scr\nipt",true));
// System.out.println("sql语句 update t1 set a=0 :"+xss.checkStr(";update t1 set a=0",true));
// System.out.println("or 测试:"+xss.checkStr("1 or 1121李1=",false));
//
// Matcher matcher = Config.sqlPattern.matcher("xx or =");//检查sql关键字
// System.out.println(matcher.find());
// System.out.println(xss.checkStr("{xx or 11 =", false));
if (matcher.find()){
return SQL_KEY;
}
//
//
// }
}
然后是将拦截的关键字弹窗提醒:
/**
* 把信息通过输出流输出到界面
*
* @param response HttpServletResponse对象-Action中通过HttpServletResponse response =
* ServletActionContext.getResponse()获取
* @param resBo 要输出到界面的对象
* @throws java.io.IOException
*/
public static void printAjaxPack(HttpServletResponse response, ResBo resBo) {
response.setContentType("text/html; charset=" + PAGE_ENCODING);
response.setHeader("Cache-Control", "no-cache");
PrintWriter out;
try {
out = response.getWriter();
out.println(AJAX_PACKET_STR);
// 得到resBo的json字符串
String jsonStr = String.valueOf(JSONObject.fromObject(resBo));
if (LOG.isDebugEnabled()) {
LOG.debug("jsonStr = " + jsonStr);
}
out.println("response.data=eval(" + jsonStr + ")");
out.println(AJAX_PACKET_END);
out.close();
} catch (IOException e) {
LOG.warn("输出信息错误", e);
}
}
/**
* 把错误信息通过输出流弹出错误提示信息框
*
* @param response HttpServletResponse对象
* @param resBo 要输出到界面的对象,resBo.getErrMsg()获取错误信息
* @throws java.io.IOException
*/
public static void printAjaxError(HttpServletResponse response, ResBo resBo) {
response.setContentType("text/html; charset=" + PAGE_ENCODING);
response.setHeader("Cache-Control", "no-cache");
PrintWriter out;
try {
out = response.getWriter();
// out.println(AJAX_PACKET_STR);
if(ResBo.ERROR_TYPE_SYSTEM == resBo.getErrorType()) {
out.print("<script>alertMsg.error('" + StringUtil.htmlEscape(resBo.getErrMsg()) + "');</script>");
} else {
out.print("<script>alertMsg.info('" + StringUtil.htmlEscape(resBo.getErrMsg()) + "');</script>");
}
// out.println(AJAX_PACKET_END);
out.close();
} catch (IOException e) {
LOG.warn("输出信息错误", e);
}
}
4、总体思路就是通过配置加载sql注入的关键词,xss关键词,将过滤器配置到web.xml中过滤所有 *.do *.gv *.java路径的请求,包括
get\post方式,并加载了url白名单(主要过滤前台js中的动态sql dynSQL),参数白名单(主要是分页查询的参数都带有select关键词),拦截器相关配置,配置文件如下:
xss.properties
open=true
debug=true
mode=true
sql=true
sql_key=1,20
select=false
xss_char=;$%@'"&<>()+,\n\r\\\\
xss_key=truncate|char|insert|select|delete|update|declare|drop|javascript|script|iframe|vbscript|frame|img|href|onreadystatechange|alert|atestu|xss|eval|;//|alert\\(|confirm|prompt|<div|<style|<svg
json=true
json_key={
rtn_str={root:{rtnCode:9999,rtnMsg:%s}}
xssurl.properties
##xssurl白名单##
##普通jsp请求 npage/evt/evt1075/evt1075.jsp
#npage.evt.evt1075.evt1075
##分页查询公共url /npage/common/page/queryList.do
#npage.common.page.queryList
npage.common.dyn.queryDynSql
npage.obim.staff.loginmng.login
npage.evt.q100.Q100Controller-initQ100Main
parameterWhiteList.properties
##参数名称白名单
countStatmentId
listStatmentId
文章浏览阅读5.9k次,点赞6次,收藏20次。Js实现图片点击切换与轮播图片点击切换<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title></title> <script type="text/ja..._点击图片进行轮播图切换
文章浏览阅读10w+次,点赞245次,收藏1.5k次。在开始安装前,如果你的电脑装过tensorflow,请先把他们卸载干净,包括依赖的包(tensorflow-estimator、tensorboard、tensorflow、keras-applications、keras-preprocessing),不然后续安装了tensorflow-gpu可能会出现找不到cuda的问题。cuda、cudnn。..._tensorflow gpu版本安装
文章浏览阅读5.4k次。在VCS菜单中有个开关,叫Enabled Version Control Integration,在打开的窗口的选项中选择Subversion即可。2.勾选command line client tools项,选择第一个(默认是最后一个)4.安装完成后,就能在我们的bin目录下找到svn.exe了。安装后会在安装目录下出现svn.exe字样有用!3.选择完成后,我们直接install即可。最后重启一下idea上就可以用svn了。_idea svn插件
文章浏览阅读857次,点赞13次,收藏5次。从下面结果看到除了代码段,数据段和BSS段以外,还有.rodata(只读数据段), .comment(注释信息段),.note.GNU-stack(堆栈提示段)。比如.text段的偏移位置是0x40. 代表ELF的header占据的空间为0x00-0x40。另外GCC还提供了自定义段,比如你可能希望变量或者某些部分代码能够放到你指定的段中去实现特定的功能,比如满足硬件内存和I/O的地址布局。hex代表的是三个段的总长度。.shstrtab : 是各个段的名称表,实际上是由各个段的名字组成的一个字符串数组。_elf文件运行
文章浏览阅读2.8k次。虚拟机,添加新的硬盘进行分区,格式化,挂载的操作_centos 永久挂载
文章浏览阅读504次。2、只要建立索引就能显著提高查询速度 事实上,我们可以发现上面的例子中,第2、3条语句完全相同,且建立索引的字段也相同;不同的仅是前者在fariqi字段上建立的是非聚合索引,后者在此字段上建立的是聚合索引,但查询速度却有着天壤之别。所以,并非是在任何字段上简单地建立索引就能提高查询速度。 从建表的语句中,我们可以看到这个有着1000万数据的表中fariqi字段有5003个不同记录。在此..._索引对查询效率非常有用,在建表时就应该建好且建完整
文章浏览阅读282次。原标题:2018全国计算机等级考试调整,一、二级都增加了考试科目全国计算机等级考试将于9月15-17日举行。在备考的最后冲刺阶段,小编为大家整理了今年新公布的全国计算机等级考试调整方案,希望对备考的小伙伴有所帮助,快随小编往下看吧!从2018年3月开始,全国计算机等级考试实施2018版考试大纲,并按新体系开考各个考试级别。具体调整内容如下:一、考试级别及科目1.一级新增“网络安全素质教育”科目(代..._计算机二级增报科目什么意思
文章浏览阅读240次。conan简单使用。_apt install conan
文章浏览阅读765次,点赞25次,收藏23次。博主介绍:CSDN特邀作者、985计算机专业毕业、某互联网大厂高级全栈开发程序员、码云/掘金/华为云/阿里云/InfoQ/StackOverflow/github等平台优质作者、专注于Java、小程序、前端、python等技术领域和毕业项目实战,以及程序定制化开发、全栈讲解、就业辅导、面试辅导、简历修改。精彩专栏 推荐订阅2023-2024年最值得选的微信小程序毕业设计选题大全:100个热门选题推荐2023-2024年最值得选的Java毕业设计选题大全:500个热门选题推荐。
文章浏览阅读1.3w次。金山软件办公套件的最新更新 WPS 2016 for Linux,日前发布了几项新功能,性能改进和各种修复。为什么选择WPS办公套件?WPS Office由三个主要组件组成:WPS 文字,WPS 演示和WPS 表格。它看起来非常类似于Microsoft Office! 与Microsoft Office提供的文档格式(包括PPT,DOC,DOCX,XLS和XLSX)完全兼容性。WPS的个人版是供个..._wps office 2016 for linux
文章浏览阅读8k次,点赞8次,收藏95次。用自己数据实现偏最小二乘回归。用Hitters数据集做演示如何使用自己的数据实现偏最小二乘回归。 此数据集有322个运动员的20个变量的数据, 其中的变量Salary(工资)是我们关心的。数据下载百度网盘链接:https://pan.baidu.com/s/13pb7VN_kTzV0hUEsg-1S1A提取码:3333import pandas as pdimport numpy as npfrom sklearn.cross_decomposition import PLSRegression_python 偏最小二乘回归
文章浏览阅读368次,点赞7次,收藏8次。记住常用的基本数据类型int,double熟悉位数: byte8位,int 32位等等记住特性: long需要加L,flaot需要加F,char必须是单引号且只有一个2.1类型转换数据类型转换, 即 它们之间可以变换.2.1.1默认转换按照数据的表示范围, 小范围向大范围转换,可以默认进行// 类型转换默认进行(小转大)long b = a;2.1.2强制转换通过强制转换,可以将数据转换过去,但是有可能丢失精度口诀: 小转大默认进行,大转小强制进行3.1字符串。