[ETC] DWR 2.0 and Spring 2.x - The DWR namespace handler

황제낙엽 2009.05.16 17:28 조회 수 : 124 추천:119

sitelink1  
sitelink2  
sitelink3 http://1 
extra_vars4 ko 
extra_vars5 http://directwebremoting.org/dwr/server/spring 
extra_vars6 sitelink1 

DWR and Spring

Initial considerations

  1. DWR 3 requires Spring version 2.5 or greater. Make sure you have the appropriate version of Spring.
  2. Make sure you are happy with everything on the getting started page.
  3. Make sure your Spring beans work properly outside of DWR (unit test).
  4. Select the configuration style based on your Spring version (see below).
  5. Configure DWR to work with Spring (see below).
  6. Look at the demo pages: http://localhost:[PORT]/[YOUR-WEBAPP]/dwr/index.htmlto check that your spring beans appear.

Step 1 - Give DWR access to the Spring context

In order to integrate DWR with Spring, DWR needs to gain access to the Spring context. There are two options here:

  1. Use Spring MVC
  2. Use the DWRSpringServlet

Use Spring MVC

If you are using Spring MVC your web.xml should look something like this:

<servlet>
  <servlet-name>springDispatcher</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value> classpath:yourSpringContext.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>springDispatcher</servlet-name>
  <url-pattern>*.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
  <servlet-name>springDispatcher</servlet-name>
  <url-pattern>/dwr/*</url-pattern>
</servlet-mapping>

The only thing you need to add is the mapping of /dwr/* to the Spring dispatcher servlet. A complete working example of this configuration can be found here.

Use the DWRSpringServlet

The DwrSpringServlet can be used if you are not using Spring MVC. This servlet gains access to the Spring context configured in your web.xml. Necessary web.xml configuration:

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
    classpath:yourSpringContext.xml
  </param-value>
</context-param>
<servlet>
  <servlet-name>dwr</servlet-name>
  <servlet-class>org.directwebremoting.spring.DwrSpringServlet</servlet-class>
  <init-param>
    <param-name>debug</param-name>
    <param-value>true</param-value>
  </init-param>
</servlet>
<servlet-mapping>
  <servlet-name>dwr</servlet-name>
  <url-pattern>/dwr/*</url-pattern>
</servlet-mapping>

A complete working example of this configuration can be found here.

Step 2 - Configure DWR's remoting

The next and final step is to configure DWR's remoting - once again there are several options. In the past (3 below) this step was accomplished in the dwr.xml via Creators and Converters. However, Spring 2.x introduced a new feature named XML Namespace Handlers. This allows DWR and Spring MVC to remote Spring beans easily with a custom syntax and removes the need for dwr.xml. Configuration for the custom namespace is covered in 1 and 2 below.

  1. Use the DWR/Spring namespace (Spring 2.5 or greater, DWR 2.x or greater, dwr.xml not required or recommended)
  2. Use the DWR/Spring namespace with annotations (Spring 2.5 or greater, DWR 2.x or greater, dwr.xml not required or recommended)
  3. Use the DWRSpringServlet (Will work for older versions of Spring or DWR - dwr.xml required. Not the recommended approach.)

The namespace

The first task you need to accomplish is adding the following lines (in bold, below) to any of your Spring XML files that includes at least one DWR specific tag. Add them inside the beansdeclaration (at the beginning of the file):

<beans
  xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.directwebremoting.org/schema/spring-dwr
    http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd">

The controller tag

If you are not using Spring MVC - skip this section. The controller tag only applies to Spring MVC configurations.

If you are using Spring MVC you must declare one <dwr:controller id="dwrController" debug="true" /> tag. This tag does not allow inner tags and the id attribute is optional.

In Spring MVC, for each controller you have to map the URLs that it will handle. The simplest way to do this is by using the <dwr:url-mapping /> tag. If you use the url-mapping tag the DWR test page will be unavailable.

Alternatively, you may specify your own SimpleUrlHandlerMapping. DWR needs mappings for the following URLs: /engine.js, /interface.js, /call/**, /interface/**. An example of a SimpleUrlHandlerMapping that will allow the DWR test page to work can be found here (see step 2, numbered item 3).

The configuration tag

The <dwr:configuration/> is used to mimic the behavior of the configuration available indwr.xml. This tag is optional and it may have nested tags (init, creator, signatures,..). These nested tags mimic the behavior of those available in dwr.xml. Example:

  <dwr:configuration>
    <dwr:convert type="bean" class="org.uk.ltd.dwr.dev.model.Address" />
  </dwr:configuration>

The remote tag

Inside each bean you want to remote include a <dwr:remote javascript="Fred"> tag. There you can specify the methods that are going to be proxied and those that won't. For example:

<bean id="timeConvert" class="com.mycompany.ui.util.TimeConvert">
  <dwr:remote javascript="AjaxTimeConvert">
    <dwr:include method="convert" />
  </dwr:remote>
</bean>

Exposing beans in other application contexts - the proxy-ref element

It is also possible to remote a bean already defined in a reachable application context indicating the reference to it by using the proxy-ref element.

Two complete (one with Spring MVC, one without) working examples of DWR and Spring using the namespace can be found here.

The namespace with Annotations

Please see The namespace before reading this section. Several of the namespace sections apply to annotation configuration as well.

If you would like to use annotations to remote your Spring beans DWR provides two tags that make it easy.

  1. annotation-scan - Enables DWR to scan the classpath, detect beans annotated with @RemoteProxy & @RemoteMethod and register the beans and Creator proxies for them. This element has several available attributes:
    • base-package - The base package to initiate scanning from - i.e. com.myApp.*.
    • regex - A regular expression that will be used in the classpath scanner.
    • scanRemoteProxy - Should DWR scan for remote proxies? Defaults to true.
    • scanDataTransferObject - Should DWR scan for converters? Defaults to true.
    • scanGlobalFilter - Defaults to true.
  2. annotation-config - Enables DWR to scan the Spring context, detect beans annotated with @RemoteProxy & @RemoteMethod and register Creator proxies for them.

A complete working example of this configuration can be found here.

The Spring Creator and dwr.xml

If you feel comfortable using dwr.xml you may use the Spring creator. This creator will lookup beans in your Spring <beans>.xml file and rely on Spring to instantiate them. This creator will be useful to you if you already use Spring and totally useless if you don't.

You allow DWR to use the spring creator to create and remote your beans as follows:

<allow>
  ...
  <create creator="spring" javascript="Fred">
    <param name="beanName" value="Shiela"/>
  </create>
  ...
</allow>

There are several ways to find your spring configuration files:

  • Spring MVC

    Define a DispatcherServlet and declare the beans in <dispatcher>-servlet.xml. There are no specifics for DWR remoted beans.
  • ContextLoaderListener

    For other MVC frameworks.
  • Using location* parameters

    If you prefer to specify which beans.xml to use in your dwr.xml file then you can use a location* parameter. You can specify as many as you wish although the names must be unique and start 'location'. For example: location-1, location-2. These locations are used as parameters to a Spring ClassPathXmlApplicationContext:
    <allow>
      ...
      <create creator="spring" javascript="Fred">
        <param name="beanName" value="Shiela"/>
        <param name=location value="beans.xml"/>
      </create>
      ...
    </allow>
    
  • Setting the BeanFactory directly

    The SpringCreator has a static setOverrideBeanFactory(BeanFactory) method that provides a way to programatically override any BeanFactories found by other means (if any).

Please, take into account that not all methods are equally easy in practice. Probably, unless you know what you're doing you're better served using one of the first two.

Common Problems

Scoped Beans

One of the common pitfalls when integrating Spring and DWR are scoped beans (session, request, ...). In practice is easy to get them going, just remember two basic rules.

  • Always declare and implement an interface with the remoted methods.
  • Remember to include <aop:scoped-proxy proxy-target-class="false" /> in the bean declaration

Here's an example:

<bean id="calc" class="...CalculatorImpl" scope=session>
  <dwr:remote javascript="Calculator">
    <dwr:include method="add"/>
  </dwr:remote>
  <aop:scoped-proxy proxy-target-class="false" />
</bean>

Aspects & DWR

If you're receiving the dreaded object is not an instance of declaring class error always check the following:

  • You have an interface and an implementation
  • You have declared <aop:aspectj-autoproxy proxy-target-class="false" />in your Spring XML
  • You have decorated your remoted bean with <aop:scoped-proxy />
In fact, AOP proxies work fine with DWR. Just configure Spring accordingly.

Mappings! Mappings! Mappings!

It is important to note that the creation of the SimpleUrlHandlerMapping may cause your existing mappings to fail if you have not explicitly created a Handler Mapping in your Spring configuration. By default Spring creates a BeanNameUrlHandlerMapping if you have not explicitly created a Handler Mapping. So when the SimpleUrlHandlerMapping is created for DWR, Spring will no longer create the default BeanNameUrlHandlerMapping and existing mappings will not work. Spring allows you to have multiple Handler Mappings, to fix this you need to create a BeanNameUrlHandlerMapping explicitly in your spring.xml (in addition to the SimpleUrlHandlerMapping). See the Spring documentation section 13.4.1 for more information.

Id is required for element 'annotation-config' when used as a top-level tag

This appears to be happening with Spring 3.x and above. We use a Spring class to parse the annotation-config element and if you do not specify an id the parse is unhappy. For now a solution to this appears to be simply adding an id attribute.

번호 제목 글쓴이 날짜 조회 수
81 마우스 드래그(drag)시 iframe 위에서 컨트롤 잃는 현상과 해결 방안 황제낙엽 2017.12.12 18478
80 매우 간단한 AJAX 예제 - prototype.js 이용 (JSP) 황제낙엽 2007.08.24 7497
79 [re] XML+JS 연동 다중셀렉트박스 (2) - [AJAX] <font color="brown">(MS Explorer 전용)</brown> 황제낙엽 2006.02.22 1559
78 Redux: React 앱의 효율적인 데이터 교류 file 황제낙엽 2020.05.19 740
77 json을 이용한 로그인 구현 file 황제낙엽 2011.03.25 601
76 How Prototype extends the DOM (Prototype으로 DOM을 확장하는 법) 황제낙엽 2011.03.24 444
75 $.ajax() 공략 file 황제낙엽 2011.03.27 415
74 Dojo로 HTML 위젯 개발하기 - Dojo HTML 위젯 황제낙엽 2009.03.18 363
73 Building Your Own Widget Library with YUI 황제낙엽 2009.04.16 321
72 15+ jQuery Popup Modal Dialog Plugins and Tutorials 황제낙엽 2011.03.30 280
71 XML+JS 연동 다중셀렉트박스 (1) - [AJAX] <font color="brown">(MS Explorer 전용)</brown> 황제낙엽 2005.12.02 241
70 Jasmine 관련 황제낙엽 2020.01.13 240
69 다섯 가지의 Ajax 우수 사례 황제낙엽 2011.04.07 219
68 Spring에서 DWR Annotation 사용하기 file 황제낙엽 2009.10.28 151
67 [펌] 6. DOJO AND JSON file 황제낙엽 2009.03.11 137
66 Ajax 관련 사이트 정리 황제낙엽 2006.04.20 132
65 웹 개발 패러다임의 전환 - Flex와 Ajax의 동거 황제낙엽 2006.12.21 125
64 XML+JS 연동 다중셀렉트박스 (1) - [AJAX] <font color="brown">(MS Explorer 전용)</brown> 황제낙엽 2005.12.02 125
» DWR 2.0 and Spring 2.x - The DWR namespace handler 황제낙엽 2009.05.16 124
62 관심 사이트 황제낙엽 2009.03.12 116