Ajax Practice DWR Article _ajax related

Source: Internet
Author: User
Tags reflection stringbuffer
DWR (Direct Web Remoting) is a Web remote call framework. Leveraging this framework makes it easy to develop Ajax. Using DWR, you can use JavaScript directly to invoke the Java method on the server side and return the value to JavaScript as if it were a direct local client invocation ( DWR dynamically generates JAVASCRIP code based on Java classes). Its latest version DWR0.6 add a number of features such as support for DOM trees Autoconfiguration, support for spring (JavaScript remote invoke Spring bean), better browser support, An optional commons-logging journaling operation is also supported.

The above excerpt from Open-open, looked at for a few days, is indeed a very good project, it translates Java into JavaScript through reflection, and then uses the callback mechanism to easily implement JavaScript invoke Java code.

The approximate development process is as follows:
1. Write the code for the business, which is unrelated to DWR.
2. Identify which classes in the business code and which methods are to be accessed directly by JavaScript.
3. Write the DWR component and encapsulate the method of step 2.
4. Configure the DWR component into the Dwr.xml file and, if necessary, configure convert for Java and JavaScript types to go with each other.
5. Through the reflection mechanism, DWR converts the class of step 4 into JavaScript code, which is provided to the foreground page call.
5. Write Web pages, call the relevant methods in step 5 JavaScript (indirectly invoke the method of the server-side related classes), execute the business logic, and return the execution results using the callback function.
6. In the callback function, you can continue to write the relevant JavaScript code for the business logic after you have executed the results.

The following is an example of user registration to illustrate its use. (Note that this example is only for demonstration purposes, illustrating the use of DWR, class design is not optimal).

1. First introduce the relevant Java classes

User: Users class,
public class User {
Login ID, primary key unique
Private String ID;
Name
private String name;
Password
private String password;
Email
Private String Email;

The following include GetXXX and Setxxx methods
.......
}

Userdao: Implement user database access, here as a demo, write test code
public class Userdao {
Storing the saved data
private static Map Datamap = new HashMap ();

Persistent users
Public boolean save (user user) {
if (Datamap.containskey (User.getid ()))
return false;
System.out.println ("Save user Below");
SYSTEM.OUT.PRINTLN ("ID:" +user.getid ());
System.out.println ("Password:" +user.getpassword ());
System.out.println ("Name:" +user.getname ());
System.out.println ("Email:" +user.getemail ());
Datamap.put (User.getid (), user);
System.out.println ("User Save End");
return true;
}

Find Users
Public User find (String ID) {
Return (User) datamap.get (ID);
}
}

Dwruseraccess:dwr component that is provided to JavaScript for access.

public class Dwruseraccess {

Userdao Userdao = new Userdao ();

Public boolean save (user user) {
return Userdao.save (user);
}

Public User find (String ID) {
return Userdao.find (ID);
}
}


The procedures that are executed by the program below are described below

1. Users enter the relevant registration information on the page, ID, name, password, email, click the "Submit" button
2.javascript code to start execution, according to the user fill in the relevant information, through the DWR provided by the Dwruseraccess.js Save method, call the server-side Dwruseraccess class Save method, the registration information to save.
3. Through the Find method in dwruseraccess.jsp, call the server-side Dwruseraccess class found method, perform user information lookup.

Note that during the execution of the above, Dwruseraccess is for DWR calls and is the DWR component, so the Dwruseraccess class needs to be configured into DWR.

Next, explain the configuration of the DWR test environment.

1. Create a new WebApp, named TestApp
2. Copy Dwr.jar to TestApp's Web-inf Lib directory
3. Compile the User,userdao,dwruseraccess class above and place it in the classes directory
4. Configure the servlet in Web.xml, the appropriate path to the DWR directory, as shown below
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<display-name>dwr servlet</display-name>
<description>direct Web remoter servlet</description>
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>scriptCompressed</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>

The above configuration can intercept all the requests to dwr under TestApp, and we will introduce them later in this interceptor.

Under 5.web-inf, create a new Dwr.xml file that reads as follows:
<?xml version= "1.0" encoding= "UTF-8"?>
<! DOCTYPE dwr Public "-//getahead limited//dtd Direct Web Remoting 1.0//en" "Http://www.getahead.ltd.uk/dwr/dwr10.dtd" >

<dwr>
<allow>
<create creator= "new" javascript= "dwruseraccess" >
<param name= "class" value= "test. Dwruseraccess "/>
</create>
<convert converter= "Bean" match= "test. User "/>
</allow>
</dwr>

Here we configure the dwruseraccess to the DWR, in the Create element, creater= "new" means that each time a dwruseraccess is invoked, a new class is required; javascript= "Dwruseraccess" , which indicates that the Javascirpt file provided to the front page call is dwruseraccess.js.

The convert element is used for data type conversions, that is, between Java classes and JavaScript, because the user object is exchanged with the foreground, so you need to use a bean conversion for this, and we'll introduce that class later.

4. Write the test HTML page test.html
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 transitional//en" >
<HTML>
<HEAD>
<title>dwr Test </TITLE>
<meta http-equiv=content-type content= "text/html; charset=gb2312 ">
<script src= "/oblog312/dwr/engine.js" ></script>
<script src= "/oblog312/dwr/util.js" ></script>
<script src= "/oblog312/dwr/interface/dwruseraccess.js" ></script>
</HEAD>
<BODY>
<B> User Registration </B><br>
------------------------------------------------
<Br>
<form name= "RegForm" >
Login Id:<input type= "text" name= "id" ><br>
Password: <input type= "password" name= "password" ><br>
Name: <input type= "text" name= "name" ><br>
E-mail: <input type= "text" name= "email" ><br>
<input type= "button" Name= "Submitbtn" value= "Submit" onclick= "OnSave ()" ><br>
</form>

<br>
<br><B> User Inquiries </B><br>
------------------------------------------------
<Br>
<form name= "Queryform" >
Login Id:<input type= "text" name= "id" ><br>
<input type= "button" Name= "Submitbtn" value= "Submit" onclick= "Onfind ()" ><br>
</form>
<br>
</BODY>
</HTML>
<script language= "JavaScript" >
<!--
function Savefun (data) {
if (data) {
Alert ("Registered successfully!") ");
} else {
Alert ("Login ID already exists!") ");
}
}

function OnSave () {
var userMap = {};
Usermap.id = RegForm.id.value;
Usermap.password = RegForm.password.value;
Usermap.name = RegForm.name.value;
Usermap.email = RegForm.email.value;
Dwruseraccess.save (UserMap, Savefun);
}

function Findfun (data) {
if (data = = NULL) {
Alert ("Unable to find User:" +queryform.id.value);
Return
}

Alert ("Find the user, \nid:" +data.id+ ", \npassword:" +data.password+ ", \nname:" +data.name+ ", \nemail:" +data.email); "

}

function Onfind () {
Dwruseraccess.find (QueryForm.id.value, Findfun);
}
-->
</SCRIPT>


The following explains the JavaScript of the page

<script src= "/oblog312/dwr/engine.js" ></script>
<script src= "/oblog312/dwr/util.js" ></script>
These two are provided by DWR, users can not care about, only need to import can

<script src= "/oblog312/dwr/interface/dwruseraccess.js" ></script>
Is the Dwruseraccess class we write, the JavaScript code generated after DWR reflection, It and Dwruseraccess.java is corresponding, for the user to call, in fact, we are through this JS file to invoke server-side dwruseraccess class.

<script language= "JavaScript" >
<!--
function Savefun (data) {
if (data) {
Alert ("Registered successfully!") ");
} else {
Alert ("User name already exists!") ");
}
}

function OnSave () {
var userMap = {};
Usermap.id = RegForm.id.value;
Usermap.password = RegForm.password.value;
Usermap.name = RegForm.name.value;
Usermap.email = RegForm.email.value;
Dwruseraccess.save (UserMap, Savefun);
}

function Findfun (data) {
if (data = = NULL) {
Alert ("Unable to find User:" +queryform.id.value);
Return
}

Alert ("Find the user, \nid:" +data.id+ ", \npassword:" +data.password+ ", \nname:" +data.name+ ", \nemail:" +data.email); "

}

function Onfind () {
Dwruseraccess.find (QueryForm.id.value, Findfun);
}
-->
</SCRIPT>

For this javascirpt code, let's look at the OnSave function, which first constructs a map, sets the form data to the map, and then calls Dwruseraccess.save (UserMap, Savefun) to perform the save operation. You can note that the Save method in the server-side dwruseraccess is this: Boolean save (user user), whose argument is a user object, returns a Boolean value, and the client's method is this: Save ( Usermap,savefun), the first parameter userMap is the map object in Javascirpt, which is equivalent to the server-side user object (converted to the user object by convert when executed on the server side). We mentioned earlier that DWR uses a callback function to return the execution result, and the second parameter savefun is a callback function. In function Savefun (data), data is the execution result, here is a bool value, very simple, we can know whether the user name is duplicated and whether the user is registered successfully by judging whether the data is true or not.

Look at the Onfind lookup function, the execution result is in the callback function Findfun (data) because the server side returns a user object, which, by convert, converts to a map object of JavaScript
So in Findfun, we can easily access this user object through Data.id, Data.name, Data.password, Data.email.


All right, configure it, start the server, and enter localhost/testapp/test.html in the directory.

1. In the "User Registration" form, in the ID box input Admin,password input in the 123456,name input chenbug,email input chenbug@zj.com, click the Submit button, pop-up dialog: "Registration Success", The information in the server background can be seen as follows:

The following starts saving the user
Id:admin
password:123456
Name:chenbug
Email:chenbug@zj.com
End of user Save

Click the Submit button again and the pop-up dialog "login ID already exists".

2. In the "User Query" dialog box, enter the login ID for admin, click the Submit button, prompted to find the user, and display relevant information, input admin123, click the Submit button, prompted unable to find users.

So far, the test is over.


Subsequent:
1. Interceptor Uk.ltd.getahead.dwr.DWRServlet
This class intercepts all requests to the DWR directory and calls the processor handler method for processing, under Uk.ltd.getahead.dwr.impl.DefaultProcessor, we can see the detailed process.
if (pathinfo.length () = = 0 | |
Pathinfo.equals (htmlconstants.path_root) | |
Pathinfo.equals (Req.getcontextpath ()))
{
Resp.sendredirect (Req.getcontextpath () + Servletpath + htmlconstants.file_index);
}
else if (Pathinfo.startswith (Htmlconstants.file_index))
{
Index.handle (req, resp);
}
else if (Pathinfo.startswith (htmlconstants.path_test))
{
Test.handle (req, resp);
}
else if (Pathinfo.startswith (htmlconstants.path_interface))
{
Iface.handle (req, resp);
}
else if (Pathinfo.startswith (htmlconstants.path_exec))
{
Exec.handle (req, resp);
}
else if (Pathinfo.equalsignorecase (Htmlconstants.file_engine))
{
File.dofile (req, resp, htmlconstants.file_engine, HTMLCONSTANTS.MIME_JS);
}
else if (Pathinfo.equalsignorecase (Htmlconstants.file_util))
{
File.dofile (req, resp, Htmlconstants.file_util, HTMLCONSTANTS.MIME_JS);
}
else if (Pathinfo.equalsignorecase (htmlconstants.file_deprecated))
{
File.dofile (req, resp, htmlconstants.file_deprecated, HTMLCONSTANTS.MIME_JS);
}
Else
{
Log.warn ("Page Not Found" ("+ PathInfo +"). In debug/test mode try viewing/[web-app]/dwr/"); $NON-nls-1$//$NON-nls-2$
Resp.senderror (Httpservletresponse.sc_not_found);
}

By judging the servlet path for request requests, you can refer to it yourself, not discussed in detail here.


2.bean Converter, <convert converter= "Bean" match= "test. User "/>
The Dwr.jar is decompressed, and the Dwr.xml is seen under the path Uk\ltd\getahead\dwr, and some of the system's default converters are configured,
<converter id= "Bean" class= "uk.ltd.getahead.dwr.convert.BeanConverter"/> That is the converter that you just used to use the user class, Enter the code to see how it translates between JavaScript and java.

Open the Beanconverter code and navigate to the function

Public Object Convertinbound (Class paramtype, inboundvariable IV, Inboundcontext inctx) throws Conversionexception

That is, converting a JavaScript object into a Java object, where
Paramtype is the class type, in the example above is test. User,
Inboundvariable IV, which is the passed-in value, can get the passed-in JavaScript value string via Iv.getvalue
Inboundcontext Inctx is the entry parameter context that is used to save the converted post-Java object.

Because the foreground is passing in a JavaScript map type, and the map must end with {beginning and ending with}, the function is judged at the beginning.
if (!value.startswith (Conversionconstants.inbound_map_start))
{
throw new IllegalArgumentException (messages.getstring ("Beanconverter.missingopener", Conversionconstants.inbound_ Map_start)); $NON-nls-1$
}

if (!value.endswith (conversionconstants.inbound_map_end))
{
throw new IllegalArgumentException (messages.getstring ("Beanconverter.missingcloser", Conversionconstants.inbound_ Map_start)); $NON-nls-1$
}

In JavaScript, the items in a map are connected by commas, such as var userMap = {id: ' admin ', Password: ' 123456 ', Name: ' Chenbug ', email: ' Chenbug@zj.com '}; The key value pairs for each item are connected by a colon,
In the next processing of the Convertinbound function, it is by parsing the map string, constructing the Java instance (the user Class) by Paramtype, and then by reflection, setting the pair of key values to the Java instance and returning.
This completes the JavaScript to Java conversion.


Another function
Public String Convertoutbound (Object data, String varname, Outboundcontext outctx) throws Conversionexception

That is, converting Java objects to JavaScript objects (in fact, declarations and assignment statements).
Object data, Java object to be converted
String varname, is the variable name of the object in JavaScript
Outboundcontext outctx, outgoing parameter context, for saving converted JavaScript values

StringBuffer buffer = new StringBuffer ();
Buffer.append ("Var"); $NON-nls-1$
Buffer.append (varname);
Buffer.append ("={};"); $NON-nls-1$
This declares a variable of the map type.

The code that comes down is the variable assignment by reflection, as follows
Buffer.append (varname);
Buffer.append ('. ');
Buffer.append (name);
Buffer.append (' = ');
Buffer.append (Nested.getassigncode ());
Buffer.append (';');
You can see more code for yourself.

3.DWR itself provides a test environment, after the configuration, you can enter the address http://localhost/testApp/dwr/index.html in IE, see the configuration of the DWR components, and related testing.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.