??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲AV成人无码久久精品老人,亚洲真人日本在线,亚洲熟妇无码另类久久久http://www.tkk7.com/rain1102/category/37657.html<br/><font color="green" style="font-family: 华文行楷;font-size:16px;">化学l构搜烦Q化学信息学Q生物信息学Q实验室信息学等 ?lt;/font><br/><font color="#3C1435">以高U技的生物、化学信息技术实现生命科学领域中专业数据的计和理、提高研发能力、增强在U研和成本效率方面的国际竞争力,为生物、化学、医药和学术机构提供一的解决Ҏ和技术咨询?lt;/font><br/> <br/><font color="green" style="font-family: 华文行楷;font-size:16px;">子曰Q危邦不入,乱邦不居。天下有道则见,无道则隐?lt;/font><font color="#3C1435"></font><br/> zh-cnFri, 06 May 2011 09:26:00 GMTFri, 06 May 2011 09:26:00 GMT60当@PathVariable遇上中文和点http://www.tkk7.com/rain1102/archive/2011/05/05/349643.html周锐周锐Thu, 05 May 2011 15:03:00 GMThttp://www.tkk7.com/rain1102/archive/2011/05/05/349643.htmlhttp://www.tkk7.com/rain1102/comments/349643.htmlhttp://www.tkk7.com/rain1102/archive/2011/05/05/349643.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/349643.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/349643.htmlSpring MVC?.0开始支持RESTQ而主要就是通过@PathVariable来处理请求参数和路径的映?br /> ׃考虑到SEO的缘故,很多人喜Ƣ把新闻的名UC\径中的一部分d理,q时候中文的名称׃遇到问题Q没办法映射Q这个是因ؓ~码问题Q只要到TOMCAT/conf下找到server.xmlQ添加URIEncoding="UTF-8"q行URL~码讄可以解决中文问题?br /> 另外l常遇到路径中有?."Q而点是特D字W,比如.html, .do{等Q所以Spring MVC默认是把点后面的信息当作文g后缀Q这时候我们就要修改这个默认倹{?/p> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
  <property name="interceptors" ref="localeChangeInterceptor"/>
  <property name="useDefaultSuffixPattern" value="false" /> 
 </bean>

另外Q这时候如果只讄q个Q请求可以传递到对于的controllerQ但传过ȝ数据会有问题Q只会传最后一个点前面的数据,除非你在最后加?#8220;/”Q比?news/试.?  q样׃?#8220;试.?#8221;当作整体Q不然只会得?#8220;试”。这时候我们可以这栯|?span style="color: #000000">@RequestMapping("/news/{title:.*}")
q样׃切ok啦?/span>

周锐 2011-05-05 23:03 发表评论
]]>
Flash Scope for Spring MVC(Without Spring Web Flow)http://www.tkk7.com/rain1102/archive/2010/05/28/322112.html周锐周锐Fri, 28 May 2010 02:19:00 GMThttp://www.tkk7.com/rain1102/archive/2010/05/28/322112.htmlhttp://www.tkk7.com/rain1102/comments/322112.htmlhttp://www.tkk7.com/rain1102/archive/2010/05/28/322112.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/322112.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/322112.htmlhttp://jira.springframework.org/browse/SPR-6464?page=com.atlassian.jira.plugin.system.issuetabpanels%3Aall-tabpanel#issue-tabs

周锐 2010-05-28 10:19 发表评论
]]>
REST in Spring 3: @MVChttp://www.tkk7.com/rain1102/archive/2009/12/24/307201.html周锐周锐Thu, 24 Dec 2009 11:53:00 GMThttp://www.tkk7.com/rain1102/archive/2009/12/24/307201.htmlhttp://www.tkk7.com/rain1102/comments/307201.htmlhttp://www.tkk7.com/rain1102/archive/2009/12/24/307201.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/307201.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/307201.htmlIn the last couple of years, REST has emerged as a compelling alternative to SOAP/WSDL/WS-*-based distributed architectures. So when we started to plan our work on the next major release of Spring – version 3.0, it was quite clear to us that we had to focus on making the development of 'RESTful' Web services and applications easier. Now, what is and isn't 'RESTful' could be the topic of a whole new post all together; in this post I'll take a more practical approach, and focus on the features that we added to the @Controller model of Spring MVC.

A Bit of Background

Ok, I lied: there is some background first. If you really want to learn about the new features, feel free to skip to the next section.

For me, work on REST started about two years ago, shortly after reading the highly recommended book RESTful Web Services from O'Reilly, by Leonard Richardson and Sam Ruby. Initially, I was thinking about adding REST support to Spring Web Services, but after working a couple of weeks on a prototype, it became clear to me that this wasn't a very good fit. In particular, I found out that I had to copy most of the logic from the Spring-MVC DispatcherServlet over to Spring-WS. Clearly, this was not the way to go forward.

Around the same time we introduced the annotation-based model of Spring MVC. This model was clearly an improvement to the former, inheritance-based model. Another interesting development at that time was the development of the JAX-RS specification. My next attempt was to try and merge these two models: to try and combine the @MVC annotations with the JAX-RS annotations, and to be able to run JAX-RS applications within the DispatcherServlet. While I did get a working prototype out of this effort, the result was not satisfactory. There were a number of technical issues which I won't bore you with, but most importantly the approach felt 'clunky' and unnatural for a developer who was already used to Spring MVC 2.5.

Finally, we decided to add the RESTful functionality to features to Spring MVC itself. Obviously, that would mean that there would be some overlap with JAX-RS, but at least the programming model would be satisfactory for Spring MVC developers, both existing and new ones. Additionally, there are already three JAX-RS implementations offering Spring support (Jersey, RESTEasy, and Restlet). Adding a fourth to this list did not seem a good use of our valuable time.

RESTful features in Spring MVC 3.0

Now, enough of the background, let's look at the features!

URI Templates

A URI template is a URI-like string, containing one or more variable names. When these variables are substituted for values, the template becomes a URI. For more information, see the proposed RFC.

In Spring 3.0 M1, we introduced the use of URI templates through the @PathVariable annotation. For instance:

 
1.@RequestMapping("/hotels/{hotelId}")
2.public String getHotel(@PathVariable String hotelId, Model model) {
3.    List<Hotel> hotels = hotelService.getHotels();
4.    model.addAttribute("hotels", hotels);
5.    return "hotels";
6.}

When a request comes in for /hotels/1, that 1 will be bound to the hotelId parameter. You can optionally specify the variable name the parameter is bound to, but when you compile your code with debugging enabled that is not necessary: we infer the path variable name from the parameter name.

You can also have more than one path variable, like so:

 
1.@RequestMapping(value="/hotels/{hotel}/bookings/{booking}", method=RequestMethod.GET)
2.public String getBooking(@PathVariable("hotel") long hotelId, @PathVariable("booking") long bookingId, Model model) {
3.    Hotel hotel = hotelService.getHotel(hotelId);
4.    Booking booking = hotel.getBooking(bookingId);
5.    model.addAttribute("booking", booking);
6.    return "booking";
7.}

This would match requests like /hotels/1/bookings/2, for instance.

You can also combine the use of Ant-style paths and path variables, like so:

 
1.@RequestMapping(value="/hotels/*/bookings/{booking}", method=RequestMethod.GET)
2.public String getBooking(@PathVariable("booking") long bookingId, Model model) {
3.    ...
4.}

and you can use data binding, too:

 
01.@InitBinder
02.public void initBinder(WebDataBinder binder) {
03.    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
04.    binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
05.}
06.  
07.@RequestMapping("/hotels/{hotel}/dates/{date}")
08.public void date(@PathVariable("hotel") String hotel, @PathVariable Date date) {
09.    ...
10.}

The above would match /hotels/1/dates/2008-12-18, for instance.

Content Negotiation

In version 2.5, Spring-MVC lets the @Controller decide which view to render for a given request, through its View, view name, and ViewResolver abstractions. In a RESTful scenario, it is common to let the client decide the acceptable representations, via the Accept HTTP header. The server responds with the delivered representation via the Content-Type header. This process is known as content negotiation.

One issue with the Accept header is that is impossible to change it in a web browser, in HTML. For instance, in Firefox, it's fixed to

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

So what if you want to link to a PDF version of a particular resource? Looking at the file extension is a good workaround. For example, http://example.com/hotels.pdf retrieves the PDF view of the hotel list, as does http://example.com/hotels with an Accept header of application/pdf.

This is what the ContentNegotiatingViewResolver does: it wraps one or more other ViewResolvers, looks at the Accept header or file extension, and resolves a view corresponding to these. In an upcoming blog post, Alef Arendsen will show you how to use the ContentNegotiatingViewResolver.

Views

We also added some new Views to Spring MVC, particularly:

  • the AbstractAtomFeedView and AbstractRssFeedView, which can be used to return an Atom and RSS feed,
  • the MarshallingView, which can be used to return an XML representation. This view is based on the Object/XML Mapping module, which has been copied from the Spring Web Services project. This module wraps XML marshalling technologies such as JAXB, Castor, JiBX, and more, and makes it easier to configure these within a Spring application context,
  • the JacksonJsonView, for JSON representations of objects in your model. This view is actually part of the Spring JavaScript project, which we'll talk about more in a future blog post.

Obviously, these work great in combination with the ContentNegotiatingViewResolver!

HTTP Method Conversion

Another key principle of REST is the use of the Uniform Interface. Basically, this means that all resources (URLs) can be manipulated using the same four HTTP method: GET, PUT, POST, and DELETE. For each of methods, the HTTP specification defines exact semantics. For instance, a GET should always be a safe operation, meaning that is has no side effects, and a PUT or DELETE should be idempotent, meaning that you can repeat these operations over and over again, but the end result should be the same.

While HTTP defines these four methods, HTML only supports two: GET and POST. Fortunately, there are two possible workarounds: you can either use JavaScript to do your PUT or DELETE, or simply do a POST with the 'real' method as an additional parameter (modeled as a hidden input field in an HTML form). This latter trick is what the HiddenHttpMethodFilter does. This filter was introduced in Spring 3.0 M1, and is a plain Servlet Filter. As such, it can be used in combination with any web framework (not just Spring MVC). Simply add this filter to your web.xml, and a POST with a hidden _method parameter will be converted into the corresponding HTTP method request.

As an extra bonus, we've also added support for method conversion in the Spring MVC form tags. For example, the following snippet taken from the updated Petclinic sample:

 
1.<form:form method="delete">
2.    <p class="submit"><input type="submit" value="Delete Pet"/></p>
3.</form:form>

will actually perform an HTTP POST, with the 'real' DELETE method hidden behind a request parameter, to be picked up by the HiddenHttpMethodFilter. The corresponding @Controller method is therefore:

 
1.@RequestMapping(method = RequestMethod.DELETE)
2.public String deletePet(@PathVariable int ownerId, @PathVariable int petId) {
3.    this.clinic.deletePet(petId);
4.    return "redirect:/owners/" + ownerId;
5.}

ETag support

An ETag (entity tag) is an HTTP response header returned by an HTTP/1.1 compliant web server used to determine change in content at a given URL. It can be considered to be the more sophisticated successor to the Last-Modified header. When a server returns a representation with an ETag header, client can use this header in subsequent GETs, in a If-None-Match header. If the content has not changed, the server will return 304: Not Modified.

In Spring 3.0 M1, we introduced the ShallowEtagHeaderFilter. This is a plain Servlet Filter, and thus can be used in combination any web framework. As the name indicates, the filter creates so-called shallow ETags (as opposed to a deep ETags, more about that later). The way it works is quite simple: the filter simply caches the content of the rendered JSP (or other content), generates a MD5 hash over that, and returns that as a ETag header in the response. The next time a client sends a request for the same resource, it use that hash as the If-None-Match value. The filter notices this, renders the view again, and compares the two hashes. If they are equal, a 304 is returned. It is important to note that this filter will not save processing power, as the view is still rendered. The only thing it saves is bandwith, as the rendered response is not sent back over the wire.

Deep ETags are a bit more complicated. In this case, the ETag is based on the underlying domain objects, RDMBS tables, etc. Using this approach, no content is generated unless the underlying data has changed. Unfortunately, implementing this approach in a generic way is much more difficult than shallow ETags. We might add support for deep ETags in a later version of Spring, by relying on JPA's @Version annotation, or an AspectJ aspect for instance.

And more!

In a following post, I will conclude my RESTful journey, and talk about the RestTemplate, which was also introduced in Spring 3.0 M2. This class gives you client-side access to RESTful resources in a fashion similar to the JdbcTemplate, JmsTemplate, etc.

Similar Posts



原文地址Qhttp://blog.springsource.com/2009/03/08/rest-in-spring-3-mvc/

周锐 2009-12-24 19:53 发表评论
]]>
JavaMail问题之Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStreamhttp://www.tkk7.com/rain1102/archive/2009/11/17/302654.html周锐周锐Tue, 17 Nov 2009 03:05:00 GMThttp://www.tkk7.com/rain1102/archive/2009/11/17/302654.htmlhttp://www.tkk7.com/rain1102/comments/302654.htmlhttp://www.tkk7.com/rain1102/archive/2009/11/17/302654.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/302654.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/302654.htmlException in thread "main" Java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStream

解决Ҏ:

   JavaEE版本和JavaMail的版本不一?请将sun公司上下载最新版?http://java.sun.com/products/javamail/downloads/index.html
   例如:javaMail 1.3以下的如果在javaEE5上就会出C面的错误,
   如果q出现此问题Q则是因为javaEE5中包含有javaMail的类但是却不全面,所以出本n的JavaMail
   包冲H?用rar打开X:/Program Files/MyEclipse 6.0/myeclipse/eclipse/plugins/com.genuitec.eclipse.j2eedt.core_x.x.x.zmyeclipsexxxxxxxxx/data/libraryset/EE_5/javaee.jar
,然后删除mail,一切就ok?



周锐 2009-11-17 11:05 发表评论
]]>
Hibernate中主键增长步长ؓ50的问?Oraclehttp://www.tkk7.com/rain1102/archive/2009/11/11/302019.html周锐周锐Wed, 11 Nov 2009 13:54:00 GMThttp://www.tkk7.com/rain1102/archive/2009/11/11/302019.htmlhttp://www.tkk7.com/rain1102/comments/302019.htmlhttp://www.tkk7.com/rain1102/archive/2009/11/11/302019.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/302019.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/302019.html原文地址Qhttp://jhyimu2005.javaeye.com/blog/514379
先声明一下我用的框架是Spring + Hibernate + SpringMVC 数据库用的是Oracle
昨天遇到了一个特诡异的问题就是我使用Oracle序列Q把主键的计ClHibernate处理Q? Entity @Table(name = "BIO_STUDY") public class Study implements Serializable{ private static final long serialVersionUID = -5932941248053882057L; private int id; private Project project; private String name; private String description; private Set<Experiment> experiments; @Id @Column(name = "ID") @SequenceGenerator(name = "BIO_STUDY_SQ", sequenceName = "BIO_STUDY_SQ" ) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "BIO_STUDY_SQ") public int getId() { return id; }


写完部v什么都没问题,可当我写了测试类q行试时发C键的初始值竟然是50Q其步长亦是50Q在同事的帮助下发现原来是Hibernate在做|@SequenceGenerator中添加两个参?span style="color: red">QallocationSize = 1, initialValue = 1Q?/span>OK。通过查找Hibernate的资料发现原来是因ؓallocationSize的默认值是50.具体请参考http://www.oracle.com/technology/global/cn/products/ias/toplink/jpa/resources/toplink-jpa-annotations.html#SequenceGenerator

只需要增加allocationSize = 1可?/span>



周锐 2009-11-11 21:54 发表评论
]]>
AbstractTransactionalJUnit4SpringContextTests中的事务回滚http://www.tkk7.com/rain1102/archive/2009/11/04/301147.html周锐周锐Wed, 04 Nov 2009 12:58:00 GMThttp://www.tkk7.com/rain1102/archive/2009/11/04/301147.htmlhttp://www.tkk7.com/rain1102/comments/301147.htmlhttp://www.tkk7.com/rain1102/archive/2009/11/04/301147.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/301147.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/301147.html 当前有一个User和一个RoleQ它们是多对多关p,中间表ؓuser_role存放user和role的id。部分User代码如下Q?br /> @ManyToMany(cascade = { CascadeType.PERSIST }, fetch = FetchType.LAZY)   
    @JoinTable(name = "user_role",
      joinColumns = @JoinColumn(name = "user_id"),
      inverseJoinColumns = @JoinColumn(name = "role_id"))    

 public Set<Role> getRoles() {
  return roles;
 }
 
 public void setRoles(Set<Role> roles) {
  this.roles = roles;
 }
 
 public void addRole(Role role) {
  if (!this.roles.contains(role)) {
   this.roles.add(role);
  }
 }
 
 public void removeRole(Role role) {
  this.roles.remove(role);
 }

Role中的部分代码如下Q?br /> @ManyToMany(
   cascade = {CascadeType.PERSIST, CascadeType.MERGE},
   mappedBy = "roles",
   targetEntity = User.class
   )

 public Set<User> getUsers() {
  return users;
 }

而测试代码承了AbstractTransactionalJUnit4SpringContextTestsQ代码如下:
 @Test
 public void testManyToMany() {
  Role oneRole = new Role();
  oneRole.setDescription("manager");
  oneRole.setEnabled(true);
  oneRole.setRoleName("manger");
  
  Role twoRole = new Role();
  twoRole.setDescription("waitress");
  twoRole.setEnabled(true);
  twoRole.setRoleName("waitress");
  
  User user = new User();
  user.setEnabled(true);
  user.setPassword("jianghaiying");
  user.setUsername("Jiang HaiYing");
  user.addRole(oneRole);
  user.addRole(twoRole);
  userDAO.persist(user);
  
  try {
   userDAO.getConnection().commit();
  } catch (SQLException e) {
   e.printStackTrace();
  }
 }
q样执行以后Q打印出的信息如下:
Hibernate: insert into user (enabled, password, username) values (?, ?, ?)
Hibernate: insert into role (description, enabled, name) values (?, ?, ?)
Hibernate: insert into role (description, enabled, name) values (?, ?, ?)

q时候问题出来了Qؓ什么没有往关系表中插入数据Q?br /> 其实qƈ不是代码或者配|写错误了,在正式运行代码一切正常,而是AbstractTransactionalJUnit4SpringContextTests出的|事实上多对多兌关系是由Hibernated我们l护的,而AbstractTransactionalJUnit4SpringContextTestsZ保持数据的清z又会自动回滚。如何解册个问题呢Q?br /> ҎQ?br /> 只需要在testҎ上添?span style="color: #008000">@Rollback(false)Q?/span>不让它回滚,一切正怺。这时候也可以Ltry语句了?br /> Hibernate: insert into user (enabled, password, username) values (?, ?, ?)
Hibernate: insert into role (description, enabled, name) values (?, ?, ?)
Hibernate: insert into role (description, enabled, name) values (?, ?, ?)
Hibernate: insert into user_role (user_id, role_id) values (?, ?)
Hibernate: insert into user_role (user_id, role_id) values (?, ?)

周锐 2009-11-04 20:58 发表评论
]]>
Spring MVC集成Tiles时候的属性值国际化http://www.tkk7.com/rain1102/archive/2009/10/24/299586.html周锐周锐Sat, 24 Oct 2009 13:08:00 GMThttp://www.tkk7.com/rain1102/archive/2009/10/24/299586.htmlhttp://www.tkk7.com/rain1102/comments/299586.htmlhttp://www.tkk7.com/rain1102/archive/2009/10/24/299586.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/299586.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/299586.html在用Tiles时? 一般会有类g下配|?
<definition name="main.layout" template="/jsp/layout/baseLayout.jsp">
  <put-attribute name="title" value="Tiles Test Title" />
  <put-attribute name="header" value="/jsp/layout/header.jsp" />
  <put-attribute name="body" value="/" />
  <put-attribute name="footer" value="/jsp/layout/footer.jsp" />
 </definition>

默认情况? 如果valueg"/"开? 则认为是URL, 其他则Q务是字符? 而如果想让title实现国际? 如何配置?
以下有两U解x? 一U就是准备多个tiles配置文g,如tiles_def_zh_CN.xml, tile_def_en_US.xml, q个优点ȝ?个h觉得).
W二U方法就是用标{? 如果spring:message或者fmt{等, 具体如下:
修改tiles配置文g中的title对应的gؓ资源文g中的key:
<put-attribute name="title" value="project.title" />
然后修改面需要渲染的地方:
<tiles:useAttribute id="key" name="title"/>
<title><spring:message code="${key}"/></title>

或?br /> <tiles:useAttribute id="key" name="title"/>
<title><fmt:message key="${key}"/>title>


周锐 2009-10-24 21:08 发表评论
]]>
Interceptor中onFlushDirtyҎ的参数previousState一直是I?/title><link>http://www.tkk7.com/rain1102/archive/2009/06/05/280270.html</link><dc:creator>周锐</dc:creator><author>周锐</author><pubDate>Fri, 05 Jun 2009 12:58:00 GMT</pubDate><guid>http://www.tkk7.com/rain1102/archive/2009/06/05/280270.html</guid><wfw:comment>http://www.tkk7.com/rain1102/comments/280270.html</wfw:comment><comments>http://www.tkk7.com/rain1102/archive/2009/06/05/280270.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/rain1102/comments/commentRss/280270.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/rain1102/services/trackbacks/280270.html</trackback:ping><description><![CDATA[Interceptor中onFlushDirtyҎ的参数previousState一直是I? l检查发现原来在更新对象的时候用saveOrUpdateҎ的缘? 替换使用merge问题p决了.<br /><img src ="http://www.tkk7.com/rain1102/aggbug/280270.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/rain1102/" target="_blank">周锐</a> 2009-06-05 20:58 <a href="http://www.tkk7.com/rain1102/archive/2009/06/05/280270.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用@RequestParaml定h参数到方法参?/title><link>http://www.tkk7.com/rain1102/archive/2009/03/17/260273.html</link><dc:creator>周锐</dc:creator><author>周锐</author><pubDate>Tue, 17 Mar 2009 08:26:00 GMT</pubDate><guid>http://www.tkk7.com/rain1102/archive/2009/03/17/260273.html</guid><wfw:comment>http://www.tkk7.com/rain1102/comments/260273.html</wfw:comment><comments>http://www.tkk7.com/rain1102/archive/2009/03/17/260273.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/rain1102/comments/commentRss/260273.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/rain1102/services/trackbacks/260273.html</trackback:ping><description><![CDATA[@RequestParam注解用于在控制器中绑定请求参数到Ҏ参数.<br /> 用法如下:<br /> @RequestMapping<br />  public void advancedSearch(<br />  <span style="color: #008000">  @RequestParam("queryStr") String queryStr,<br />    @RequestParam("showFlag") String showFlag,<br />    @RequestParam("totalnumber") String totalNumber,<br />    @RequestParam("upType") String upType,<br />    @RequestParam("jmesareq") String jmesaReq,<br />    @RequestParam("isExportOper") String isExportOper,</span><br />    HttpServletResponse response, final HttpServletRequest request,<br />    ModelMap model) {<br />   // get query structure and query type from page<br />   List<Long> cd_ids = new ArrayList<Long>();<br />   if(StringUtils.equals("invoke", jmesaReq)){<br />    cd_ids = (List<Long>)request.getSession().getAttribute(Constants.RESULT_IDS);<br />   }<br />  ....<br />  }<br /> <br /> 使用q个注解参数默认是必需? 但是可以把@RequestParam的required属性设|ؓfalse从而让q个参数可?<br /> 例如<span style="color: #008000">@RequestParam(value="name", required="false")</span><img src ="http://www.tkk7.com/rain1102/aggbug/260273.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/rain1102/" target="_blank">周锐</a> 2009-03-17 16:26 <a href="http://www.tkk7.com/rain1102/archive/2009/03/17/260273.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring Security 2 配置_讲[转蝲]http://www.tkk7.com/rain1102/archive/2009/03/14/259768.html周锐周锐Sat, 14 Mar 2009 15:04:00 GMThttp://www.tkk7.com/rain1102/archive/2009/03/14/259768.htmlhttp://www.tkk7.com/rain1102/comments/259768.htmlhttp://www.tkk7.com/rain1102/archive/2009/03/14/259768.html#Feedback1http://www.tkk7.com/rain1102/comments/commentRss/259768.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/259768.html阅读全文

周锐 2009-03-14 23:04 发表评论
]]>
Spring中Bean的生命中期与InitializingBean和DisposableBean接口http://www.tkk7.com/rain1102/archive/2009/03/14/259764.html周锐周锐Sat, 14 Mar 2009 14:22:00 GMThttp://www.tkk7.com/rain1102/archive/2009/03/14/259764.htmlhttp://www.tkk7.com/rain1102/comments/259764.htmlhttp://www.tkk7.com/rain1102/archive/2009/03/14/259764.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/259764.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/259764.htmlSpring提供了一些标志接口,用来改变BeanFactory中的bean的行为?/span>它们包括InitializingBean?/span>DisposableBean?/span>实现q些接口会DBeanFactory调用前一个接口的afterPropertiesSet()ҎQ?/span>调用后一个接?/span>destroy()ҎQ从而?/span>bean可以在初始化和析构后做一些特定的动作?/span>

在内部,Spring使用BeanPostProcessors 来处理它能找到的标志接口以及调用适当的方法?/span>如果你需要自定义的特性或者其他的Spring没有提供的生命周期行为,你可以实现自q BeanPostProcessor。关于这斚w更多的内容可以看q里Q?/span>W?/span> 3.7 ?/span>“使用BeanPostprocessors定制bean”?/span>

所有的生命周期的标志接口都在下面叙q。在附录的一节中Q你可以扑ֈ相应的图Q?/span>展示?/span>Spring如何理beanQ那些生命周期的Ҏ如何改变你?/span>bean的本质特征以及它们如何被理?/span>

1. InitializingBean / init-method

实现org.springframework.beans.factory.InitializingBean 接口允许一?/span>bean在它的所有必ȝ属性被BeanFactory讄后,来执行初始化的工作?/span>InitializingBean接口仅仅制定了一个方法:

    * Invoked by a BeanFactory after it has set all bean properties supplied    * (and satisfied BeanFactoryAware and ApplicationContextAware).    * <p>This method allows the bean instance to perform initialization only    * possible when all bean properties have been set and to throw an    * exception in the event of misconfiguration.    * @throws Exception in the event of misconfiguration (such    * as failure to set an essential property) or if initialization fails.    */    void afterPropertiesSet() throws Exception;

注意Q通常InitializingBean接口的用是能够避免的(而且不鼓励,因ؓ没有必要把代码同Spring耦合hQ?/span>Bean的定义支持指定一个普通的初始化方法。在使用XmlBeanFactory的情况下Q可以通过指定init-method属性来完成?/span>举例来说Q下面的定义Q?/span>

<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>public class ExampleBean {    public void init() {        // do some initialization work    }}

同下面的完全一P

<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>public class AnotherExampleBean implements InitializingBean {    public void afterPropertiesSet() {        // do some initialization work    }}

但却不把代码耦合?/span>Spring?/span>

2. DisposableBean / destroy-method

实现org.springframework.beans.factory.DisposableBean接口允许一?/span>beanQ?/span>可以在包含它?/span>BeanFactory销毁的时候得C个回调?/span>DisposableBean也只指定了一个方法:

    /**    * Invoked by a BeanFactory on destruction of a singleton.    * @throws Exception in case of shutdown errors.    * Exceptions will get logged but not rethrown to allow    * other beans to release their resources too.    */    void destroy() throws Exception;

注意Q通常DisposableBean接口的用能够避免的Q而且是不鼓励的,因ؓ它不必要地将代码耦合?/span>SpringQ?/span> Bean的定义支持指定一个普通的析构Ҏ。在使用XmlBeanFactory使用的情况下Q它是通过 destroy-method属性完成?/span>举例来说Q下面的定义Q?/span>

<bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="destroy"/>public class ExampleBean {    public void cleanup() {        // do some destruction work (like closing connection)    }}

同下面的完全一P

<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>public class AnotherExampleBean implements DisposableBean {    public void destroy() {        // do some destruction work    }}

但却不把代码耦合?/span>Spring?/span>

重要的提C:当以portotype模式部v一?/span>bean的时候,bean的生命周期将会有许的变化?/span>通过定义Q?/span>Spring无法理一?/span>non-singleton/prototype bean的整个生命周期,因ؓ当它创徏之后Q它被交l客L而且容器Ҏ不再留意它了?/span>当说?/span>non-singleton/prototype bean的时候,你可以把Spring的角色想象成“new”操作W的替代品?/span>从那之后的Q何生命周期方面的事情都由客户端来处理?/span>BeanFactory?/span>bean的生命周期将会在W?/span> 3.4.1 ?/span>“生命周期接口”一节中有更详细的叙q?/span> .



周锐 2009-03-14 22:22 发表评论
]]>
Hibernate ?Spring 多数据源的配|【{载?/title><link>http://www.tkk7.com/rain1102/archive/2009/03/09/258670.html</link><dc:creator>周锐</dc:creator><author>周锐</author><pubDate>Mon, 09 Mar 2009 13:06:00 GMT</pubDate><guid>http://www.tkk7.com/rain1102/archive/2009/03/09/258670.html</guid><wfw:comment>http://www.tkk7.com/rain1102/comments/258670.html</wfw:comment><comments>http://www.tkk7.com/rain1102/archive/2009/03/09/258670.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/rain1102/comments/commentRss/258670.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/rain1102/services/trackbacks/258670.html</trackback:ping><description><![CDATA[<p>Spring2.0.1以后的版本已l支持配|多数据源,q且可以在运行的时候动态加载不同的数据源。通过l承AbstractRoutingDataSource可以实现多数据源的动态{换。目前做的项目就是需要访?2个数据源Q每个数据源的表l构都是相同的,所以要求数据源的变动对于编码h员来说是透明Q也是说同样SQL语句在不同的环境下操作的数据库是不一L。具体的配置如下Q?<br /> 一、首先需要写一个静态的键值对照类Q?/p> <p> <div>代码</div> <div> <div> <div></div> <ol> <li><span><span>package</span><span> cn.com.xinli.ccp.dynamicds;   </span></span> <li><span>  </span> <li><span>public</span><span> </span><span>class</span><span> DataSourceMap {   </span> <li><span>    </span><span>public</span><span> </span><span>static</span><span> </span><span>final</span><span> String Admin=</span><span>"Admin"</span><span>;   </span> <li><span>    </span><span>public</span><span> </span><span>static</span><span> </span><span>final</span><span> String Yxh = </span><span>"Yxh"</span><span>;   </span> <li><span>}  </span></li> </ol> </div> </div> <p> </p> <p> </p> <p> </p> <p>q个cM要在使用的时候当作获得数据源的标志用?<br /> 二、徏立一个获得和讄上下文的c: <br /> <div>代码</div> <div> <div> <div></div> <ol> <li><span><span>package</span><span> cn.com.xinli.ccp.dynamicds;   </span></span> <li><span>  </span> <li><span>public</span><span> </span><span>class</span><span> CustomerContextHolder {   </span> <li><span>    </span><span>private</span><span> </span><span>static</span><span> </span><span>final</span><span> ThreadLocal contextHolder =    </span> <li><span>        </span><span>new</span><span> ThreadLocal();   </span> <li><span>       </span> <li><span>    </span><span>public</span><span> </span><span>static</span><span> </span><span>void</span><span> setCustomerType(String customerType) {   </span> <li><span>      contextHolder.set(customerType);   </span> <li><span>    }   </span> <li><span>       </span> <li><span>    </span><span>public</span><span> </span><span>static</span><span> String getCustomerType() {   </span> <li><span>      </span><span>return</span><span> (String) contextHolder.get();   </span> <li><span>    }   </span> <li><span>       </span> <li><span>    </span><span>public</span><span> </span><span>static</span><span> </span><span>void</span><span> clearCustomerType() {   </span> <li><span>      contextHolder.remove();   </span> <li><span>    }   </span> <li><span>  </span> <li><span>}  </span></li> </ol> </div> </div> <br /> q个主要负责讄上下文环境和获得上下文环境?<br /> 三、徏立动态数据源c,q个cdȝ承AbstractRoutingDataSourceQ?<br /> <div>代码</div> <div> <div> <div></div> <ol> <li><span><span>package</span><span> cn.com.xinli.ccp.dynamicds;   </span></span> <li><span>  </span> <li><span>import</span><span> org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;   </span> <li><span>  </span> <li><span>public</span><span> </span><span>class</span><span> DynamicDataSource </span><span>extends</span><span> AbstractRoutingDataSource {   </span> <li><span>  </span> <li><span>    </span><span>protected</span><span> Object determineCurrentLookupKey() {   </span> <li><span>        </span><span>// TODO Auto-generated method stub </span><span>  </span> <li><span>        </span><span>return</span><span> CustomerContextHolder.getCustomerType();   </span> <li><span>    }   </span> <li><span>  </span> <li><span>}  </span></li> </ol> </div> </div> <br /> q个cdCdetermineCurrentLookupKeyҎQ该Ҏq回一个ObjectQ一般是q回字符Ԍ也可以是枚Dcd。该Ҏ中直接用了CustomerContextHolder.getCustomerType()Ҏ获得上下文环境ƈ直接q回?<br /> 四、编写spring的配|文仉|数据源 <br /> <div>代码</div> <div> <div> <div></div> <ol> <li><span><span><</span><span>bean</span><span> </span><span>id</span><span>=</span><span>"parentDataSource"</span><span>  </span></span> <li><span>            </span><span>class</span><span>=</span><span>"org.springframework.jdbc.datasource.DriverManagerDataSource"</span><span>></span><span>  </span> <li><span>            </span><span><</span><span>property</span><span> </span><span>name</span><span>=</span><span>"driverClassName"</span><span>></span><span>  </span> <li><span>                </span><span><</span><span>value</span><span>></span><span>COM.ibm.db2.jdbc.net.DB2Driver</span><span></</span><span>value</span><span>></span><span>  </span> <li><span>            </span><span></</span><span>property</span><span>></span><span>  </span> <li><span>            </span><span><</span><span>property</span><span> </span><span>name</span><span>=</span><span>"url"</span><span>></span><span>  </span> <li><span>                </span><span><</span><span>value</span><span>></span><span>jdbc:db2:127.0.0.1:TEST</span><span></</span><span>value</span><span>></span><span>  </span> <li><span>            </span><span></</span><span>property</span><span>></span><span>  </span> <li><span>    </span><span></</span><span>bean</span><span>></span><span>  </span> <li><span>       </span> <li><span>    </span><span><</span><span>bean</span><span> </span><span>id</span><span>=</span><span>"adminDataSource"</span><span> </span><span>parent</span><span>=</span><span>"parentDataSource"</span><span>></span><span>  </span> <li><span>        </span><span><</span><span>property</span><span> </span><span>name</span><span>=</span><span>"username"</span><span> </span><span>value</span><span>=</span><span>"admin"</span><span>/></span><span>  </span> <li><span>        </span><span><</span><span>property</span><span> </span><span>name</span><span>=</span><span>"password"</span><span> </span><span>value</span><span>=</span><span>"master997mb"</span><span>/></span><span>  </span> <li><span>    </span><span></</span><span>bean</span><span>></span><span>  </span> <li><span>       </span> <li><span>    </span><span><</span><span>bean</span><span> </span><span>id</span><span>=</span><span>"yxhDataSource"</span><span> </span><span>parent</span><span>=</span><span>"parentDataSource"</span><span>></span><span>  </span> <li><span>        </span><span><</span><span>property</span><span> </span><span>name</span><span>=</span><span>"username"</span><span> </span><span>value</span><span>=</span><span>"yxh"</span><span>/></span><span>  </span> <li><span>        </span><span><</span><span>property</span><span> </span><span>name</span><span>=</span><span>"password"</span><span> </span><span>value</span><span>=</span><span>"yxh"</span><span>/></span><span>  </span> <li><span>    </span><span></</span><span>bean</span><span>></span><span>  </span></li> </ol> </div> </div> <br /> 在这个配|中可以看到首先有个parentDataSourceQ这个主要配|一些数据源的公用信息,目中都是链接DB2数据库;adminDataSource和yxhDataSource是根据不同需要配|的个性化信息Q但都必dparent属性,gؓparentDataSource。这样就配置好了2个数据源信息。当然如果链接的多数据源是不同类型的两个数据库,那么parentDataSource可以不要了Q直接配|两个不同的数据源链接就可以了?<br /> 五、编写spring配置文g配置多数据源映射关系 <br /> <div>代码</div> <div> <div> <div></div> <ol> <li><span><span><</span><span>bean</span><span> </span><span>id</span><span>=</span><span>"dataSource"</span><span> </span><span>class</span><span>=</span><span>"cn.com.xinli.ccp.dynamicds.DynamicDataSource"</span><span>></span><span>  </span></span> <li><span>       </span><span><</span><span>property</span><span> </span><span>name</span><span>=</span><span>"targetDataSources"</span><span>></span><span>  </span> <li><span>          </span><span><</span><span>map</span><span> </span><span>key-type</span><span>=</span><span>"<a title="Java爱好? href="http://www.tkk7.com/rain1102" >Java</a>.lang.String"</span><span>></span><span>  </span> <li><span>             </span><span><</span><span>entry</span><span> </span><span>key</span><span>=</span><span>"Yxh"</span><span> </span><span>value-ref</span><span>=</span><span>"yxhDataSource"</span><span>/></span><span>  </span> <li><span>          </span><span></</span><span>map</span><span>></span><span>  </span> <li><span>       </span><span></</span><span>property</span><span>></span><span>  </span> <li><span>       </span><span><</span><span>property</span><span> </span><span>name</span><span>=</span><span>"defaultTargetDataSource"</span><span> </span><span>ref</span><span>=</span><span>"adminDataSource"</span><span>/></span><span>  </span> <li><span>    </span><span></</span><span>bean</span><span>></span><span>  </span></li> </ol> </div> </div> <br /> 在这个配|中W一个property属性配|目标数据源Q?lt;map key-type="<a title="Java爱好? href="http://www.tkk7.com/rain1102" >Java</a>.lang.String">中的key-type必须要和静态键值对照类DataSourceMap中的值的cd相同Q?lt;entry key="Yxh" value-ref="yxhDataSource"/>中key的值必要和静态键值对照类中的值相同,如果有多个|可以配置多个<entry>标签。第二个property属性配|默认的数据源?<br /> 六、配|hibernate?<br /> Hibernate的配|和普通的hibernate、springl合的配|一?<br /> <div>代码</div> <div> <div> <div></div> <ol> <li><span><span><</span><span>bean</span><span> </span><span>id</span><span>=</span><span>"sessionFactory"</span><span>  </span></span> <li><span>        </span><span>class</span><span>=</span><span>"org.springframework.orm.hibernate3.LocalSessionFactoryBean"</span><span>></span><span>  </span> <li><span>        </span><span><!-- to override, use the "SpringDatasourceConfig" snippet in your project --></span><span>  </span> <li><span>        </span><span><</span><span>property</span><span> </span><span>name</span><span>=</span><span>"dataSource"</span><span>></span><span>  </span> <li><span>            </span><span><</span><span>ref</span><span> </span><span>local</span><span>=</span><span>"dataSource"</span><span> </span><span>/></span><span>  </span> <li><span>        </span><span></</span><span>property</span><span>></span><span>  </span> <li><span>        </span><span><</span><span>property</span><span> </span><span>name</span><span>=</span><span>"mappingResources"</span><span>></span><span>  </span> <li><span>            </span><span><</span><span>list</span><span>></span><span>  </span> <li><span>                </span><span><</span><span>value</span><span>></span><span>  </span> <li><span>                    cn/com/xinli/ccp/entity/User.hbm.xml   </span> <li><span>                </span><span></</span><span>value</span><span>></span><span>  </span> <li><span>                </span><span><</span><span>value</span><span>></span><span>  </span> <li><span>                    cn/com/xinli/ccp/entity/Test.hbm.xml   </span> <li><span>                </span><span></</span><span>value</span><span>></span><span>  </span> <li><span>            </span><span></</span><span>list</span><span>></span><span>  </span> <li><span>        </span><span></</span><span>property</span><span>></span><span>  </span> <li><span>        </span><span><</span><span>property</span><span> </span><span>name</span><span>=</span><span>"hibernateProperties"</span><span>></span><span>  </span> <li><span>            </span><span><</span><span>props</span><span>></span><span>  </span> <li><span>                </span><span><</span><span>prop</span><span> </span><span>key</span><span>=</span><span>"hibernate.dialect"</span><span>></span><span>  </span> <li><span>                    org.hibernate.dialect.DB2Dialect   </span> <li><span>                </span><span></</span><span>prop</span><span>></span><span>  </span> <li><span>                   </span> <li><span>                </span><span><</span><span>prop</span><span> </span><span>key</span><span>=</span><span>"hibernate.show_sql"</span><span>></span><span>true</span><span></</span><span>prop</span><span>></span><span>  </span> <li><span>                </span><span><</span><span>prop</span><span> </span><span>key</span><span>=</span><span>"hibernate.use_outer_join"</span><span>></span><span>true</span><span></</span><span>prop</span><span>></span><span>  </span> <li><span>                </span><span><</span><span>prop</span><span> </span><span>key</span><span>=</span><span>"hibernate.jdbc.batch_size"</span><span>></span><span>50</span><span></</span><span>prop</span><span>></span><span>  </span> <li><span>                </span><span><</span><span>prop</span><span> </span><span>key</span><span>=</span><span>"hibernate.jdbc.fetch_size"</span><span>></span><span>5</span><span></</span><span>prop</span><span>></span><span>  </span> <li><span>                </span><span><</span><span>prop</span><span> </span><span>key</span><span>=</span><span>"hibernate.connection.pool_size"</span><span>></span><span>2</span><span></</span><span>prop</span><span>></span><span>  </span> <li><span>                </span><span><</span><span>prop</span><span> </span><span>key</span><span>=</span><span>"hibernate.connection.autocommit"</span><span>></span><span>false</span><span></</span><span>prop</span><span>></span><span>  </span> <li><span>                </span><span><</span><span>prop</span><span> </span><span>key</span><span>=</span><span>"hibernate.cache.use_query_cache"</span><span>></span><span>false</span><span></</span><span>prop</span><span>></span><span>  </span> <li><span>                </span><span><</span><span>prop</span><span> </span><span>key</span><span>=</span><span>"hibernate.max_fetch_depth"</span><span>></span><span>1</span><span></</span><span>prop</span><span>></span><span>  </span> <li><span>                </span><span><</span><span>prop</span><span> </span><span>key</span><span>=</span><span>"hibernate.bytecode.use_reflection_optimizer"</span><span>></span><span>true</span><span></</span><span>prop</span><span>></span><span>  </span> <li><span>            </span><span></</span><span>props</span><span>></span><span>  </span> <li><span>        </span><span></</span><span>property</span><span>></span><span>  </span> <li><span>    </span><span></</span><span>bean</span><span>></span><span>  </span> <li><span>  </span> <li><span><</span><span>bean</span><span> </span><span>id</span><span>=</span><span>"mydao"</span><span> </span><span>class</span><span>=</span><span>"cn.com.xinli.ccp.dao.HibernateBaseDao"</span><span>></span><span>  </span> <li><span>        </span><span><</span><span>property</span><span> </span><span>name</span><span>=</span><span>"sessionFactory"</span><span>></span><span>  </span> <li><span>            </span><span><</span><span>ref</span><span> </span><span>local</span><span>=</span><span>"sessionFactory"</span><span> </span><span>/></span><span>  </span> <li><span>        </span><span></</span><span>property</span><span>></span><span>  </span> <li><span>    </span><span></</span><span>bean</span><span>></span><span>  </span></li> </ol> </div> </div> <br /> 关于dao的代码这里就省略了?<br /> 七、配|结束,可以使用了?<br /> <div>代码</div> <div> <div> <div></div> <ol> <li><span><span>public</span><span> </span><span>class</span><span> DaoTest </span><span>extends</span><span> TestCase {   </span></span> <li><span>  </span> <li><span>    </span><span>public</span><span> </span><span>void</span><span> testSave() </span><span>throws</span><span> Exception{   </span> <li><span>        CustomerContextHolder.setCustomerType(DataSourceMap.Admin);</span><span>//讄数据?</span><span>  </span> <li><span>        </span><span>//hibernate创徏实体 </span><span>  </span> <li><span>        Test test = </span><span>new</span><span> Test();   </span> <li><span>        test.setTest(</span><span>"22222222"</span><span>);   </span> <li><span>           </span> <li><span>        mydao.save(test);</span><span>//使用dao保存实体 </span><span>  </span> <li><span>           </span> <li><span>        CustomerContextHolder.setCustomerType(DataSourceMap.Yxh);</span><span>//讄为另一个数据源 </span><span>  </span> <li><span>           </span> <li><span>        mydao.save(test);</span><span>//使用dao保存实体到另一个库?</span><span>  </span> <li><span>           </span> <li><span>    }   </span> <li><span>}  </span></li> </ol> </div> </div> 在项目中对于~码人员对多数据源的切换可以做成透明的,操作同样的daoQ就可以讉K不同的数据库了?img src ="http://www.tkk7.com/rain1102/aggbug/258670.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/rain1102/" target="_blank">周锐</a> 2009-03-09 21:06 <a href="http://www.tkk7.com/rain1102/archive/2009/03/09/258670.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring MVC I18N配置http://www.tkk7.com/rain1102/archive/2009/03/07/258389.html周锐周锐Sat, 07 Mar 2009 11:11:00 GMThttp://www.tkk7.com/rain1102/archive/2009/03/07/258389.htmlhttp://www.tkk7.com/rain1102/comments/258389.htmlhttp://www.tkk7.com/rain1102/archive/2009/03/07/258389.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/258389.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/258389.html     <!-- i18n configure -->
    <bean id="messageSource"  class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="com.founder.cst.i18n.messageResource"/> 
    </bean>

2. 配置ResolverQ这里有三种Q基于RequestQ基于SessionQ以及基于CookieQ但一般我们会用基于Session的?br />     <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"/>
    ZRequest的class为:org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
    ZSession的class为:org.springframework.web.servlet.i18n.CookieLocaleResolver

3. 配置拦截?br />     <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />

4. 讄拦截?br />     <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"> 
        <property name="interceptors" ref="localeChangeInterceptor"/>
    </bean>
    如果使用BeanNameUrlHandlerMapping则ؓ
    <bean id="defaultUrlMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
        <property name="interceptors" ref="localeChangeInterceptor" />
    </bean>

最后注意请求参CؓlocaleQ例如locale=zh_CN
在controller里面获取资源文g的时? 注意使用RequestContextUtils.getLocale(request)替代request.getLocale()获取locale信息.


周锐 2009-03-07 19:11 发表评论
]]>
Spring 2.5.6新特性之packagesToScanhttp://www.tkk7.com/rain1102/archive/2009/02/09/253927.html周锐周锐Mon, 09 Feb 2009 09:14:00 GMThttp://www.tkk7.com/rain1102/archive/2009/02/09/253927.htmlhttp://www.tkk7.com/rain1102/comments/253927.htmlhttp://www.tkk7.com/rain1102/archive/2009/02/09/253927.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/253927.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/253927.html
估计有不h无奈选择了从AnnotationSessionFactoryBeanl承一个自定义的子c,自己实现扫描逻辑Q找出@Entity注解q的cL单配|进厅R?br />
Spring 2.5.6里有个不怎么L的改q,那就是在AnnotationSessionFactoryBean上增加了一个新的方法:
setPackagesToScan(String[] packagesToScan)

有了q个ҎQ我们不再需要自己动手去实现实体cȝ扫描了,直接在Spring配置文g中AnnotationSessionFactoryBeanq个section上增加类似如下的一个property卛_(假定你需要加载的实体cL在的包名matchq个字符?com.**.bo")Q?br />
<property name="packagesToScan" value="com.**.bo"/>

你也可以以清单的方式指定多于1条的匚w字串Q如Q?br />
<property name="packagesToScan">
    
<list>
        
<value>com.abc.core.bo</value>
        
<value>com.abc.auditing.bo</value>
    
</list>
</property>


周锐 2009-02-09 17:14 发表评论
]]>
Bind And Validatehttp://www.tkk7.com/rain1102/archive/2009/01/09/250752.html周锐周锐Fri, 09 Jan 2009 15:05:00 GMThttp://www.tkk7.com/rain1102/archive/2009/01/09/250752.htmlhttp://www.tkk7.com/rain1102/comments/250752.htmlhttp://www.tkk7.com/rain1102/archive/2009/01/09/250752.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/250752.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/250752.html在Spring MVC体系里,已经提供了bind(request,command)函数q行Bind and Validate工作?
  但因为默认的bind()函数是抛出Servlet异常Q而不是返回以数组形式保存错误信息的BindingResult对象供Controller处理 所以BaseController另外实现了一个bindObject函数Q?/p>

BindException  bindObject(ServletRequest request, Object command)
1.Bind And Validate的完整用代码:
     public BindingResult bindBook(HttpServletRequest request, Book book) throws Exception
    {
 Integer category_id = new Integer(request.getParameter("category.id"));
        book.setCategory(bookManager.getCategory(category_id));
        binder.setDisallowedFields(new String[]{"category"});
addValidator(new BookValiator());
        return bindObject(request, book);
}
  其中W?-3句是l定不能自动l定的Category对象Q(另外一个方案是实现Category的PropertityEditor,q注册,不过q太不实际了Qƈ命obinder忽略q些已被手工l定的field.
       注意,如果不忽?binderl定时则很有可能出错?/p>

  W?句增加validator?/p>

  W?句执行Bind and Validate?/p>

不过Q我们一般会重蝲preBind()函数来完?-3句的操作。逐一
     而且springmodules+ common-validator已经提供了默认的几种Validator和在XML节点配置默认注入的框Ӟ只有自己写了特别的validatorQƈ且不希望使用common-validator框架来定义时才像W四步那样用BaseController的addValidator函数加入新的validator?/p>

2.Binder
     一般由ServletRequestDataBinder完成Bind的工作。与其他框架自动l定FormBean不同QSpring里需要手工调用Binder.

     但因为日期格式不固定, Binderq没有预先包含Date的Propertity Editor?另外数字cȝEditor默认不允许字W串为空Q这些都需要初始化讄?/p>

     在Multi-action体系?有initBinder()的callBack函数Q?/p>

        SimpleDateFormat dateFormat = new SimpleDateFormat(DateUtil.getDatePattern());
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
        binder.registerCustomEditor(Integer.class, new CustomNumberEditor(Integer.class, true));
        binder.registerCustomEditor(Double.class, new CustomNumberEditor(Double.class, true));
   createBinder的另一个callBack函数是getCommandName()QgetCommandName用于在面?lt;spring:bind>l定错误信息时的标识QbaseController默认定ؓ首字母小写的cd?/p>

 

3.Validator
     Validator的客L和服务器端方案用common validator和spring moudles里的集成 ?/p>

 

4.Bind and Validate出错处理
    Bind and Validate出错Q一般会重新跛_输入面Q在头以如下代码显C错误信息,q新绑定所有数据:

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>


<c:iftest="${book!=null}">
    <spring:bind path="book.*">
        <c:if test="${not empty status.errorMessages}"><  BR>            <div class="error">
                <c:forEach var="error" items="${status.errorMessages}">
                    ${error}<br/>
                </c:forEach>
            </div>
        </c:if>
    </spring:bind>
</c:if>

 



周锐 2009-01-09 23:05 发表评论
]]>
Spring中用Springmodules的Commons Validator做验?/title><link>http://www.tkk7.com/rain1102/archive/2009/01/08/250551.html</link><dc:creator>周锐</dc:creator><author>周锐</author><pubDate>Thu, 08 Jan 2009 14:54:00 GMT</pubDate><guid>http://www.tkk7.com/rain1102/archive/2009/01/08/250551.html</guid><wfw:comment>http://www.tkk7.com/rain1102/comments/250551.html</wfw:comment><comments>http://www.tkk7.com/rain1102/archive/2009/01/08/250551.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/rain1102/comments/commentRss/250551.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/rain1102/services/trackbacks/250551.html</trackback:ping><description><![CDATA[<p>使用Springmodules的Commons Validator做验证需要两个beanQ?span style="font-size: 10pt; color: rgb(42,0,255)">ValidatorFactory</span><span style="font-size: 10pt; color: rgb(42,0,255)">?/span><span style="font-size: 10pt; color: rgb(42,0,255)">BeanValidator</span>Q及两xml文gQ?span style="font-size: 10pt; color: rgb(42,0,255)">validator-rules.xml</span><span style="font-size: 10pt; color: black">?/span><span style="font-size: 10pt; color: rgb(42,0,255)">validation.xml</span>Q的支持Q?span>ValidatorFactory</span>用于刉?span>BeanValidator</span>Q后者则是在E序中执行校验的控制bean。v<span>alidator-rules.xml</span>中定义了各种验证的规则,如字D不为空Q字D输?span>值必Mؓ整数{等Q在q里可以自己扩展验证规则。而v</span><span>alidation.xml</span>中则定义了那些bean及bean中的哪些属性字D需要验证,使用哪些验证规则。validate 分ؓ两验证Q客L验证Q?span>javascript</span>Q和服务器端验证。以下是使用validate的步骤:</p> <span>1.<span style="font: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">       </span></span>在配|?lt;action>-servlet.xml文g中声?span>ValidatorFactory</span> ?<span>BeanValidator</span>Q?br /> <!-- validation --><br />  <bean id="validatorFactory" class="org.springmodules.validation.commons.DefaultValidatorFactory"> <br />     <property name="validationConfigLocations"> <br />         <list> <br />             <value>WEB-INF/validator-rules.xml</value> <br />             <value>WEB-INF/validation.xml</value> <br />         </list> <br />     </property> <br />  </bean> <br />  <br />  <bean id="beanValidator" class="org.springmodules.validation.commons.DefaultBeanValidator"> <br />      <property name="validatorFactory" ref="validatorFactory"/> <br />  </bean><br /> ?nbsp;    声明validatoFactory q里我们使用DefaultValidatorFactory<br /> ?nbsp;    定义其validationConfigLocations属性,validator-rules.xml和validation.xml传入<br /> ?nbsp;    声明beanValidator q里我们使用DefaultBeanValidator <br /> ?nbsp;    在其属性中指明要用的validatorFactory 。这里我们用刚刚定义的validatorFactory<br /> q里需要注意的是随着Springmodules版本的不同,DefaultValidatorFactory和DefaultBeanValidator的包路径有可能不同?br /> <br /> <span>2.<span style="font: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">       </span></span>在需要进行验证的controllerQ即要用form表单或者command的controllerQ中声明validate?br /> <bean id="compoundMainController" class="com.founder.action.CompoundMainController"><br />    <property name="formView"><br />     <value>regcompound</value><br />    </property><br />    <property name="successView"><br />     <value>regcompound</value><br />    </property><br />    <property name="<span style="color: #0000ff">commandClass</span>"><br />     <value>com.founder.domain.ChemicalInfo</value><br />    </property><br />    <property name="<span style="color: #0000ff">commandName</span>"><br />     <value>chemicalInfo</value><br />    </property><br />    <property name="compoundService"><br />     <ref bean="compoundService"/><br />    </property><br />    <property name="validator" ref="beanValidator" /> <br />  </bean><br /> ?nbsp;    commandName 用于指明需要验证的 command的名字,q个名字必须?validation.xml?lt;form name=" xxxxx "> 所写的名字保持一致?br /> ?nbsp;    commandClass用于指定q个command的类型。其必须与你jsp提交的form最后Ş成的commandcd怸致?br /> ?nbsp;    声明该controller使用validatorQ这里将我们刚刚定义的beanValidator传入q去?br /> <br /> <span>3.<span style="font: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">       </span></span>?span style="font-size: 10pt; color: rgb(42,0,255)">validation.xml</span>文g中,定义你要校验?span style="font-size: 10pt; color: rgb(42,0,255)">formbean</span>Q或者说?span style="font-size: 10pt; color: rgb(42,0,255)">command</span>Q?Q定义这?span style="font-size: 10pt; color: rgb(42,0,255)">bean</span>中有哪几?span style="font-size: 10pt; color: rgb(42,0,255)">field</span>需要验证,使用何种规则验证。(<span style="color: red">注意Q这里定义的</span><span style="color: red">form name </span><span style="color: red">必须和前?/span><span style="color: red">controller</span><span style="color: red">中定义的</span><span style="color: red">commandName</span><span style="color: red">保持一?/span>Q以下是几种常用的验证示例:<br />         <form name="chemicalInfo"> <br />             <field property="saltForm" depends="maxlength,required"> <br />                 <arg0 key="chemicalInfo.saltForm.displayName" /> <br />                 <arg1 name="maxlength" key="${var:maxlength}" resource="false" /> <br />                 <var> <br />                     <var-name>maxlength</var-name> <br />                     <var-value>30</var-value> <br />                 </var> <br />             </field> <br />             <field property="saltNumber" depends="required"> <br />                 <arg0 key="chemicalInfo.saltNumber.displayName" /> <br />             </field> <br />         </form> <br /> 而validator-rules.xml默认模板可以从下载的spring-modules-0.9.zipQ当然你下的版本可能不同Q里面的可以扑ֈ?br /> <br /> <span style="font-size: 10pt; color: black">4.  </span><span style="font-size: 10pt; color: black">?span>jsp</span>面中定义错误信息显C句:</span><br /> <spring:bindpath="chemicalInfo.*">   -----?br />     <c:iftest="${not empty status.errorMessages}"><br />     <div class="error">   <br />         <c:forEachvar="error" items="${status.errorMessages}"><br />             <c:outvalue="${error}"escapeXml="false"/><br/><br />         </c:forEach><br />     </div><br />     </c:if><br /> </spring:bind><br /> ?nbsp;     q里的path必须要与传入?jsp的bean的名字一栗如传入该jsp的数据bean叫chemicalInfoQpath应该写为chemicalInfo.*?br /> <br /> <span style="font-size: 10pt">5</span><span style="font-size: 10pt">Q?/span><span style="font-size: 10pt">使客L产生</span><span style="font-size: 10pt">javascript</span><span style="font-size: 10pt">代码Q?br /> <v:javascriptformName="chemicalInfo"    -----?br /> staticJavascript="false" xhtml="true" cdata="false"/><br /> <script type="text/javascript" src="<c:urlvalue="scripts/validator.jsp"/>"></script><br />  <br /> ?nbsp;     v:javascript标签是spring的标{,定义在spring-commons-validator.tld 。其中formName必须与validation.xml中form的name保持一致?/span><img src ="http://www.tkk7.com/rain1102/aggbug/250551.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/rain1102/" target="_blank">周锐</a> 2009-01-08 22:54 <a href="http://www.tkk7.com/rain1102/archive/2009/01/08/250551.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring MVC Annotation & Convention Over Configurationhttp://www.tkk7.com/rain1102/archive/2009/01/07/250410.html周锐周锐Wed, 07 Jan 2009 13:43:00 GMThttp://www.tkk7.com/rain1102/archive/2009/01/07/250410.htmlhttp://www.tkk7.com/rain1102/comments/250410.htmlhttp://www.tkk7.com/rain1102/archive/2009/01/07/250410.html#Feedback1http://www.tkk7.com/rain1102/comments/commentRss/250410.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/250410.htmlSpring MVC在用annotationq行配置controller时候要注意Q两Uurlmapping的模式不能同时用,如果使用annotation׃能再配置urlmapping了?/p> <action>-servlet.xml如下Q?br />

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">

 <!-- 对com.founder.action包中的所有类q行扫描Q以完成Bean创徏和自动依赖注入的功能 -->
 <context:component-scan base-package="com.founder.action"/>
 
<!-- 启动Spring MVC的注解功能,完成h和注解POJO的映?-->
 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
 
<!--把请求的URL映射到Controller的name上面 -->
 <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/> 
  
 <!-- Ҏ型视囑֐U的解析Q即在模型视囑֐U添加前后缀-->
 <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="viewClass">
   <value>org.springframework.web.servlet.view.JstlView</value>
  </property>
  <property name="prefix">
     <value>/jsp/</value>
  </property>
  <property name="suffix">
   <value>.jsp</value>
  </property>
 </bean>

</beans>


package com.founder.action;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;


@Controller
@RequestMapping
public class HelloController{
 @RequestMapping
 public String world(){
  String name = "Eric";
  System.out.println("name is = " + name);
  return "hello";
 }
 
 @RequestMapping
 public String test() {
  String name = "test";
  System.out.println("name is = " + name);
  return "test";
 }
 
}



周锐 2009-01-07 21:43 发表评论
]]>
Yale CAS实现原理及其基础协议[转蝲]http://www.tkk7.com/rain1102/archive/2008/09/08/227739.html周锐周锐Mon, 08 Sep 2008 06:56:00 GMThttp://www.tkk7.com/rain1102/archive/2008/09/08/227739.htmlhttp://www.tkk7.com/rain1102/comments/227739.htmlhttp://www.tkk7.com/rain1102/archive/2008/09/08/227739.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/227739.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/227739.htmlJava 目Q就?8 个?CAS 。对q些l计Q我虽然不以为然Q但有一点可以肯定的是, CAS 是我认ؓ最单实效,而且_安全?SSO 选择?
       本节主要分析 CAS 的安全性,以及Z?CAS 被这栯计,带着许密码学的基础知识Q我希望有助于读者对 CAS 的协议有更深层次的理解?
从结构体pȝQ?CAS 包含两部分:
l         CAS Server
CAS Server 负责完成对用L认证工作Q?CAS Server 需要独立部|Ԍ有不止一U?CAS Server 的实玎ͼ Yale CAS Server ?ESUP CAS Server 都是很不错的选择?
CAS Server 会处理用户名 / 密码{凭?(Credentials) Q它可能会到数据库检索一条用户帐号信息,也可能在 XML 文g中检索用户密码,对这U方式, CAS 均提供一U灵zM同一的接?/ 实现分离的方式, CAS I竟是用何种认证方式Q跟 CAS 协议是分ȝQ也是Q这个认证的实现l节可以自己定制和扩展?
l         CAS Client
CAS Client 负责部v在客LQ注意,我是?Web 应用Q,原则上, CAS Client 的部|意味着Q当有对本地 Web 应用的受保护资源的访问请求,q且需要对h方进行n份认证, Web 应用不再接受M的用户名密码{类似的 Credentials Q而是重定向到 CAS Server q行认证?
目前Q?CAS Client 支持Q某些在完善中)非常多的客户端,包括 Java ?.Net ?ISAPI ?Php ?Perl ?uPortal ?Acegi ?Ruby ?VBScript {客LQ几乎可以这栯Q?CAS 协议能够适合M语言~写的客L应用?
 剖析协议像剖析设计模式Q有些时候,协议让h怸着头脑?CAS 的代理模式要相对复杂一些,它引入了一些新的概念,我希望能够在q里描述一下其原理Q有助于读者在配置和调?CAS SSO 有更清晰的思\?
如果没记错, CAS 协议应该是由 Drew Mazurek 负责可开发的Q从 CAS v1 到现在的 CAS v3 Q整个协议的基础思想都是Z Kerberos 的票据方式?
       CAS v1 非常原始Q传送一个用户名居然?”yes\ndavid.turing” 的方式, CAS v2 开始用了 XML 规范Q大大增Z可扩展性, CAS v3 开始?AOP 技术,?Spring 爱好者可以轻N|?CAS Server 到现有的应用环境中?
CAS 是通过 TGT(Ticket Granting Ticket) 来获?ST(Service Ticket) Q通过 ST 来访问服务,?CAS 也有对应 TGT Q?ST 的实体,而且他们在保?TGT 的方法上虽然有所区别Q但是,最l都可以实现q样一个目的——免dơ登录的ȝ?
       下面Q我们看?CAS 的基本协议框Ӟ
基础协议
cas_protocol-1.jpg
                                                 CAS
基础模式
       上图是一个最基础?CAS 协议Q?CAS Client ?Filter 方式保护 Web 应用的受保护资源Q过滤从客户端过来的每一?Web hQ同Ӟ CAS Client 会分?HTTP h中是否包h Service Ticket( 上图中的 Ticket) Q如果没有,则说明该用户是没有经q认证的Q于是, CAS Client 会重定向用户h?CAS Server Q?Step 2 Q?Step 3 是用戯证过E,如果用户提供了正的 Credentials Q?CAS Server 会生一个随机的 Service Ticket Q然后,~存?Ticket Qƈ且重定向用户?CAS Client Q附带刚才生的 Service Ticket Q, Service Ticket 是不可以伪造的Q最后, Step 5 ?Step6 ?CAS Client ?CAS Server 之间完成了一个对用户的n份核实,?Ticket 查到 Username Q因?Ticket ?CAS Server 产生的,因此Q所?CAS Server 的判断是毋庸|疑的?
       该协议完成了一个很单的dQ就?User(david.turing) 打开 IE Q直接访?helloservice 应用Q它被立即重定向?CAS Server q行认证Q?User 可能感觉到浏览器?helloservcie ?casserver 之间重定向,?User 是看不到Q?CAS Client ?CAS Server 怺间的 Service Ticket 核实 (Validation) q程。当 CAS Server 告知 CAS Client 用户 Service Ticket 对应凿w䆾Q?CAS Client 才会对当?Request 的用戯行服务?
CAS 如何实现 SSO
       当我们的 Web 时代q处于初U阶D늚时候, SSO 是通过׃n cookies 来实玎ͼ比如Q下面三个域名要?SSO Q?
如果通过 CAS 来集成这三个应用Q那么,q三个域名都要做一些域名映,
因ؓ是同一个域Q所以每个站炚w能够׃nZ cas.org ?cookies 。这U方法原始,不灵z而且有不安全隐患,已经被抛弃了?
CAS 可以很简单的实现跨域?SSO Q因为,单点被控制在 CAS Server Q用h有h值的 TGC-Cookie 只是?CAS Server 相关Q?CAS Server 只有一个,因此Q解决了 cookies 不能跨域的问题?
回到 CAS 的基协议图,?Step3 完成之后Q?CAS Server 会向 User 发送一?Ticket granting cookie (TGC) l?User 的浏览器Q这?Cookie q?Kerberos ?TGT Q下ơ当用户?Helloservice2 重定向到 CAS Server 的时候, CAS Server 会主?Get 到这?TGC cookie Q然后做下面的事情:
1Q?span style="font: 7pt 'Times New Roman'">              如果 User 的持?TGC 且其q没失效Q那么就走基协议囄 Step4 Q达C SSO 的效果?
2Q?span style="font: 7pt 'Times New Roman'">              如果 TGC 失效Q那么用戯是要重新认证 ( 走基协议囄 Step3) ?
 CAS 的代理模?
 模式 1 已经能够满大部分简单的 SSO 应用Q现在,我们探讨一U更复杂的情况,即用戯?helloservice Q?helloservice 又依赖于 helloservice2 来获取一些信息,如同Q?
User à helloservice à helloservice2
q种情况下,假设 helloservice2 也是需要对 User q行w䆾验证才能讉KQ那么,Z不媄响用户体验(q多的重定向D User ?IE H口不停?闪动 ) Q?CAS 引入了一U?Proxy 认证机制Q即 CAS Client 可以代理用户去访问其?Web 应用?
代理的前提是需?CAS Client 拥有用户的n份信?( cM凭据 ) ?与其说之前我们提到的 TGC 是用h有对自己w䆾信息的一U凭据,则这里的 PGT 是 CAS Client 端持有的对用戯n份信息的一U凭据。凭?TGC Q?User 可以免去输入密码以获取访问其它服务的 Service Ticket Q所以,q里Q凭?PGT Q?Web 应用可以代理用户d现后端的认证Q而无需前端用户的参与?
如下面的 CAS Proxy 图所C, CAS Client 在基协议之上Q提供了一个额外的 PGT URL l?CAS Server, 于是Q?CAS Server 可以通过 PGT URL 提供一?PGT l?CAS Client ?
cas_protocol-2.jpg
      
初学者可能会对上囄 PGT URL 感到qhQ或者会问,Z么要q么ȝQ要通过一个额外的 URL( 而且?SSL 的入?) M?PGT Q如果直接在 Step 6 q回Q则q用来做对应关系?PGTIOU 都可以省掉?PGTIOU 设计是从安全性考虑的,非常必要Q?CAS 协议安全性问题我会在后面一节介l?
于是Q?CAS Client 拿到?PGT( PGTIOU-85…..ti2td ) Q这?PGT ?TGC 同样地关键, CAS Client 可以通过 PGT 向后?Web 应用q行认证。如下图所C, Proxy 认证与普通的认证其实差别不大Q?Step1, 2 与基模式?Step 1,2 几乎一P唯一不同的是Q?Proxy 模式用的?PGT 而不?TGC Q是 Proxy Ticket Q?PT Q而不?Service Ticket ?
最l的l果是, helloservice2 明白 helloservice 所代理的客h David. Turing 同学Q同ӞҎ本地{略Q?helloservice2 有义务ؓ PGTURL=http://helloservice/proxy 服务 (PGTURL 用于表示一?Proxy 服务 ) Q于是它传递数据给 helloservice 。这P helloservice 便完成一个代理者的角色Q协?User q回他想要的数据?

cas_protocol-3.jpg
   代理认证模式非常有用Q它也是 CAS 协议 v2 的一个最大的变化Q这U模式非帔R合在复杂的业务领域中应?SSO 。因为,以前我们实施 SSO 的时候,都是假定?IE User ?SSO 的访问者,忽视了业务系l作?SSO 的访问者角艌Ӏ?/div>


周锐 2008-09-08 14:56 发表评论
]]>Kerberos?http://www.tkk7.com/rain1102/archive/2008/09/08/227724.html周锐周锐Mon, 08 Sep 2008 06:23:00 GMThttp://www.tkk7.com/rain1102/archive/2008/09/08/227724.htmlhttp://www.tkk7.com/rain1102/comments/227724.htmlhttp://www.tkk7.com/rain1102/archive/2008/09/08/227724.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/227724.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/227724.htmlKerberos协议Q?/span>

Kerberos协议主要用于计算机网l的w䆾鉴别(Authentication), 其特Ҏ用户只需输入一ơn份验证信息就可以凭借此验证获得的票?/span>(ticket-granting ticket)讉K多个服务Q即SSO(Single Sign On)。由于在每个Client?/span>Service之间建立了共享密钥,使得该协议具有相当的安全性?br />
条g

先来看看Kerberos协议的前提条Ӟ

如下图所C,Client?/span>KDCQ?/span> KDC?/span>Service 在协议工作前已经有了各自的共享密钥,q且׃协议中的消息无法IK防火墙Q这些条件就限制?/span>Kerberos协议往往用于一个组l的内部Q?/span> 使其应用场景不同?/span>X.509 PKI?/span>

 

q程

Kerberos
协议分ؓ两个部分Q?/span>

1 . Client?/span>KDC发送自qw䆾信息Q?/span>KDC?/span>Ticket Granting Service得到TGT(ticket-granting ticket)Q?/span> q用协议开始前Client?/span>KDC之间的密钥将TGT加密回复l?/span>Client?/span>

此时只有真正?/span>Client才能利用它与KDC之间的密钥将加密后的TGT解密Q从而获?/span>TGT?/span>

Q此q程避免?/span>Client直接?/span>KDC发送密码,以求通过验证的不安全方式Q?/span>

2. Client利用之前获得?/span>TGT?/span>KDCh其他Service?/span>TicketQ从而通过其他Service的n份鉴别?/span>

 Kerberos协议的重点在于第二部分,介如下:

 

1Q?span>    Client之前获?/span>TGT和要h的服务信?/span>(服务名等)发送给KDCQ?/span>KDC中的Ticket Granting ServiceؓClient?/span>Service之间生成一?/span>Session Key用于Service?/span>Client的n份鉴别。然?/span>KDC这?/span>Session Key和用户名Q用户地址Q?/span>IPQ,服务名,有效?/span>, 旉戳一起包装成一?/span>Ticket(q些信息最l用?/span>Service?/span>Client的n份鉴?/span>)发送给ServiceQ?/span> 不过Kerberos协议q没有直接将Ticket发送给ServiceQ而是通过Client转发l?/span>Service.所以有了第二步?/span>

2Q?span>    此时KDC刚才的Ticket转发l?/span>Client。由于这?/span>Ticket是要l?/span>Service的,不能?/span>Client看到Q所?/span>KDC用协议开始前KDC?/span>Service之间的密钥将Ticket加密后再发送给Client。同时ؓ了让Client?/span>Service之间׃n那个U密(KDC在第一步ؓ它们创徏?/span>Session Key)Q?/span> KDC?/span>Client与它之间的密钥将Session Key加密随加密的Ticket一赯回给Client?/span>

3Q?span>    Z完成Ticket的传递,Client刚才收到的Ticket转发?/span>Service. ׃Client不知?/span>KDC?/span>Service之间的密钥,所以它无法改Ticket中的信息。同?/span>Client收到的Session Key解密出来Q然后将自己的用户名Q用户地址Q?/span>IPQ打包成Authenticator?/span>Session Key加密也发送给Service?/span>

4Q?span>    Service 收到Ticket后利用它?/span>KDC之间的密钥将Ticket中的信息解密出来Q从而获?/span>Session Key和用户名Q用户地址Q?/span>IPQ,服务名,有效期。然后再?/span>Session Key?/span>Authenticator解密从而获得用户名Q用户地址Q?/span>IPQ将其与之前Ticket中解密出来的用户名,用户地址Q?/span>IPQ做比较从而验?/span>Client的n份?/span>

5Q?span>    如果Service有返回结果,其q回l?/span>Client?/span>

ȝ

概括h?/span>Kerberos协议主要做了两g?/span>

1Q?span>    Ticket的安全传递?/span>

2Q?span>    Session Key的安全发布?/span>

再加上时间戳的用就很大E度上的保证了用户鉴别的安全性。ƈ且利?/span>Session KeyQ在通过鉴别之后Client?/span>Service之间传递的消息也可以获?/span>Confidentiality(机密?, Integrity(完整?的保证。不q由于没有用非对称密钥自然也就无法h抗否认性,q也限制了它的应用。不q相对而言它比X.509 PKI的n份鉴别方式实施v来要单多了?/span>

推荐资料Q?/span>

Kerberos的原?/span>

Kerberos: An Authentication Service for Computer Networks

Web Services Securitypd文章 



周锐 2008-09-08 14:23 发表评论
]]>
Commons-Validatorhttp://www.tkk7.com/rain1102/archive/2008/05/07/198893.html周锐周锐Wed, 07 May 2008 02:50:00 GMThttp://www.tkk7.com/rain1102/archive/2008/05/07/198893.htmlhttp://www.tkk7.com/rain1102/comments/198893.htmlhttp://www.tkk7.com/rain1102/archive/2008/05/07/198893.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/198893.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/198893.html阅读全文

周锐 2008-05-07 10:50 发表评论
]]>
目中封装Spring中的试基类http://www.tkk7.com/rain1102/archive/2008/04/21/194490.html周锐周锐Mon, 21 Apr 2008 05:15:00 GMThttp://www.tkk7.com/rain1102/archive/2008/04/21/194490.htmlhttp://www.tkk7.com/rain1102/comments/194490.htmlhttp://www.tkk7.com/rain1102/archive/2008/04/21/194490.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/194490.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/194490.htmlpackage com.founder.common;

import Java.text.SimpleDateFormat;
import Java.util.TimeZone;

import org.hibernate.SessionFactory;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;

/**
 * This class is the base class of all the tests,
 * we can use the dependency injection functionality of spring in all the tests,
 * and the default transaction mode is rollback, so we don't need to write special code to restore data after calling some methods affected database data.
 *
 * @author Rui Zhou, Copyright © 2008 foundersoftware. All Rights Reserved.
 * @version 1.00, 2008-03-22 15:46
 */
public abstract class SpringTestCaseBase extends AbstractTransactionalDataSourceSpringContextTests {
 
 protected SimpleDateFormat sdf;
 
 public SpringTestCaseBase() {
  // query the protected variables to implement denpendency injection automatically,
  // so we don't need to write settor and gettor methods anymore.
  this.setPopulateProtectedVariables(true);
  
  sdf = new SimpleDateFormat("yyyy-MM-dd");
  sdf.setTimeZone(TimeZone.getDefault());
 }
 
 protected String[] getConfigLocations() {
  return new String[] { "file:WebRoot/WEB-INF/applicationContext*.xml"};
    }
 
 protected void flushSession(){
  SessionFactory sessionFactory = (SessionFactory)applicationContext.getBean("sessionFactory");  
        sessionFactory.getCurrentSession().flush();
    }
}



周锐 2008-04-21 13:15 发表评论
]]>
在Servlet(或者FilterQ或者Listener)中用spring的IOC容器 http://www.tkk7.com/rain1102/archive/2008/01/15/175495.html周锐周锐Tue, 15 Jan 2008 08:42:00 GMThttp://www.tkk7.com/rain1102/archive/2008/01/15/175495.htmlhttp://www.tkk7.com/rain1102/comments/175495.htmlhttp://www.tkk7.com/rain1102/archive/2008/01/15/175495.html#Feedback1http://www.tkk7.com/rain1102/comments/commentRss/175495.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/175495.html在servlet或者filter或者Listener中用spring的IOC容器的方法是Q?/p>

WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext()); 

׃spring是注入的对象攑֜ServletContext中的Q所以可以直接在ServletContext取出WebApplicationContext 对象Q?/p>

WebApplicationContext webApplicationContext = (WebApplicationContext) servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

事实上WebApplicationContextUtils.getWebApplicationContextҎ是使用上面的代码实现的Q徏议用上面上面的静态方?nbsp;


注意Q在使用webApplicationContext.getBean("ServiceName")的时候,前面强制转化要用接口,如果使用实现cM报类型{换错误。如Q?br /> LUserService userService Q?(LUserService) webApplicationContext.getBean("userService");

周锐 2008-01-15 16:42 发表评论
]]>
HibernateTemplate的常规用?/title><link>http://www.tkk7.com/rain1102/archive/2007/12/26/170633.html</link><dc:creator>周锐</dc:creator><author>周锐</author><pubDate>Wed, 26 Dec 2007 08:46:00 GMT</pubDate><guid>http://www.tkk7.com/rain1102/archive/2007/12/26/170633.html</guid><wfw:comment>http://www.tkk7.com/rain1102/comments/170633.html</wfw:comment><comments>http://www.tkk7.com/rain1102/archive/2007/12/26/170633.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/rain1102/comments/commentRss/170633.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/rain1102/services/trackbacks/170633.html</trackback:ping><description><![CDATA[<p style="text-indent: 21pt; line-height: 15.7pt">HibernateTemplate<span style="font-family: 宋体">提供非常多的常用Ҏ来完成基本的操作Q比如通常的增加、删除、修攏V查询等操作Q?/span>Spring 2.0<span style="font-family: 宋体">更增加对命名</span>SQL<span style="font-family: 宋体">查询的支持,也增加对分页的支持。大部分情况下,使用</span>Hibernate<span style="font-family: 宋体">的常规用法,可完成大多?/span>DAO<span style="font-family: 宋体">对象?/span>CRUD<span style="font-family: 宋体">操作。下面是</span>HibernateTemplate<span style="font-family: 宋体">的常用方法简介:</span></p> <p><span style="font-family: Wingdings">q<span style="font: 7pt 'Times New Roman'">      </span></span>void delete(Object entity)<span style="font-family: 宋体">Q删除指定持久化实例</span></p> <p><span style="font-family: Wingdings">q<span style="font: 7pt 'Times New Roman'">      </span></span>deleteAll(Collection entities)<span style="font-family: 宋体">Q删除集合内全部持久化类实例</span></p> <p><span style="font-family: Wingdings">q<span style="font: 7pt 'Times New Roman'">      </span></span>find(String queryString)<span style="font-family: 宋体">Q根?/span>HQL<span style="font-family: 宋体">查询字符串来q回实例集合</span></p> <p><span style="font-family: Wingdings">q<span style="font: 7pt 'Times New Roman'">      </span></span>findByNamedQuery(String queryName)<span style="font-family: 宋体">Q根据命名查询返回实例集?/span></p> <p><span style="font-family: Wingdings">q<span style="font: 7pt 'Times New Roman'">      </span></span>get(Class entityClass, Serializable id)<span style="font-family: 宋体">Q根据主键加载特定持久化cȝ实例</span></p> <p><span style="font-family: Wingdings">q<span style="font: 7pt 'Times New Roman'">      </span></span>save(Object entity)<span style="font-family: 宋体">Q保存新的实?/span></p> <p><span style="font-family: Wingdings">q<span style="font: 7pt 'Times New Roman'">      </span></span>saveOrUpdate(Object entity)<span style="font-family: 宋体">Q根据实例状态,选择保存或者更?/span></p> <p><span style="font-family: Wingdings">q<span style="font: 7pt 'Times New Roman'">      </span></span>update(Object entity)<span style="font-family: 宋体">Q更新实例的状态,要求</span>entity<span style="font-family: 宋体">是持久状?/span></p> <p><span style="font-family: Wingdings">q<span style="font: 7pt 'Times New Roman'">      </span></span>setMaxResults(int maxResults)<span style="font-family: 宋体">Q设|分늚大小</span></p><img src ="http://www.tkk7.com/rain1102/aggbug/170633.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/rain1102/" target="_blank">周锐</a> 2007-12-26 16:46 <a href="http://www.tkk7.com/rain1102/archive/2007/12/26/170633.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MyEclipse 开?SSH 整合?java.lang.NoSuchMethodError: org.objectweb.asm.ClassVisitor.visit 解决Ҏ http://www.tkk7.com/rain1102/archive/2007/12/23/169853.html周锐周锐Sun, 23 Dec 2007 12:47:00 GMThttp://www.tkk7.com/rain1102/archive/2007/12/23/169853.htmlhttp://www.tkk7.com/rain1102/comments/169853.htmlhttp://www.tkk7.com/rain1102/archive/2007/12/23/169853.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/169853.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/169853.html Java.lang.NoSuchMethodError: org.objectweb.asm.ClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V
 at net.sf.cglib.core.ClassEmitter.begin_class(ClassEmitter.java:77)
Spring ?/span> Hibernate q的一?/span> jar 文g发生了版本冲H?/span>, 删除 WEB-INF/lib/asm-2.2.3.jar 然后重启 Tomcat.
asm-2.2.3.jar
       asm.jar
       asm-attrs.jar
      asm-commons-2.2.3.jar
      asm-util-2.2.3.jar


周锐 2007-12-23 20:47 发表评论
]]>
采用GenericManager做业务处理的时候CGLIB报错. http://www.tkk7.com/rain1102/archive/2007/12/23/169846.html周锐周锐Sun, 23 Dec 2007 12:26:00 GMThttp://www.tkk7.com/rain1102/archive/2007/12/23/169846.htmlhttp://www.tkk7.com/rain1102/comments/169846.htmlhttp://www.tkk7.com/rain1102/archive/2007/12/23/169846.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/169846.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/169846.html
  1. public interface GenericManager<T, PK extends Serializable> {   
  2.   
  3. public List<T> getAll();   
  4.   
  5. public T get(PK id);   
  6.   
  7. .......基本的CRUDҎ   
  8.   
  9. }  

  1. public class GenericManagerImpl<T, PK extends Serializable> implements GenericManager<T, PK> {   
  2.   
  3. protected BaseGenericHibernateDAO<T, PK> baseGenericHibernateDAO;   
  4.   
  5. public GenericManagerImpl(BaseGenericHibernateDAO<T, PK> baseGenericHibernateDAO) {   
  6. this.baseGenericHibernateDAO = baseGenericHibernateDAO;   
  7. }   
  8.   
  9. 对应实现上面的接口CRUDҎ   
  10.   
  11. }  
但是现在目启动的时候抛Z个如下的错误:
  • Caused by: org.springframework.aop.framework.AopConfigException: Couldn't generate CGLIB subclass of class [class com.xxxx.user.service.impl.UserManagerImpl]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given   
  • Caused by: java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given   
  • at net.sf.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:718)  

  • 是Spring AOP的问?主要是出现在事务q块,׃我用的是Spring2.0 AOP 来声明事?在声明事务的时候我把taget-prent-class="true" ?但事实上不能为true.Lq个OK了因针对接口代理.


    周锐 2007-12-23 20:26 发表评论
    ]]>
    Spring事务、异?/title><link>http://www.tkk7.com/rain1102/archive/2007/07/16/130588.html</link><dc:creator>周锐</dc:creator><author>周锐</author><pubDate>Mon, 16 Jul 2007 07:23:00 GMT</pubDate><guid>http://www.tkk7.com/rain1102/archive/2007/07/16/130588.html</guid><wfw:comment>http://www.tkk7.com/rain1102/comments/130588.html</wfw:comment><comments>http://www.tkk7.com/rain1102/archive/2007/07/16/130588.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.tkk7.com/rain1102/comments/commentRss/130588.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/rain1102/services/trackbacks/130588.html</trackback:ping><description><![CDATA[<p><span>Spring</span><span>的事务实现采用基?/span><span>AOP</span><span>的拦截器来实玎ͼ如果没有在事务配|的时候注明回滚的</span><span>checked exception</span><span>Q那么只有在发生?/span><span>unchecked exception</span><span>的时候,才会q行事务回滚。因此在</span><span>DAO</span><span>层和</span><span>service</span><span>层,最好抛?/span><span>unckecked exception</span><span>Q毕竟对于数据库操作Q?/span><span>unckecked exception</span><span>更加合适,q个斚w的例?/span><span>hibernate</span><span>是一个,?/span><span>hibernate2</span><span>中,</span><span>HibernateException</span><span>q是</span><span>checked exceptions</span><span>Q但是到?/span><span>hibernate3</span><span>中就成了</span><span>unchecked exceptions</span><span>Q因为对于数据库操作来说Q一旦出现异常,是比较严重的错误,而且?/span><span>client</span><span>端基本上是无能ؓ力的Q所以?/span><span>unchecked exceptions</span><span>更加合适?/span></p> <p><span>另外Q在</span><span>DAO</span><span>?/span><span>service</span><span>层的代码中,除非是ؓ了异常的转化、重新抛出,否则不要捕捉和处理异常,否则</span><span>AOP</span><span>在拦截的时候就不能捕捉到异常,也就不能正确执行回滚。这一炚w常很容易被忽视Q只有在明白?/span><span>spring</span><span>的事务处理机制后Q才能领会到?/span></p> <p><span>对于</span><span>hibernate</span><span>的异常,</span><span>spring</span><span>会包?/span><span>hibernate</span><span>?/span><span>upckecked hibernateException</span><span>?/span><span>DAOAccessException</span><span>Qƈ且抛出,在事务管理层Q一旦接收到</span><span>DAOAccessException</span><span>׃触发事务的回滚,同时该异怼l箋向上层抛出,供上层进一步处理,比如?/span><span>UI</span><span>层向用户反馈错误信息{?br>在spring的事务管理环境下Q用unckecked exception可以极大地简化异常的处理Q只需要在事务层声明可能抛出的异常Q这里的异常可以是自定义的unckecked exception体系Q,在所有的中间层都只是需要简单throws卛_Q不需要捕捉和处理Q直接到最高层Q比如UI层再q行异常的捕捉和处理?br></span></p><img src ="http://www.tkk7.com/rain1102/aggbug/130588.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/rain1102/" target="_blank">周锐</a> 2007-07-16 15:23 <a href="http://www.tkk7.com/rain1102/archive/2007/07/16/130588.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring中的所有事务策?/title><link>http://www.tkk7.com/rain1102/archive/2007/07/13/130075.html</link><dc:creator>周锐</dc:creator><author>周锐</author><pubDate>Fri, 13 Jul 2007 06:05:00 GMT</pubDate><guid>http://www.tkk7.com/rain1102/archive/2007/07/13/130075.html</guid><wfw:comment>http://www.tkk7.com/rain1102/comments/130075.html</wfw:comment><comments>http://www.tkk7.com/rain1102/archive/2007/07/13/130075.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/rain1102/comments/commentRss/130075.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/rain1102/services/trackbacks/130075.html</trackback:ping><description><![CDATA[Spring中的所?nobr>事务</nobr>{略Q?br> <ul> <li>PROPAGATION_REQUIRED--支持当前事务Q如果当前没有事务,新Z个事务。这是最常见的选择? <li>PROPAGATION_SUPPORTS--支持当前事务Q如果当前没有事务,׃非事务方式执行? <li>PROPAGATION_MANDATORY--支持当前事务Q如果当前没有事务,抛出异常? <li>PROPAGATION_REQUIRES_NEW--新徏事务Q如果当前存在事务,把当前事务挂赗? <li>PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作Q如果当前存在事务,把当前事务挂v? <li>PROPAGATION_NEVER--以非事务方式执行Q如果当前存在事务,则抛出异常? <li>PROPAGATION_NESTED--如果当前存在事务Q则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIREDcM的操作?</li> </ul><img src ="http://www.tkk7.com/rain1102/aggbug/130075.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/rain1102/" target="_blank">周锐</a> 2007-07-13 14:05 <a href="http://www.tkk7.com/rain1102/archive/2007/07/13/130075.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Open Session in Test 及自动Rollbackhttp://www.tkk7.com/rain1102/archive/2007/05/15/117541.html周锐周锐Tue, 15 May 2007 03:09:00 GMThttp://www.tkk7.com/rain1102/archive/2007/05/15/117541.htmlhttp://www.tkk7.com/rain1102/comments/117541.htmlhttp://www.tkk7.com/rain1102/archive/2007/05/15/117541.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/117541.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/117541.html 
    如果不能l承于这个基c,可以自己单编写,代码是这LQ?br>   protected PlatformTransactionManager transactionManager;
       protected TransactionStatus transactionStatus;
       protected boolean defaultRollback = true;
       public void setUp()
       {
            transactionManager = (PlatformTransactionManager) ctx.getBean("transactionManager");
            transactionStatus = transactionManager.getTransaction(new DefaultTransactionDefinition());
       }
       public void tearDown()
       {
            if (defaultRollback)
                transactionManager.rollback(this.transactionStatus);
            else
               transactionManager.commit(this.transactionStatus);
        }
    (注,hibernate太奸诈了Q如果全部默认回滚,只会在session里干z,一点不写数据库Q达不到完全的测试效果?

    周锐 2007-05-15 11:09 发表评论
    ]]>
    关于Spring中的回滚问题AbstractTransactionalDataSourceSpringContextTestshttp://www.tkk7.com/rain1102/archive/2007/05/15/117518.html周锐周锐Tue, 15 May 2007 02:06:00 GMThttp://www.tkk7.com/rain1102/archive/2007/05/15/117518.htmlhttp://www.tkk7.com/rain1102/comments/117518.htmlhttp://www.tkk7.com/rain1102/archive/2007/05/15/117518.html#Feedback0http://www.tkk7.com/rain1102/comments/commentRss/117518.htmlhttp://www.tkk7.com/rain1102/services/trackbacks/117518.htmlHibernateTemaplate.executeWithSession(...){
    public Object doInHibernate(Session session) {
    runTest();
    session.flush();//synchornize database, errors will be reported.
    session.clear();}...}
    而AbstractTransactionalDataSourceSpringContextTests只要你不调用super.setDefaultRollback(false);q个基类默认׃回滚! 于是由此产生hibernateh,无法发现数据库操?然后我们你在试中显C用session.flush
    或者参杂一些查询调?其实也是Z触发session.flush)?/p>

    不过q里面也有些陷阱:如果你的试q是会把数据写入了数据库的话,可能是由于你加蝲的spring配置文g里有多个事务理器或session工厂,从而导致AbstractTransactionalDataSourceSpringContextTests没有获得正确的TransactionManager或SessionFactory,所以就没能回滚不过q种错误也不太容易犯,因ؓAbstractTransactionalDataSourceSpringContextTests默认按类型组?如果她发现有多个TransactionManagercd的bean是要报错?此时你需要调用setAutowireMode(this.AUTOWIRE_BY_NAME);使其按名U组装?br>
    另外值得注意的是Q用MYSQL时候表的类型选择。例?/p>

    CREATE TABLE `myisam` (
      `id` 
    int(11NOT NULL auto_increment,
      `name` 
    varchar(100default NULL,
      `content` 
    text,
      
    PRIMARY KEY  (`id`)
    ) ENGINE
    =MyISAM DEFAULT CHARSET=gbk;
    q时候应该把cd改ؓInnoDB?/span>

    MySQL存储引擎包括处理事务安全表的引擎和处理非事务安全表的引擎Q?#183; MyISAM理非事务表。它提供高速存储和索,以及全文搜烦能力。MyISAM在所有MySQL配置里被支持Q它是默认的存储引擎Q除非你配置 MySQL默认使用另外一个引擎?·MEMORY存储引擎提供“内存?#8221;表。MERGE存储引擎允许集合被处理同样的MyISAM表作Z个单独的表。就像MyISAM一P MEMORY和MERGE存储引擎处理非事务表Q这两个引擎也都被默认包含在MySQL中?释:MEMORY存储引擎正式地被定为HEAP引擎?#183; InnoDB和BDB存储引擎提供事务安全表。BDB被包含在为支持它的操作系l发布的MySQL-Max二进制分发版里。InnoDB也默认被包括在所 有MySQL 5.1二进制分发版里,你可以按照喜好通过配置MySQL来允许或止M引擎?#183;EXAMPLE存储引擎是一?#8220;存根”引擎Q它不做什么。你可以用这?引擎创徏表,但没有数据被存储于其中或从其中检索?/span>



    周锐 2007-05-15 10:06 发表评论
    ]]>
    acegi的配|?/title><link>http://www.tkk7.com/rain1102/archive/2007/03/29/107142.html</link><dc:creator>周锐</dc:creator><author>周锐</author><pubDate>Thu, 29 Mar 2007 02:32:00 GMT</pubDate><guid>http://www.tkk7.com/rain1102/archive/2007/03/29/107142.html</guid><wfw:comment>http://www.tkk7.com/rain1102/comments/107142.html</wfw:comment><comments>http://www.tkk7.com/rain1102/archive/2007/03/29/107142.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/rain1102/comments/commentRss/107142.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/rain1102/services/trackbacks/107142.html</trackback:ping><description><![CDATA[<p>applicationContext-acegi-security.xml<br /><strong>1.filterChainProxy配置<br /></strong><bean id="<font style="BACKGROUND-COLOR: #ffffff" color="#800080">filterChainProxy</font>" class="org.acegisecurity.util.FilterChainProxy"><br />  <property name="<font style="BACKGROUND-COLOR: #ffffff" color="#006400">filterInvocationDefinitionSource</font>"><br />   <value><br />    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON<br />    PATTERN_TYPE_APACHE_ANT<br />    /**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor<br />   </value><br />  </property><br /> </bean><br /><br /><strong>2.httpSessionContextIntegrationFilter配置</strong><br /><bean id="<font color="#800080">httpSessionContextIntegrationFilter</font>" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"/><br /><br />3.logoutFilter配置<br /><bean id="<font color="#800080">logoutFilter</font>" class="org.acegisecurity.ui.logout.LogoutFilter"><br />  <constructor-arg value="/index.jsp"/> <!-- URL redirected to after logout --><br />  <constructor-arg><br />   <list><br />    <ref bean="<font color="#006400">rememberMeServices</font>"/><br />    <bean class="<font color="#006400">org.acegisecurity.ui.logout.SecurityContextLogoutHandler</font>"/><br />   </list><br />  </constructor-arg><br /> </bean><br /><br /><strong>4.authenticationProcessingFilter配置<br /></strong><bean id="<font color="#800080">authenticationProcessingFilter</font>" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter"><br />  <property name="<font color="#006400">authenticationManager</font>" ref="authenticationManager"/><br />  <property name="<font color="#006400">authenticationFailureUrl</font>" value="/login.jsp?login_error=1"/><br />  <property name="<font color="#006400">defaultTargetUrl</font>" value="/"/><br />  <property name="<font color="#006400">filterProcessesUrl</font>" value="/j_acegi_security_check"/><br />  <property name="<font color="#006400">rememberMeServices</font>" ref="rememberMeServices"/><br /> </bean><br /><br /><strong>5.securityContextHolderAwareRequestFilter配置</strong><br /><bean id="<font color="#800080">securityContextHolderAwareRequestFilter</font>" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/><br /><br /><strong>6.rememberMeProcessingFilter配置</strong><br /><bean id="<font color="#800080">rememberMeProcessingFilter</font>" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter"><br />  <property name="<font color="#006400">authenticationManager</font>" ref="authenticationManager"/><br />  <property name="<font color="#006400">rememberMeServices</font>" ref="rememberMeServices"/><br /> </bean><br /><br /><strong>7.anonymousProcessingFilter配置</strong><br /><bean id="<font color="#800080">anonymousProcessingFilter</font>" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter"><br />  <property name="<font color="#006400">key</font>" value="changeThis"/><br />  <property name="<font color="#006400">userAttribute</font>" value="anonymousUser,ROLE_ANONYMOUS"/><br /> </bean><br /><br /><strong>8.exceptionTranslationFilter配置</strong><br /><bean id="<font color="#800080">exceptionTranslationFilter</font>" class="org.acegisecurity.ui.ExceptionTranslationFilter"><br />  <property name="<font color="#006400">authenticationEntryPoint</font>"><br />   <bean class="<font color="#006400">org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint</font>"><br />    <property name="<font color="#006400">loginFormUrl</font>" value="/login.jsp"/><br />    <property name="<font color="#008000">forceHttps</font>" value="false"/><br />   </bean><br />  </property><br />  <property name="<font color="#006400">accessDeniedHandler</font>"><br />   <bean class="<font color="#006400">org.acegisecurity.ui.AccessDeniedHandlerImpl</font>"><br />    <property name="<font color="#006400">errorPage</font>" value="/accessDenied.jsp"/><br />   </bean><br />  </property><br /> </bean><br /><br /><strong>9.filterInvocationInterceptor配置</strong><br /><bean id="<font color="#800080">filterInvocationInterceptor</font>" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor"><br />  <property name="<font color="#006400">authenticationManager</font>" ref="authenticationManager"/><br />  <property name="<font color="#006400">accessDecisionManager</font>" ref="accessDecisionManager"/><br />  <property name="<font color="#006400">objectDefinitionSource</font>"><br />   <value><br />    PATTERN_TYPE_APACHE_ANT<br />    /mainFrame.html=admin,user<br />    /文g?/*.html*=admin,user<br />    /文g?/*.html*=admin,user<br />    /文g?/*.html*=admin<br />    /accessDenied.jsp*=ROLE_ANONYMOUS<br />   </value><br />  </property><br /> </bean><br /><br /><strong>10.</strong><font color="#000000"><strong>accessDecisionManager配置</strong><br /></font><bean id="<font color="#800080">accessDecisionManager</font>" class="org.acegisecurity.vote.AffirmativeBased"><br />  <property name="allowIfAllAbstainDecisions" value="false"/><br />  <property name="decisionVoters"><br />   <list><br />    <bean class="org.acegisecurity.vote.RoleVoter"><br />     <property name="rolePrefix" value=""/><br />    </bean><br />    <bean class="org.acegisecurity.vote.AuthenticatedVoter"/><br />   </list><br />  </property><br /> </bean><br /><br /><strong>11.rememberMeServices配置</strong></p> <p> <bean id="<font color="#800080">rememberMeServices</font>" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices"><br />  <property name="userDetailsService" ref="userDetailsService"/><br />  <property name="key" value="changeThis"/><br /> </bean><br /><br /><strong>12.authenticationManager配置</strong></p> <p> <bean id="<font color="#800080">authenticationManager</font>" class="org.acegisecurity.providers.ProviderManager"><br />  <property name="providers"><br />   <list><br />    <ref local="daoAuthenticationProvider"/><br />    <bean class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider"><br />     <property name="key" value="changeThis"/><br />    </bean><br />    <bean class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider"><br />     <property name="key" value="changeThis"/><br />    </bean><br />   </list><br />  </property><br /> </bean><br /><br /><strong>13.daoAuthenticationProvider配置</strong></p> <p> <bean id="<font color="#800080">daoAuthenticationProvider</font>" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider"><br />  <property name="userDetailsService" ref="userDetailsService"/><br />  <property name="userCache"><br />   <bean class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache"><br />    <property name="cache"><br />     <bean class="org.springframework.cache.ehcache.EhCacheFactoryBean"><br />      <property name="cacheManager"><br />       <bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"><br />        <property name="configLocation" value="classpath:ehcache.xml"/><br />       </bean><br />      </property><br />      <property name="cacheName" value="userCache"/><br />     </bean><br />    </property><br />   </bean><br />  </property><br /> </bean><br /><br /><strong>14.methodSecurityInterceptor配置</strong><br /> <br /> <bean id="<font color="#800080">methodSecurityInterceptor</font>" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor"><br />  <property name="authenticationManager" ref="authenticationManager"/><br />  <property name="accessDecisionManager" ref="accessDecisionManager"/><br />  <property name="objectDefinitionSource"><br />    <value><br />     com.rain.wsh.service.IUserService.get*=IS_AUTHENTICATED_ANONYMOUSLY <br />      com.rain.wsh.service.IUserService.create*=IS_AUTHENTICATED_ANONYMOUSLY <br />      com.rain.wsh.service.IUserService.update*=IS_AUTHENTICATED_ANONYMOUSLY <br />      com.rain.wsh.service.IUserService.delete*=IS_AUTHENTICATED_ANONYMOUSLY <br />   </value><br />  </property><br /> </bean><br /><br /><strong>15.loggerListener配置</strong></p> <p> <!-- This bean is optional; it isn't used by any other bean as it only listens and logs --><br /> <bean id="<font color="#800080">loggerListener</font>" class="org.acegisecurity.event.authentication.LoggerListener"/><br /><br />?userDetailsService定义?<br /><bean id="<font color="#800080">userDetailsService</font>" class="com.rain.wsh.service.impl.UserDetailsServiceImpl"/><br /><br />package com.rain.wsh.service.impl;</p> <p>import org.acegisecurity.userdetails.UserDetails;<br />import org.acegisecurity.userdetails.UserDetailsService;<br />import org.acegisecurity.userdetails.UsernameNotFoundException;<br />import org.springframework.dao.DataAccessException;</p> <p>import com.rain.wsh.dao.IUserDAO;</p> <p>public class UserDetailsServiceImpl implements <font color="#800080">UserDetailsService</font> {<br /> private final Logger log = Logger.getLogger(getClass());<br /> <br /> private IUserDAO userDAO;<br /> <br /> /**<br />  * @return the userDAO<br />  */<br /> public IUserDAO getUserDAO() {<br />  return userDAO;<br /> }</p> <p> /**<br />  * @param userDAO the userDAO to set<br />  */<br /> public void setUserDAO(IUserDAO userDAO) {<br />  this.userDAO = userDAO;<br /> }<br /> <br /> /*<br />  * (non-Javadoc)<br />  * @see org.acegisecurity.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)<br />  */<br /> public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException {<br />  <br />  UserDetails user = userDAO.getUserByName(userName);<br />  if (user == null) {<br />   log.error("The user was not found:" + userName);<br />   throw new UsernameNotFoundException("The user was not found:" + userName);<br />  }<br />  return user;<br /> }</p> <p>}<br /><br />注意user必须实现<font color="#006400">Serializable, UserDetails</font><br /></p><img src ="http://www.tkk7.com/rain1102/aggbug/107142.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/rain1102/" target="_blank">周锐</a> 2007-03-29 10:32 <a href="http://www.tkk7.com/rain1102/archive/2007/03/29/107142.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://1314c.com" target="_blank">ӰӾ߹ۿȫ</a>| <a href="http://xianzijie.com" target="_blank">ۺϼ¶</a>| <a href="http://guakao88.com" target="_blank">߹ۿ</a>| <a href="http://www-566846.com" target="_blank">߲ŸԲ </a>| <a href="http://sx97zc.com" target="_blank">߹ۿ˳Ƶ</a>| <a href="http://lyczyb.com" target="_blank">߹ۿһ</a>| <a href="http://918989b.com" target="_blank">67paoǿ</a>| <a href="http://selangcun.com" target="_blank">޾ƷҹƵ</a>| <a href="http://am33318.com" target="_blank">㻨ѸƵ</a>| <a href="http://djqq520.com" target="_blank">պ޹Ƶ</a>| <a href="http://rr7733.com" target="_blank">ձѹۿվ</a>| <a href="http://mangshigas.com" target="_blank">ܲƵ</a>| <a href="http://ydstbj.com" target="_blank">Ʒmnbavվ</a>| <a href="http://lyjhjx.com" target="_blank">99Ƶѹۿ</a>| <a href="http://xyjxnhcl.com" target="_blank">޳߹ۿ</a>| <a href="http://4438xa48.com" target="_blank">AëƬA</a>| <a href="http://48eh.com" target="_blank">avƬþ</a>| <a href="http://xamxx.com" target="_blank">ַѹۿ </a>| <a href="http://8mav958.com" target="_blank">˾Ʒþ</a>| <a href="http://vinsotec.com" target="_blank">Ƶ㶮</a>| <a href="http://hs718.com" target="_blank">޳ɫwwwþվҹ</a>| <a href="http://douhuowang.com" target="_blank">þ99Ʒѿ</a>| <a href="http://www678678.com" target="_blank">ѻɫַ</a>| <a href="http://wo93xyz.com" target="_blank">ѿƬ</a>| <a href="http://baizhengsh.com" target="_blank">һƬѿ</a>| <a href="http://lshwork.com" target="_blank">޾Ʒѹۿ</a>| <a href="http://zuahowan.com" target="_blank">ˬָ߳ëƬ</a>| <a href="http://fenglufzjx.com" target="_blank">վɫƵѿ½</a>| <a href="http://sczxzt.com" target="_blank">av޹av</a>| <a href="http://shlamore.com" target="_blank">˸ӰԺѿ</a>| <a href="http://820111com.com" target="_blank">޳AVƬWWW</a>| <a href="http://wwwfac37.com" target="_blank">޾Ʒרþþ</a>| <a href="http://aierphoto.com" target="_blank">AVһ</a>| <a href="http://wxyz2.com" target="_blank">ŮɫëƬѿ</a>| <a href="http://yidazn.com" target="_blank">þþƷ㽶</a>| <a href="http://vo168.com" target="_blank">վɫѿ </a>| <a href="http://wwwbi757.com" target="_blank">ŮպѲ</a>| <a href="http://otkaxap.com" target="_blank">Ļþ2020</a>| <a href="http://dxj588.com" target="_blank">һƵ߲</a>| <a href="http://hezuoedu.com" target="_blank">ѿƬ߹ۿ</a>| <a href="http://yzddcpj.com" target="_blank">һػ¼Ѳİ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>