开发

Spring的@Autowired与自动代理

我想Spring框架的优点,第一条应该就是Spring的依赖注入了吧。尤其@Autowired这个注解,甚至可以直接注解在私有成员变量上而不用去写setter方法。之前看《Spring实战》这书的时候,里面说autowired自动注入是byType的,当时一直以为就是byClass,就是根据变量的类类型,去Spring context中找这样类型的bean。但当我写Dao层、Service层代码的时候,发现情况根本不是这样的。 比如说我现有有一个BookmakerDao接口,以及接口的实现类BookmakerDaoHibernate,并用@Repository注解将实现类注解为Spring bean。 public interface BookmakerDao { /** * */ } @Repository public class BookmakerDaoHibernate implements BookmakerDao { /** […]

Entity的继承以及泛型Dao(二)

一、继承与泛型都是因为懒 接着先前的例子,我们已经把Odds1x2与OddsHandicap这两个实体类的共同属性抽离出来放在他们的抽象父类Odds中。那么接下来要做的就是实现实体类相应的Dao类型。最简单的实现方法就是每个Entity对应一个Dao,每个Dao内都要实现对Entity的增删查改操作,但实际上大部分的增删查改操作都是类似的,只是处理不同的Entity而已。为了少写些重复代码,我们有完全正当的理由写一个泛型Dao来实现这些基本的增删查改操作。 仍然以我们的Odds为例子,假设我们现在只需要实现一个功能,就是查找某场比赛的某种赔率。 public interface OddsDao <T> { /** * 获取所有与某场赛事相关的有效赔率 * @param matchId * @return */ List<T> getAllValidByMatchId(long matchId);

Entity的继承以及泛型Dao(一)

一、两张类似的表与两个类似的实体类 现在我有一个betspider数据库,里面放着我自己的爬虫爬来的足球赔率,以bs_odds_1x2(胜负平赔率)、bs_odds_handicap(让球赔率)这两张表作为例子,他们在数据库中的表结构是这样的: 首先不考虑实体类的继承,这两张表对应着两个独立的实体类:(请暂时忽略下面实体类属性的数据类型与mysql的表字段类型的不完全匹配 =。=#) @Entity @Table(name = "bs_odds_1x2") public class Odds1x2 implements Serializable { private static final long serialVersionUID =

freemarker实现通用布局的模板拆分与复用

一、基础页面布局 假设我们项目页面的通用布局如下图所示: 实现这样的布局的基本html代码如下: <html> <head> </head> <body> <div style="width: 700px; text-align:center; font-size:30px;"> <div style="background-color: #b4efb8;">header</div> <div style="width:30%; height:300px; float:left; background-color:

Spring中@ModelAttribute以及超级坑爹的@SessionAttributes注解

重要的结论要先说出来,千万不要用@SessionAttributes来保存http session的属性!!! 在Spring MVC中,@ModelAttribute注解作用在方法或者方法参数上,表示将被注解的方法的返回值或者是被注解的参数作为Model的属性加入到Model中,然后Spring框架自会将这个Model传递给ViewResolver。Model的生命周期只有一个http请求的处理过程,请求处理完后,Model就销毁了。 @SessionAttributes(attrName)注解的意思就是将Model中的attrName属性作为session的属性保存下来。 但关键是它并不仅仅是将这个属性放到HttpSession中这么简单!它的做法大概可以理解为将Model中的被注解的attrName属性保存在一个SessionAttributesHandler中,在每个RequestMapping的方法执行后,这个SessionAttributesHandler都会将它自己管理的“属性”从Model中写入到真正的HttpSession;同样,在每个RequestMapping的方法执行前,SessionAttributesHandler会将HttpSession中的被@SessionAttributes注解的属性写入到新的Model中。注意!它的生命周期很别扭哦! 所以如果在方法中用HttpSession.removeAttribute()来删除被@SessionAttributes注解的属性,你会发现根本没有效果,因为方法执行结束后,它又被SessionAttributesHandler从Model中写回HttpSession了。可以用一个SessionStatus.setComplete()方法来让SessionAttributesHandler在方法结束后不接手工作,从而达到不写入HttpSession的目的,但这方法太鸡巴扯了我感觉。 所以,最重要的是,千万不要使用@SessionAttributes注解来管理session的属性!!! 下面贴一个简单的例子,自己试一下就知道了 /** * 被@SessionAttributes注解的类,会有一个SessionAttributesHandler加入它的HandlerExecutionChain中 * 在每个RequestMapping的方法执行前,SessionAttributesHandler都会将testSession从HttpSession写入Model * 在每个RequestMapping的方法执行后,SessionAttributesHandler都会将testSession从Model写入HttpSession */ @Controller @RequestMapping("/test") @SessionAttributes("testSession")

在spring中使用hibernate

一、基本配置 在Spring的servlet-context.xml文件中添加 <!– 配置数据库 –> <!– 简单的使用jdbc的DriverManagerDataSource,没有连接池 –> <beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <beans:property name="driverClassName" value="com.mysql.jdbc.Driver" /> <beans:property name="url" value="jdbc:mysql://localhost:3306/your_database" /> <beans:property

奇葩的localhost:8080/announce访问

这是今天写spring boot程序时候遇到的奇葩问题。 首先,由于项目的静态资源我是放在如下项目的src/main/resources/static目录下面(这是使用spring boot项目默认创建的目录) 为了确保spring boot能够将 “http://localhost:8080/resources/css/main.css” 这样的静态文件匹配到该目录下,我在项目的application.properties添加了一行: spring.mvc.static-path-pattern = /resources/** 这样做后,web前端就能正常访问到项目的静态资源了。但同时发现一个问题,这样做会莫名其妙的使日志系统输出o.s.web.servlet.PageNotFound告警(当用户访问不存在的页面时),默认的spring boot配置是不开启该告警的。 这个告警信息可以通过修改spring boot的logging配置来隐藏。在application.properties中添加一行: logging.level.org.springframework.web.servlet.PageNotFound = ERROR 2016.2.23,我一开始以为是这个logging.xx.PageNotFound配置被莫名其妙修改了的原因,但后来测试了好久发现这个logging.xx.PageNotFound其实一直都是INFO级的,所以我怀疑可能是由于配置了static-path-pattern后导致mapping顺序有点不一样了,然后其中某个抛出了pagenotfound异常并输出异常了。后面再查查吧 然后,我发现Console终端时不时的弹出如下Warn

Servlet监听器、过滤器与Spring拦截器

一、监听器 Servlet监听器是指这样的实例对象,首先它实现了Servlet规范中定义的某些Listener接口,然后由Servlet容器实例化,并在整个web application生命周期中监听某些事件,对监听到的事件调用相应的方法进行处理。 Servlet监听器主要包括ServletContextListener、HttpSessionListener、ServletRequestListener这三大类监听器。 ServletContextListener   负责监听Servlet上下文(亦即整个web application)的创建/销毁事件 HttpSessionListener   负责监听Session会话的创建/销毁事件 ServletRequestListener   负责监听用户请求的发起/返回事件。 当这些事件发生时,会自动触发已注册的监听器实例来进行相应处理。 Servlet监听器需要在web项目的web.xml文件中注册,或者使用@WebListener注解。 以一个简单例子作为说明: package com.funway.listener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener;

关于Servlet的输出中文乱码问题

最近在看一个java教程,跟着里面写了一段Servlet代码: @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("处理GET请求"); PrintWriter out = resp.getWriter(); resp.setContentType("text/html;charset=UTF-8"); out.println("<h1>这是一个SERVLET</h1>"); }

python爬虫

好像从python开始流行起,他就与爬虫扯上关系了。一提起python就想到爬虫程序,可能是因为python提供的库(模块)比较方便吧,不管是自带的urllib,还是各种第三方库。总结一下我所了解的关于python爬虫的知识,我觉得可以将这些库分为下面四大类:http协议库,文档解析库,模拟浏览器,爬虫框架。 1. urllib、urllib2、urllib3、requests urllib、urllib2是python 2自带的http库,它们负责请求url链接并返回结果。urllib2并不完全是对urllib的升级,有时候得urllib跟urllib2一起用,比如当你想在POST请求中带上参数的话,就得用urllib.urlencode()来格式化参数,就是这么蛋疼。不过在python 3后,urllib跟urllib2就合并了。 自带的urllib、urllib2有很多局限,比如说链接不可重用(http请求头的connection值总是close)。 urllib3、requests都是针对urllib、urllib2改进的第三方库。requests的底层是用urllib3来实现的,并且比urllib3提供了更强大的接口。 so,可以说,现在最方便的http库应该就是requests了。 2. beautiful soup beautiful soup是用来解析html、xml文档的第三方库,它支持多种解析引擎(包括原生的html引擎、lxml引擎、html5lib引擎)。 通常的工作流程是先使用urllib库请求某个url,然后将返回的html数据传递给beautiful soup进行解析。 通过urllib(requests)+beautiful soup结合可以很好地爬取静态网页的内容。但现在的web技术,Ajax跟node.js大行其道,很多网页内容是通过javascript动态生成的,简单地html爬虫对此根本就无能为力,除非你能破译出javascript动态加载的目标url,然后再访问该地址并解析数据。或者,可以考虑使用“模拟”浏览器来解析页面的dom模型,并进行操作。 3. ghost、selenium

Scroll to Top