JavaWeb三大组件之Filter
JavaWeb三大组件之Filter
为什么80%的码农都做不了架构师?>>>
过滤器概述
1 什么是过滤器
过滤器JavaWeb三大组件之一,它与Servlet很相似!不它过滤器是用来拦截请求的,而不是处理请求的。当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继承执行用户请求的Servlet;如果Filter不“放行”,那么就不会执行用户请求的Servlet。
Filter来决定是否调用Servlet!当执行完成Servlet的代码后,还会执行Filter后面的代码。
2 过滤器之hello world
实现Filter接口。
public class HelloFilter implements Filter {
public void init (FilterConfig filterConfig) throws ServletException {}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("Hello Filter");
}
public void destroy () {}
}
在web.xml文件中部署Filter:
helloFilter
cn.test.filter.HelloFilter
helloFilter
/index.jsp
当用户访问index.jsp页面时,会执行HelloFilter的doFilter()方法!在我们的示例中,index.jsp页面是不会被执行的,如果想执行index.jsp页面,那么我们需要放行!
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//filter开始
chain.doFilter(request, response);
}
过滤器详细
1 过滤器的生命周期
init(FilterConfig) :在服务器启动时会创建Filter实例,并且每个类型的Filter只创建一个实例,从此不再创建!在创建完Filter实例后,会马上调用init()方法完成初始化工作,这个方法只会被执行一次;
doFilter(ServletRequest req,ServletResponse res,FilterChain chain) :这个方法会在用户每次访问“目标资源(pattern>index.jsp)”时执行,如果需要“放行”,那么需要调用FilterChain的doFilter(ServletRequest,ServletResponse) 方法,如果不调用FilterChain的doFilter()方法,那么目标资源将无法执行;
destroy() :服务器会在创建Filter对象之后,把Filter放到缓存中一直使用,通常不会销毁它。一般会在服务器关闭时销毁Filter对象,在销毁Filter对象之前,服务器会调用Filter对象的destory()方法。
2 FilterConfig
你已经看到了吧,Filter接口中的init()方法的参数类型为FilterConfig类型。它的功能与ServletConfig相似,与web.xml文件中的配置信息对应。下面是FilterConfig的功能介绍:
ServletContext getServletContext() :获取ServletContext的方法;
String getFilterName() :获取Filter的配置名称;与元素对应;
String getInitParameter(String name) :获取Filter的初始化配置,与元素对应;
Enumeration getInitParameterNames() :获取所有初始化参数的名称。
3 FilterChain
doFilter()方法的参数中有一个类型为FilterChain的参数,它只有一个方法:doFilter(ServletRequest,ServletResponse) 。
前面我们说doFilter()方法的放行,让请求流访问目标资源!但这么说不严密,其实调用该方法的意思是,“我(当前Filter)”放行了,但不代表其他人(其他过滤器)也放行。
也就是说,一个目标资源上,可能部署了多个过滤器,调用FilterChain类的doFilter()方法表示的是执行下一个过滤器的doFilter()方法,或者是执行目标资源!
如果当前过滤器是最后一个过滤器,那么调用chain.doFilter()方法表示执行目标资源,而不是最后一个过滤器,那么chain.doFilter()表示执行下一个过滤器的doFilter()方法。
4 多个过滤器执行顺序
一个目标资源可以指定多个过滤器,过滤器的执行顺序是在web.xml文件中的部署顺序:
myFilter1
cn.itcast.filter.MyFilter1
myFilter1
/index.jsp
myFilter2
cn.itcast.filter.MyFilter2
myFilter2
/index.jsp
public class MyFilter1 extends HttpFilter {
public void doFilter(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out .println("filter1 start...");
chain.doFilter(request, response);//放行,执行MyFilter2的doFilter()方法
System.out .println("filter1 end...");
}
}
public class MyFilter2 extends HttpFilter {
public void doFilter(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out .println("filter2 start...");
chain.doFilter(request, response);//放行,执行目标资源
System.out .println("filter2 end...");
}
}
This is my JSP page.
index.jsp <%System.out.println("index.jsp"); %>
当有用户访问index.jsp页面时,输出结果如下:
filter1 start...
filter2 start...
index.jsp
filter2 end...
filter1 end...
5 四种拦截方式
我们来做个测试,写一个过滤器,指定过滤的资源为b.jsp,然后我们在浏览器中直接访问b.jsp,你会发现过滤器执行了!
但是,当我们在a.jsp中request.getRequestDispathcer(“/b.jsp”).forward(request,response)时,就不会再执行过滤器了!也就是说,默认情况下,只能直接访问目标资源才会执行过滤器,而forward执行目标资源,不会执行过滤器!
public class MyFilter extends HttpFilter {
public void doFilter(HttpServletRequest request,
HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out .println("myfilter...");
chain.doFilter(request, response);
}
}
myfilter
cn.itcast.filter.MyFilter
myfilter
/b.jsp
b.jsp
a.jsp <%
request.getRequestDispatcher("/b.jsp").forward(request, response);
%>
http://localhost:8080/filtertest/b.jsp -->直接访问b.jsp时,会执行过滤器内容;
http://localhost:8080/filtertest/a.jsp --> 访问a.jsp,但a.jsp会forward到b.jsp,这时就不会执行过滤器!
其实过滤器有四种拦截方式!分别是:REQUEST 、FORWARD 、INCLUDE 、ERROR 。
REQUEST:直接访问目标资源时执行过滤器。包括:在地址栏中直接访问、表单提交、超链接、重定向,只要在地址栏中可以看到目标资源的路径,就是REQUEST;
FORWARD:转发访问执行过滤器。包括RequestDispatcher#forward()方法、标签都是转发访问;
INCLUDE:包含访问执行过滤器。包括RequestDispatcher#include()方法、标签都是包含访问;
ERROR:当目标资源在web.xml中配置为中时,并且真的出现了异常,转发到目标资源时,会执行过滤器。
可以在中添加0~n个子元素,来说明当前访问的拦截方式。
myfilter
/b.jsp
REQUEST
FORWARD
myfilter
/b.jsp
myfilter
/b.jsp
FORWARD
其实最为常用的就是REQUEST和FORWARD两种拦截方式,而INCLUDE和ERROR都比较少用!其中INCLUDE比较好理解,我们这里不再给出代码,学员可以通过FORWARD方式修改,来自己测试。而ERROR方式不易理解,下面给出ERROR拦截方式的例子:
myfilter
/b.jsp
ERROR
500
/b.jsp
a.jsp <%
if (true )
throw new RuntimeException("嘻嘻~");
%>
6 过滤器的应用场景
过滤器的应用场景:
l 执行目标资源之前做预处理 工作,例如设置编码,这种试通常都会放行 ,只是在目标资源执行之前做一些准备工作;
l 通过条件判断是否放行,例如校验当前用户是否已经登录,或者用户IP是否已经被禁用;
l 在目标资源执行后,做一些后续的特殊处理工作,例如把目标资源输出的数据进行处理[c17] ;
7 设置目标资源
在web.xml文件中部署Filter时,可以通过“*”来执行目标资源:
这一特性与Servlet完全相同!通过这一特性,我们可以在用户访问敏感资源时,执行过滤器,例如:/admin/*,可以把所有管理员才能访问的资源放到/admin路径下,这时可以通过过滤器来校验用户身份。
还可以为指定目标资源为某个Servlet,例如:
myservlet
cn.itcast.servlet.MyServlet
myservlet
/abc
myfilter
cn.itcast.filter.MyFilter
myfilter
myservlet [崔19]
当用户访问http://localhost:8080/filtertest/abc时,会执行名字为myservlet的Servlet,这时会执行过滤器。
8 Filter小结
Filter的三个方法:
l void init(FilterConfig):在Tomcat启动时被调用;
l void destroy():在Tomcat关闭时被调用;
l void doFilter(ServletRequest,ServletResponse,FilterChain):每次有请求时都调用该方法;
FilterConfig类:与ServletConfig相似,用来获取Filter的初始化参数
l ServletContext getServletContext():获取ServletContext的方法;
l String getFilterName():获取Filter的配置名称;
l String getInitParameter(String name):获取Filter的初始化配置,与元素对应;
l Enumeration getInitParameterNames():获取所有初始化参数的名称。
FilterChain类:
l void doFilter(ServletRequest,ServletResponse):放行!表示执行下一个过滤器,或者执行目标资源。可以在调用FilterChain的doFilter()方法的前后添加语句,在FilterChain的doFilter()方法之前的语句会在目标资源执行之前执行,在FilterChain的doFilter()方法之后的语句会在目标资源执行之后执行。
四各拦截方式:REQUEST、FORWARD、INCLUDE、ERROR,默认是REQUEST方式。
l REQUEST:拦截直接请求方式;
l FORWARD:拦截请求转发方式;
l INCLUDE:拦截请求包含方式;
l ERROR:拦截错误转发方式。
过滤器应用案例
分ip统计网站的访问次数
ip
count
192.168.1.111
2
192.168.1.112
59
统计工作需要在所有资源之前都执行,那么就可以放到Filter中了。
我们这个过滤器不打算做拦截操作!因为我们只是用来做统计的。
用什么东西来装载统计的数据。Map
整个网站只需要一个Map即可!
Map什么时候创建(使用ServletContextListener,在服务器启动时完成创建,并只在到ServletContext中),Map保存到哪里!(Map保存到ServletContext中!!!)
Ø Map需要在Filter中用来保存数据
Ø Map需要在页面使用,打印Map中的数据
1 说明
网站统计每个IP地址访问本网站的次数。
2 分析
因为一个网站可能有多个页面,无论哪个页面被访问,都要统计访问次数,所以使用过滤器最为方便。
因为需要分IP统计,所以可以在过滤器中创建一个Map,使用IP为key,访问次数为value。当有用户访问时,获取请求的IP,如果IP在Map中存在,说明以前访问过,那么在访问次数上加1,即可;IP在Map中不存在,那么设置次数为1。
把这个Map存放到ServletContext中!
3 代码
index.jsp
分IP统计访问次数
"center" width="50%" border="1" >
IP地址
次数
"entry">
${entry.key }
${entry.value }
[崔20]
IPFilter
public class IPFilter implements Filter {
private ServletContext context;
public void init(FilterConfig fConfig) throws ServletException {
context = fConfig.getServletContext();[崔21]
Map ipCountMap = Collections
.synchronizedMap (new LinkedHashMap());
[崔22] context.setAttribute("ipCountMap", ipCountMap);
}
@SuppressWarnings("unchecked")
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
String ip = req.getRemoteAddr();[崔23]
Map ipCountMap = (Map) context
.getAttribute("ipCountMap");
[崔24]
Integer count = ipCountMap.get(ip);[崔25]
if (count == null ) {
count = 1;
[崔26] } else {
count += 1;[崔27]
}
ipCountMap.put(ip, count);[崔28]
context.setAttribute("ipCountMap", ipCountMap);[崔29]
chain.doFilter(request, response);[崔30]
}
public void destroy() {}
}
IPFilter
IPFilter
cn.itcast.filter.ip.IPFilter
IPFilter
/*
粗粒度权限控制(拦截是否登录、拦截用户名admin权限)
RBAC à 基于角色的权限控制
l tb_user
l tb_role
l tb_userrole
l tb_menu(增、删、改、查)
l tb_rolemenu
1 说明
我们给出三个页面:index.jsp、user.jsp、admin.jsp。
l index.jsp:谁都可以访问,没有限制;
l user.jsp:只有登录用户才能访问;
l admin.jsp:只有管理员才能访问。
2 分析
设计User类:username、password、grade,其中grade表示用户等级,1表示普通用户,2表示管理员用户。
当用户登录成功后,把user保存到session中。
创建LoginFilter,它有两种过滤方式:
l 如果访问的是user.jsp,查看session中是否存在user;
l 如果访问的是admin.jsp,查看session中是否存在user,并且user的grade等于2。
3 代码
User.java
public class User {
private String username;
private String password;
private int grade[崔31] ;
…
}
为了方便,这里就不使用数据库了,所以我们需要在UserService中创建一个Map,用来保存所有用户。Map中的key中用户名,value为User对象。
UserService.java
public class UserService {
private static Map users [崔32] = new HashMap();
static {
users .put("zhangSan", new User("zhangSan", "123", 1));
users .put("liSi", new User("liSi", "123", 2));
[崔33] }
public User login[崔34] (String username, String password) {
User user = users .get(username);[崔35]
if (user == null ) return null ;[崔36]
return user.getPassword().equals(password) ? user : null ;[崔37]
}
}
login.jsp
index.jsp
/user/user.jsp
/admin/admin.jsp
LoginServlet
public class LoginServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
[崔39] UserService userService = new UserService();
User user = userService.login(username, password);[崔40]
if (user == null [崔41] ) {
request.setAttribute("msg", "用户名或密码错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
[崔42] } else {
request.getSession().setAttribute("user", user);
request.getRequestDispatcher("/index.jsp").forward(request, response);
[崔43] }
}
}
LoginUserFilter.java
LoginUserFilter
LoginUserFilter
cn.itcast.filter.LoginUserFilter
LoginUserFilter
/user/*[崔44]
public class LoginUserFilter implements Filter {
public void destroy() {}
public void init(FilterConfig fConfig) throws ServletException {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
response.setContentType("text/html;charset=utf-8");
HttpServletRequest req = (HttpServletRequest) request;
User user = (User) req.getSession().getAttribute("user");[崔45]
if (user == null )[崔46] {
response.getWriter().print("您还没有登录");[崔47]
return ;[崔48]
}
chain.doFilter(request, response);[崔49]
}
}
LoginAdminFilter.java
LoginAdminFilter
LoginAdminFilter
cn.itcast.filter.LoginAdminFilter
LoginAdminFilter
/admin/*[崔50]
public class LoginAdminFilter implements Filter {
public void destroy() {}
public void init(FilterConfig fConfig) throws ServletException {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
response.setContentType("text/html;charset=utf-8");
HttpServletRequest req = (HttpServletRequest) request;
User user = (User) req.getSession().getAttribute("user");[崔51]
if (user == null ) {
response.getWriter().print("您还没有登录!");
return ;
}[崔52]
if (user.getGrade() < 2) {
response.getWriter().print("您的等级不够!");
return ;
}[崔53]
chain.doFilter(request, response);[崔54]
}
}
禁用资源缓存
浏览器只是要缓存页面,这对我们在开发时测试很不方便,所以我们可以过滤所有资源,然后添加去除所有缓存!
public class NoCacheFilter extends HttpFilter {
public void doFilter(HttpServletRequest request,
HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
response.setHeader("cache-control", "no-cache");
response.setHeader("pragma", "no-cache");
response.setHeader("expires", "0");
chain.doFilter(request, response);
}
}
但是要注意,有的浏览器可能不会理会你的设置,还是会缓存的!这时就要在页面中使用时间戳来处理了。
解决全站字符乱码(POST和GET中文编码问题)
servlet:
l POST:request.setCharacterEncoding(“utf-8”);
l GET:
Ø String username = request.getParameter(“username”);
Ø username = new String(username.getBytes(“ISO-8859-1”), “utf-8”);
1 说明
乱码问题:
l 获取请求参数中的乱码问题;
Ø POST请求:request.setCharacterEncoding(“utf-8”);
Ø GET请求:new String(request.getParameter(“xxx”).getBytes(“iso-8859-1”), “utf-8”);
l 响应的乱码问题:response.setContextType(“text/html;charset=utf-8”)。
基本上在每个Servlet中都要处理乱码问题,所以应该把这个工作放到过滤器中来完成。
2 分析
其实全站乱码问题的难点就是处理GET请求参数的问题。
如果只是处理POST请求的编码问题,以及响应编码问题,那么这个过滤器就太!太!太简单的。
public class EncodingFilter extends HttpFilter {
public void doFilter(HttpServletRequest request,
HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
String charset = this .getInitParameter("charset");[崔55]
if (charset == null || charset.isEmpty()) {
charset = "UTF-8";
}
[崔56] request.setCharacterEncoding(charset);[崔57]
response.setContentType("text/html;charset=" + charset);[崔58]
chain.doFilter(request, response);
}
}
如果是POST请求,当执行目标Servlet时,Servlet中调用request.getParameter()方法时,就会根据request.setCharacterEncoding()设置的编码来转码!这说明在过滤器中调用request.setCharacterEncoding()方法会影响在目标Servlet中的request.getParameter()方法的行为!
但是如果是GET请求,我们又如何能影响request.getParameter()方法的行为呢?这是不好做到的!我们不可能先调用request.getParameter()方法获取参数,然后手动转码后,再施加在到request中!因为request只有getParameter(),而没有setParameter()方法。
处理GET请求参数编码问题,需要在Filter中放行时,把request对象给“调包”了,也就是让目标Servlet使用我们“调包”之后的request对象。这说明我们需要保证“调包”之后的request对象中所有方法都要与“调包”之前一样可以使用,并且getParameter()方法还要有能力返回转码之后的参数。
这可能让你想起了“继承”,但是这里不能用继承,而是“装饰者模式(Decorator Pattern)”!
下面是三种对a对象进行增强的手段:
l 继承:AA类继承a对象的类型:A类,然后重写fun1()方法,其中重写的fun1()方法就是被增强的方法。但是,继承必须要知道a对象的真实类型,然后才能去继承。如果我们不知道a对象的确切类型,而只知道a对象是IA接口的实现类对象,那么就无法使用继承来增强a对象了;
l 装饰者模式:AA类去实现a对象相同的接口:IA接口,还需要给AA类传递a对象,然后在AA类中所有的方法实现都是通过代理a对象的相同方法完成的,只有fun1()方法在代理a对象相同方法的前后添加了一些内容,这就是对fun1()方法进行了增强;
l 动态代理:动态代理与装饰者模式比较相似,而且是通过反射来完成的。动态代理会在最后一天的基础加强中讲解,这里就不再废话了。
对request对象进行增强的条件,刚好符合装饰者模式的特点!因为我们不知道request对象的具体类型,但我们知道request是HttpServletRequest接口的实现类。这说明我们写一个类EncodingRequest,去实现HttpServletRequest接口,然后再把原来的request传递给EncodingRequest类!在EncodingRequest中对HttpServletRequest接口中的所有方法的实现都是通过代理原来的request对象来完成的,只有对getParameter()方法添加了增强代码!
JavaEE已经给我们提供了一个HttpServletRequestWrapper类,它就是HttpServletRequest的包装类,但它做任何的增强!你可能会说,写一个装饰类,但不做增强,其目的是什么呢?使用这个装饰类的对象,和使用原有的request有什么分别呢?
HttpServletRequestWrapper类虽然是HttpServletRequest的装饰类,但它不是用来直接使用的,而是用来让我们去继承的!当我们想写一个装饰类时,还要对所有不需要增强的方法做一次实现是很心烦的事情,但如果你去继承HttpServletRequestWrapper类,那么就只需要重写需要增强的方法即可了。
3 代码
EncodingRequest
public class EncodingRequest extends HttpServletRequestWrapper [崔59] {
private String charset;
public EncodingRequest[崔60] (HttpServletRequest request, String charset) {
super (request);
this .charset = charset;
}
public String getParameter[崔61] (String name) {
HttpServletRequest request [崔62] = (HttpServletRequest) getRequest();
String method = request.getMethod()[崔63] ;
if (method.equalsIgnoreCase("post[崔64] ")) {
try {
request.setCharacterEncoding(charset);[崔65]
} catch (UnsupportedEncodingException e) {}
} else if (method.equalsIgnoreCase("get[崔66] ")) {
String value = request.getParameter(name);[崔67]
try {
value = new String(name.getBytes("ISO-8859-1"), charset);[崔68]
} catch (UnsupportedEncodingException e) {
}
return value[崔69] ;
}
return request.getParameter(name);
}
}
EncodingFilter
public class EncodingFilter extends HttpFilter {
public void doFilter(HttpServletRequest request,
HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
String charset = this .getInitParameter("charset");[崔70]
if (charset == null || charset.isEmpty()) {
charset = "UTF-8";
}[崔71]
response.setCharacterEncoding(charset);
response.setContentType("text/html;charset=" + charset);
EncodingRequest res = new EncodingRequest(request, charset);[崔72]
chain.doFilter(res, response);[崔73]
}
}
web.xml
EncodingFilter
cn.itcast.filter.EncodingFilter
charset
UTF-8
EncodingFilter
/*
页面静态化
1 说明
你到“当当”搜索最多的是什么分类,没错,就是Java分类!你猜猜,你去搜索Java分类时,“当当”会不会去查询数据库呢?当然会了,不查询数据库怎么获取Java分类下的图书呢!其实每天都有很多人去搜索“Java分类”的图书,每次都去访问数据库,这会有性能上的缺失!如果是在访问静态页面(html)那么就会快的多了!静态页面本身就比动态页面快很多倍,而且动态页面总是要去数据库查询,这会更加降低速度!
页面静态化是把动态页面生成的html保存到服务器的文件上,然后再有相同请求时,不再去执行动态页面,而是直接给用户响应上次已经生成的静态页面。而且静态页面还有助与搜索引擎找到你!
2 查看图书分类
我们先来写一个小例子,用来查看不同分类的图书。然后我们再去思考如何让动态页面静态化的问题。
index.jsp
BookServlet.java
public class BookServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
BookService bookService = new BookService();[崔74]
List bookList = null ;
String param = request.getParameter("category");[崔75]
if (param == null || param.isEmpty()) {
bookList = bookService.findAll();[崔76]
} else {
int category = Integer.parseInt (param);
bookList = bookService.findByCategory(category);
[崔77] }
request.setAttribute("bookList", bookList);
request.getRequestDispatcher("/show.jsp").forward(request, response);
[崔78] }
}
show.jsp
"1" align="center" width="50%" >
图书名称
图书单价
图书分类
"book">
${book.bname }
${book.price }
JavaSE分类
JavaEE分类
Java框架分类
3 分析
我们的目标是在用户第一次访问页面时生成静态页面,然后让请求重定向到静态页面上去。当用户再次访问时,直接重定向到静态页面上去。
我们需要为不同的请求生成静态页面,例如用户访问BookServlet?category=1时,我们要生成静态页面,当用户访问BookServlet?category=2时,也要生成静态页面。即不同的参数生成不同的静态页面!
我们可以使用category为key,静态页面的路径为value,保存到一个Map中,然后再把Map保存到ServletContext中。没有对应的静态页面时,我们生成静态页面,再重定向到静态页面,如果存在静态页面,那么直接重定向即可。
StaticResponse.java
public class StaticResponse extends HttpServletResponseWrapper {
private PrintWriter pw;
public StaticResponse(HttpServletResponse response, String filepath)
throws FileNotFoundException, UnsupportedEncodingException {
super (response);
pw = new PrintWriter(filepath, "UTF-8");[崔79]
}
public PrintWriter getWriter[崔80] () throws IOException {
return pw;
}
public void close() throws IOException {
pw.close();[崔81]
}
}
StaticFilter.java
public class StaticFilter implements Filter {
private ServletContext sc;
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String key = "key_" + request.getParameter("category");[崔82]
Map map = (Map) sc.getAttribute("pages");[崔83]
if (map == null ) {
map = new HashMap();
sc.setAttribute("pages", map);
}[崔84]
if (map.containsKey(key)) {
res.sendRedirect(req.getContextPath() + "/staticPages/" + map.get(key));
return ;
}[崔85]
String html = key + ".html";[崔86]
String realPath = sc.getRealPath("/staticPages/" + html);[崔87]
StaticResponse sr = new StaticResponse(res, realPath);[崔88]
chain.doFilter(request, sr);[崔89]
sr.close();[崔90]
res.sendRedirect(req.getContextPath() + "/staticPages/" + html);[崔91]
map.put(key, html);[崔92]
}
public void init(FilterConfig fConfig) throws ServletException {
this .sc = fConfig.getServletContext();
}
}
转载于:https://my.oschina.net/zion/blog/832890
你可能感兴趣的:(java,web.xml,数据库)
移动端城市区县二级联动选择功能实现包
good2know
本文还有配套的精品资源,点击获取简介:本项目是一套为移动端设计的jQuery实现方案,用于简化用户在选择城市和区县时的流程。它包括所有必需文件:HTML、JavaScript、CSS及图片资源。通过动态更新下拉菜单选项,实现城市到区县的联动效果,支持数据异步加载。开发者可以轻松集成此功能到移动网站或应用,并可基于需求进行扩展和优化。1.jQuery移动端解决方案概述jQuery技术简介jQuery
深入解析JVM工作原理:从字节码到机器指令的全过程
一、JVM概述Java虚拟机(JVM)是Java平台的核心组件,它实现了Java"一次编写,到处运行"的理念。JVM是一个抽象的计算机器,它有自己的指令集和运行时内存管理机制。JVM的主要职责:加载:读取.class文件并验证其正确性存储:管理内存分配和垃圾回收执行:解释或编译字节码为机器指令安全:提供沙箱环境限制恶意代码二、JVM架构详解JVM由三个主要子系统组成:1.类加载子系统类加载过程分为
JVM 内存模型深度解析:原子性、可见性与有序性的实现
练习时长两年半的程序员小胡
JVM 深度剖析:从面试考点到生产实践 jvm java 内存模型
在了解了JVM的基础架构和类加载机制后,我们需要进一步探索Java程序在多线程环境下的内存交互规则。JVM内存模型(JavaMemoryModel,JMM)定义了线程和主内存之间的抽象关系,它通过规范共享变量的访问方式,解决了多线程并发时的数据一致性问题。本文将从内存模型的核心目标出发,详解原子性、可见性、有序性的实现机制,以及volatile、synchronized等关键字在其中的作用。一、J
什么是缓存雪崩?缓存击穿?缓存穿透?分别如何解决?什么是缓存预热?
daixin8848
缓存 redis java 开发语言
缓存雪崩:在一个时间段内,有大量的key过期,或者Redis服务宕机,导致大量的请求到达数据库,带来巨大压力-给key设置不同的TTL、利用Redis集群提高服务的高可用性、添加多级缓存、添加降级流策略缓存击穿:给某一个key设置了过期时间,当key过期的时间,恰好这个时间点有大量的并发请求访问这个key,可能会瞬间把数据库压垮-互斥锁:缓存失败时,只允许一个请求去加载数据并更新缓存,其他请求阻塞
Java | 多线程经典问题 - 售票
Ada54
一、售票需求1)同一个票池2)多个窗口卖票,不能出售同一张票二、售票问题代码实现(线程与进程小总结,请戳:Java|线程和进程,创建线程)step1:定义SaleWindow类实现Runnable接口,覆盖run方法step2:实例化SaleWindow对象,创建Thread对象,将SaleWindow作为参数传给Thread类的构造函数,然后通过Thread.start()方法启动线程step3
SpringMVC的执行流程
1、什么是MVCMVC是一种设计模式。MVC的原理图如下所示M-Model模型(完成业务逻辑:有javaBean构成,service+dao+entity)V-View视图(做界面的展示jsp,html……)C-Controller控制器(接收请求—>调用模型—>根据结果派发页面2、SpringMVC是什么SpringMVC是一个MVC的开源框架,SpringMVC=Struts2+Spring,
JAVA接口机结构解析
秃狼
SpringBoot 八股文 Java java 学习
什么是接口机在Java项目中,接口机通常指用于与外部系统进行数据交互的中间层,负责处理请求和响应的转换、协议适配、数据格式转换等任务。接口机的结构我们的接口机的结构分为两个大部分,外部接口机和内部接口机,在业务的调度上也是通过mq来实现的,只要的目的就是为了解耦合和做差异化。在接口机中主要的方法就是定时任务,消息的发送和消费,其他平台调用接口机只能提供外部接口机的方法进行调用,外部接口机可以提供消
Aop +反射 实现方法版本动态切换
需求分析在做技术选型的时候一直存在着两个声音,mongo作为数据库比较mysql好,mysql做为该数据比mongo好。当然不同数据库都有有着自己的优势,我们在做技术选型的时候无非就是做到对数据库的扬长避短。mysql最大的优势就是支持事务,事务的五大特性保证的业务可靠性,随之而来的就是事务会产生的问题:脏读、幻读、不可重复度,当然我们也会使用不同的隔离级别来解决。(最典型的业务问题:银行存取钱)
最新阿里四面面试真题46道:面试技巧+核心问题+面试心得
风平浪静如码
前言做技术的有一种资历,叫做通过了阿里的面试。这些阿里Java相关问题,都是之前通过不断优秀人才的铺垫总结的,先自己弄懂了再去阿里面试,不然就是去丢脸,被虐。希望对大家帮助,祝面试成功,有个更好的职业规划。一,阿里常见技术面1、微信红包怎么实现。2、海量数据分析。3、测试职位问的线程安全和非线程安全。4、HTTP2.0、thrift。5、面试电话沟通可能先让自我介绍。6、分布式事务一致性。7、ni
图论算法经典题目解析:DFS、BFS与拓扑排序实战
周童學
数据结构与算法 深度优先 算法 图论
图论算法经典题目解析:DFS、BFS与拓扑排序实战图论问题是算法面试中的高频考点,本博客将通过四道LeetCode经典题目(均来自"Top100Liked"题库),深入讲解图论的核心算法思想和实现技巧。涵盖DFS、BFS、拓扑排序和前缀树等知识点,每道题配有Java实现和易错点分析。1.岛屿数量(DFS遍历)问题描述给定一个由'1'(陆地)和'0'(水)组成的二维网格,计算岛屿的数量。岛屿由水平或
【异常】使用 LiteFlow 框架时,提示错误ChainDuplicateException: [chain name duplicate] chainName=categoryChallenge
本本本添哥
002 - 进阶开发能力 java
一、报错内容Causedby:com.yomahub.liteflow.exception.ChainDuplicateException:[chainnameduplicate]chainName=categoryChallengeatcom.yomahub.liteflow.parser.helper.ParserHelper.lambda$null$0(ParserHelper.java:1
Java并发核心:线程池使用技巧与最佳实践! | 多线程篇(五)
bug菌¹
Java实战(进阶版) java Java零基础入门 Java并发 线程池 多线程篇
本文收录于「Java进阶实战」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!环境说明:Windows10+IntelliJIDEA2021.3.2+Jdk1.8本文目录前言摘要正文何为线程池?为什么需要线程池?线程池的好处线程池使用场景如何创建线程池?线程池的常见配置源码解析案例分享案例代码演示案例运行
Java 队列
tryxr
java 开发语言 队列
队列一般用什么哪种结构实现队列的特性数据入队列时一定是从尾部插入吗数据出队列时一定是从头部删除吗队列的基本运算有什么队列支持随机访问吗队列的英文表示什么是队列队列从哪进、从哪出队列的进出顺序队列是用哪种结构实现的Queue和Deque有什么区别Queue接口的方法Queue中的add与offer的区别offer、poll、peek的模拟实现如何利用链表实现队列如何利用顺序表实现队列什么叫做双端队列
JVM 内存分配与回收策略:从对象创建到内存释放的全流程
在JVM的运行机制中,内存分配与回收策略是连接对象生命周期与垃圾收集器的桥梁。它决定了对象在堆内存中的创建位置、存活过程中的区域迁移,以及最终被回收的时机。合理的内存分配策略能减少GC频率、降低停顿时间,是优化Java应用性能的核心环节。本文将系统解析JVM的内存分配规则、对象晋升机制,以及实战中的内存优化技巧。一、对象优先在Eden区分配:新生代的“临时缓冲区”大多数情况下,Java对象在新生代
代码随想录算法训练营第三十五天
01背包问题二维题目链接01背包问题二维题解importjava.util.Scanner;publicclassMain{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);intM=sc.nextInt();intN=sc.nextInt();int[]space=newint[M];int[]value=new
微信公众号回调java_处理微信公众号消息回调
weixin_39607620
微信公众号回调java
1、背景在上一节中,咱们知道如何接入微信公众号,可是以后公众号会与咱们进行交互,那么微信公众号如何通知到咱们本身的服务器呢?咱们知道咱们接入的时候提供的url是GET/mp/entry,那么公众号以后产生的事件将会以POST/mp/entry发送到咱们本身的服务器上。html2、代码实现,此处仍是使用weixin-java-mp这个框架实现一、引入weixin-java-mpcom.github.
MySQL复习题
一.填空题1.关系数据库的标准语言是SQL。2.数据库发展的3个阶段中,数据独立性最高的是阶段数据库系统。3.概念模型中的3种基本联系分别是一对一、一对多和多对多。4.MySQL配置文件的文件名是my.ini或my.cnf。5.在MySQL配置文件中,datadir用于指定数据库文件的保存目录。6.添加IFNOTEXISTS可在创建的数据库已存在时防止程序报错。7.MySQL提供的SHOWCREA
学C++的五大惊人好处
为什么要学c++学c++有什么用学习c++的好处有1.中考可以加分2.高考可能直接录取3.就业广且工资高4.在未来30--50年c++一定是一个很受欢迎的职业5.c++成功的例子deepsick等AI智能C++语言兼备编程效率和编译运行效率的语言C++语言是C语言功能增强版,在c语言的基础上添加了面向对象编程和泛型编程的支持既继承了C语言高效,简洁,快速和可移植的传统,又具备类似Java、Go等其
Android GreenDao介绍和Generator生成表对象代码
目录(?)[-]介绍创建工程转载请注明:http://blog.csdn.net/sinat_30276961/article/details/50052109最近无意中发现了GreenDao,然后查看了一些资料后,发现这个数据库框架很适合用,于是乎,查看了官网的api,并自己写了一个小应用总结一下它的使用方法。介绍按照国际惯例,在开篇,总要先介绍一下什么是GreenDao吧。首先需要说明的是Gr
Java8 Stream流的sorted()的排序【正序、倒序、多字段排序】
Tony666688888
java windows 开发语言
针对集合排序,java8可以用Stream流的sorted()进行排序。示例Bean以下我们会使用这个Bean来做示例。publicclassOrder{privateStringweight;privateDoubleprice;privateStringdateStr;//忽略getter、setter、构造方法、toString}字段排序首先是比较器Comparator,形式如下:Compa
用代码生成艺术字:设计个性化海报的秘密
本文围绕“用代码生成艺术字:设计个性化海报的秘密”展开,先概述代码生成艺术字在海报设计中的独特价值,接着介绍常用的代码工具(如HTML、CSS、JavaScript等),详细阐述从构思到实现的完整流程,包括字体样式设计、动态效果添加等,还分享了提升艺术字质感的技巧及实际案例。最后总结代码生成艺术字的优势,为设计师提供打造个性化海报的实用指南,助力提升海报设计的独特性与吸引力,符合搜索引擎SEO标准
java实习生40多天有感
别拿爱情当饭吃
从5月15日开始,我开始第一步步入社会,我今年大三,在一家上市互联网公司做一名实习生,主要做java后端开发。开始的时候,觉得公司的环境挺不错的,不过因为公司在CBD,所以隔壁的午饭和晚饭都要20+RMB,而且还吃不饱,这让我感觉挺郁闷的。一到下午,我就会犯困(因为饿)。因此,我又不得不买一些干粮在公司屯着。关于技术,有一个比较大的项目在需求调研当中,我们做实习生,就是辅助项目经理,测试功能,并且
Mac OSX 下的mysql数据库文件存放位置
Bruuuces
mysql mac osx 位置 存放
之前我的mysql的系统数据库里的表被我玩坏了,万般无奈之下只得删除所有mysql的东西重新构建数据库。按照网上搜到的内容删除后重装发现数据库没有什么变化。于是自己在每个可能存放数据库文件的目录查找,最终确认目录位置如下:使用HomeBrew安装为/usr/local/var/mysql使用官方下载的dmg镜像安装为/usr/local/mysql删除这个目录再重新安装mysql就会重新生成系统数
mac升级mysql_Mac OSX下的MySQL数据库升级
weixin_39801714
mac升级mysql
MacOSX下的数据库升级最麻烦的不过权限的问题.本文的MySQL的安装方式为OSX下DMG磁盘镜像的安装方式,MacPorts/Homebrew的方式大同小异.从5.6.17升级到5.7.18安装目录信息ls-al/usr/local|grepmysqllrwxr-xr-x1rootwheel30B52100:39mysql@->mysql-5.6.17-osx10.7-x86_64drwxr-
大学生入门:初识方法及其易踩坑的点
在java学习过程中,我们不难发现有很多重复使用的功能代码块,每次使用如果都要重新写一遍,岂不是很麻烦,就算是“cv”大法,感觉也不是很方便,那么,有什么办法可以解决这个问题呢?方法!java中,一段可重用的,用于执行特定功能的代码块叫做方法,它可以接收参数、返回结果,并且可以被多次使用。一、方法的基本结构[修饰符]返回值类型方法名([参数列表])[throws异常类型]{//方法体}[throw
[Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
这些不会的
解释:这个错误是很常见的错误,错误的提示已经很清楚了就是java的Object数组不能转换成为String[]数组,这就说明你要转换的数组它本身是Object类型的数组,但是你却非要把它转换为String类的数组,这当然是错误的。示例:[java]viewplaincopypackagecom.dada;importjava.util.ArrayList;importjava.util.List;
【MySQL】MySQL数据库如何改名
武昌库里写JAVA
面试题汇总与解析 spring boot vue.js sql java 学习
MySQL建库授权语句https://www.jianshu.com/p/2237a9649ceeMySQL数据库改名的三种方法https://www.cnblogs.com/gomysql/p/3584881.htmlMySQL安全修改数据库名几种方法https://blog.csdn.net/haiross/article/details/51282417MySQL重命名数据库https://
HikariCP调试日志深度解析:生产环境故障排查完全指南
HikariCP调试日志深度解析:生产环境故障排查完全指南更新时间:2025年7月4日|作者:资深架构师|适用版本:HikariCP5.x+|难度等级:中高级前言在生产环境中,数据库连接池往往是系统性能的关键瓶颈。HikariCP作为当前最流行的Java连接池,其调试日志包含了丰富的运行时信息,能够帮助我们快速定位和解决各种连接池相关问题。本文将深入解析HikariCP的日志体系,提供一套完整的故
大学社团管理系统(11831)
codercode2022
java spring boot spring echarts spring cloud sentinel java-rocketmq
有需要的同学,源代码和配套文档领取,加文章最下方的名片哦一、项目演示项目演示视频二、资料介绍完整源代码(前后端源代码+SQL脚本)配套文档(LW+PPT+开题报告)远程调试控屏包运行三、技术介绍Java语言SSM框架SpringBoot框架Vue框架JSP页面Mysql数据库IDEA/Eclipse开发四、项目截图有需要的同学,源代码和配套文档领取,加文章最下方的名片哦!
今年校招竞争真激烈
12_05
程序员满大街,都要找不到工作了。即使人工智能满大街,我也后悔当初没学机器学习,后悔当初没学Java。C++真难找工作。难道毕了业就失业吗?好担心!
ASM系列六 利用TreeApi 添加和移除类成员
lijingyao8206
jvm 动态代理 ASM 字节码技术 TreeAPI
同生成的做法一样,添加和移除类成员只要去修改fields和methods中的元素即可。这里我们拿一个简单的类做例子,下面这个Task类,我们来移除isNeedRemove方法,并且添加一个int 类型的addedField属性。
package asm.core;
/**
* Created by yunshen.ljy on 2015/6/
Springmvc-权限设计
bee1314
spring Web jsp
万丈高楼平地起。
权限管理对于管理系统而言已经是标配中的标配了吧,对于我等俗人更是不能免俗。同时就目前的项目状况而言,我们还不需要那么高大上的开源的解决方案,如Spring Security,Shiro。小伙伴一致决定我们还是从基本的功能迭代起来吧。
目标:
1.实现权限的管理(CRUD)
2.实现部门管理 (CRUD)
3.实现人员的管理 (CRUD)
4.实现部门和权限
算法竞赛入门经典(第二版)第2章习题
CrazyMizzz
c 算法
2.4.1 输出技巧
#include <stdio.h>
int
main()
{
int i, n;
scanf("%d", &n);
for (i = 1; i <= n; i++)
printf("%d\n", i);
return 0;
}
习题2-2 水仙花数(daffodil
struts2中jsp自动跳转到Action
麦田的设计者
jsp webxml struts2 自动跳转
1、在struts2的开发中,经常需要用户点击网页后就直接跳转到一个Action,执行Action里面的方法,利用mvc分层思想执行相应操作在界面上得到动态数据。毕竟用户不可能在地址栏里输入一个Action(不是专业人士)
2、<jsp:forward page="xxx.action" /> ,这个标签可以实现跳转,page的路径是相对地址,不同与jsp和j
php 操作webservice实例
IT独行者
PHP webservice
首先大家要简单了解了何谓webservice,接下来就做两个非常简单的例子,webservice还是逃不开server端与client端。我测试的环境为:apache2.2.11 php5.2.10做这个测试之前,要确认你的php配置文件中已经将soap扩展打开,即extension=php_soap.dll;
OK 现在我们来体验webservice
//server端 serve
Windows下使用Vagrant安装linux系统
_wy_
windows vagrant
准备工作:
下载安装 VirtualBox :https://www.virtualbox.org/
下载安装 Vagrant :http://www.vagrantup.com/
下载需要使用的 box :
官方提供的范例:http://files.vagrantup.com/precise32.box
还可以在 http://www.vagrantbox.es/
更改linux的文件拥有者及用户组(chown和chgrp)
无量
c linux chgrp chown
本文(转)
http://blog.163.com/yanenshun@126/blog/static/128388169201203011157308/
http://ydlmlh.iteye.com/blog/1435157
一、基本使用:
使用chown命令可以修改文件或目录所属的用户:
命令
linux下抓包工具
矮蛋蛋
linux
原文地址:
http://blog.chinaunix.net/uid-23670869-id-2610683.html
tcpdump -nn -vv -X udp port 8888
上面命令是抓取udp包、端口为8888
netstat -tln 命令是用来查看linux的端口使用情况
13 . 列出所有的网络连接
lsof -i
14. 列出所有tcp 网络连接信息
l
我觉得mybatis是垃圾!:“每一个用mybatis的男纸,你伤不起”
alafqq
mybatis
最近看了
每一个用mybatis的男纸,你伤不起
原文地址 :http://www.iteye.com/topic/1073938
发表一下个人看法。欢迎大神拍砖;
个人一直使用的是Ibatis框架,公司对其进行过小小的改良;
最近换了公司,要使用新的框架。听说mybatis不错;就对其进行了部分的研究;
发现多了一个mapper层;个人感觉就是个dao;
解决java数据交换之谜
百合不是茶
数据交换
交换两个数字的方法有以下三种 ,其中第一种最常用
/*
输出最小的一个数
*/
public class jiaohuan1 {
public static void main(String[] args) {
int a =4;
int b = 3;
if(a<b){
// 第一种交换方式
int tmep =
渐变显示
bijian1013
JavaScript
<style type="text/css">
#wxf {
FILTER: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=#ffffff, EndColorStr=#97FF98);
height: 25px;
}
</style>
探索JUnit4扩展:断言语法assertThat
bijian1013
java 单元测试 assertThat
一.概述
JUnit 设计的目的就是有效地抓住编程人员写代码的意图,然后快速检查他们的代码是否与他们的意图相匹配。 JUnit 发展至今,版本不停的翻新,但是所有版本都一致致力于解决一个问题,那就是如何发现编程人员的代码意图,并且如何使得编程人员更加容易地表达他们的代码意图。JUnit 4.4 也是为了如何能够
【Gson三】Gson解析{"data":{"IM":["MSN","QQ","Gtalk"]}}
bit1129
gson
如何把如下简单的JSON字符串反序列化为Java的POJO对象?
{"data":{"IM":["MSN","QQ","Gtalk"]}}
下面的POJO类Model无法完成正确的解析:
import com.google.gson.Gson;
【Kafka九】Kafka High Level API vs. Low Level API
bit1129
kafka
1. Kafka提供了两种Consumer API
High Level Consumer API
Low Level Consumer API(Kafka诡异的称之为Simple Consumer API,实际上非常复杂)
在选用哪种Consumer API时,首先要弄清楚这两种API的工作原理,能做什么不能做什么,能做的话怎么做的以及用的时候,有哪些可能的问题
在nginx中集成lua脚本:添加自定义Http头,封IP等
ronin47
nginx lua
Lua是一个可以嵌入到Nginx配置文件中的动态脚本语言,从而可以在Nginx请求处理的任何阶段执行各种Lua代码。刚开始我们只是用Lua 把请求路由到后端服务器,但是它对我们架构的作用超出了我们的预期。下面就讲讲我们所做的工作。 强制搜索引擎只索引mixlr.com
Google把子域名当作完全独立的网站,我们不希望爬虫抓取子域名的页面,降低我们的Page rank。
location /{
java-归并排序
bylijinnan
java
import java.util.Arrays;
public class MergeSort {
public static void main(String[] args) {
int[] a={20,1,3,8,5,9,4,25};
mergeSort(a,0,a.length-1);
System.out.println(Arrays.to
Netty源码学习-CompositeChannelBuffer
bylijinnan
java netty
CompositeChannelBuffer体现了Netty的“Transparent Zero Copy”
查看API(
http://docs.jboss.org/netty/3.2/api/org/jboss/netty/buffer/package-summary.html#package_description)
可以看到,所谓“Transparent Zero Copy”是通
Android中给Activity添加返回键
hotsunshine
Activity
// this need android:minSdkVersion="11"
getActionBar().setDisplayHomeAsUpEnabled(true);
@Override
public boolean onOptionsItemSelected(MenuItem item) {
静态页面传参
ctrain
静态
$(document).ready(function () {
var request = {
QueryString :
function (val) {
var uri = window.location.search;
var re = new RegExp("" + val + "=([^&?]*)", &
Windows中查找某个目录下的所有文件中包含某个字符串的命令
daizj
windows 查找某个目录下的所有文件 包含某个字符串
findstr可以完成这个工作。
[html]
view plain
copy
>findstr /s /i "string" *.*
上面的命令表示,当前目录以及当前目录的所有子目录下的所有文件中查找"string&qu
改善程序代码质量的一些技巧
dcj3sjt126com
编程 PHP 重构
有很多理由都能说明为什么我们应该写出清晰、可读性好的程序。最重要的一点,程序你只写一次,但以后会无数次的阅读。当你第二天回头来看你的代码 时,你就要开始阅读它了。当你把代码拿给其他人看时,他必须阅读你的代码。因此,在编写时多花一点时间,你会在阅读它时节省大量的时间。让我们看一些基本的编程技巧: 尽量保持方法简短 尽管很多人都遵
SharedPreferences对数据的存储
dcj3sjt126com
SharedPreferences简介: &nbs
linux复习笔记之bash shell (2) bash基础
eksliang
bash bash shell
转载请出自出处:
http://eksliang.iteye.com/blog/2104329
1.影响显示结果的语系变量(locale)
1.1locale这个命令就是查看当前系统支持多少种语系,命令使用如下:
[root@localhost shell]# locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
Android零碎知识总结
gqdy365
android
1、CopyOnWriteArrayList add(E) 和remove(int index)都是对新的数组进行修改和新增。所以在多线程操作时不会出现java.util.ConcurrentModificationException错误。
所以最后得出结论:CopyOnWriteArrayList适合使用在读操作远远大于写操作的场景里,比如缓存。发生修改时候做copy,新老版本分离,保证读的高
HoverTree.Model.ArticleSelect类的作用
hvt
Web .net C# hovertree asp.net
ArticleSelect类在命名空间HoverTree.Model中可以认为是文章查询条件类,用于存放查询文章时的条件,例如HvtId就是文章的id。HvtIsShow就是文章的显示属性,当为-1是,该条件不产生作用,当为0时,查询不公开显示的文章,当为1时查询公开显示的文章。HvtIsHome则为是否在首页显示。HoverTree系统源码完全开放,开发环境为Visual Studio 2013
PHP 判断是否使用代理 PHP Proxy Detector
天梯梦
proxy
1. php 类
I found this class looking for something else actually but I remembered I needed some while ago something similar and I never found one. I'm sure it will help a lot of developers who try to
apache的math库中的回归——regression(翻译)
lvdccyb
Math apache
这个Math库,虽然不向weka那样专业的ML库,但是用户友好,易用。
多元线性回归,协方差和相关性(皮尔逊和斯皮尔曼),分布测试(假设检验,t,卡方,G),统计。
数学库中还包含,Cholesky,LU,SVD,QR,特征根分解,真不错。
基本覆盖了:线代,统计,矩阵,
最优化理论
曲线拟合
常微分方程
遗传算法(GA),
还有3维的运算。。。
基础数据结构和算法十三:Undirected Graphs (2)
sunwinner
Algorithm
Design pattern for graph processing.
Since we consider a large number of graph-processing algorithms, our initial design goal is to decouple our implementations from the graph representation
云计算平台最重要的五项技术
sumapp
云计算 云平台 智城云
云计算平台最重要的五项技术
1、云服务器
云服务器提供简单高效,处理能力可弹性伸缩的计算服务,支持国内领先的云计算技术和大规模分布存储技术,使您的系统更稳定、数据更安全、传输更快速、部署更灵活。
特性
机型丰富
通过高性能服务器虚拟化为云服务器,提供丰富配置类型虚拟机,极大简化数据存储、数据库搭建、web服务器搭建等工作;
仅需要几分钟,根据CP
《京东技术解密》有奖试读获奖名单公布
ITeye管理员
活动
ITeye携手博文视点举办的12月技术图书有奖试读活动已圆满结束,非常感谢广大用户对本次活动的关注与参与。
12月试读活动回顾:
http://webmaster.iteye.com/blog/2164754
本次技术图书试读活动获奖名单及相应作品如下:
一等奖(两名)
Microhardest:http://microhardest.ite