Tuesday, December 7, 2010
Excluding xerces/xercesImpl from your CXF project
The only difference was to include a new dependency which has more business logic.
Then comparing my last CXF project lib folder with my new one, I found xercesImpl*.jar was additional to my current project.
I just removed from my POM (added as exclusion from my new dependency) and Listo! my CXF Web Service is working as expected :D
Thursday, December 2, 2010
Quest Toad on Oracle 11g not supported
Nevertheless, this post is to warn all developers out there using Quest TOAD for Oracle.
The current release of TOAD is 9.1, this version is not supported with Oracle 11g (client). But even more important, the version that comes out half of November, TOAD 9.5 (see screenshot below which is a beta), isn't working with the Oracle 11g client neither!
And looking around I found this message coming from Quest: Unfortunately, it was confirmed by our team's technical lead that Toad version 9.5 only support Oracle server 11g and not Oracle client 11g. My only suggestion for you is to install another client on your machine that is 10gR2 version or lower."
It's hard to believe that you need to install an Oracle Server just to get your development environment (TOAD) running ;-) Nevertheless, a workaround is to install Oracle 10g client, which I don't want to do as I'm connecting to 11g databases.
Or go for SQL Developer, a free alternative of Oracle.
A screenshot of the error "OCI version 11.1.0.1.0 is not supported"
I'm using both SQL Developer and TOAD as I think both have strengths and points to improve.
This post isn't to favor for SQL Developer, it's just to warn you.
Thursday, November 11, 2010
Conditions in One Line
Wednesday, October 27, 2010
My first official LEFT JOIN
Tuesday, October 26, 2010
Add new parameter to Stored Procedure without impacting existing call
Add another parameter to my SP to handle the transaction or not, but If I do this the signature (DDL) of my SP is going to change!
There is one way to do this, something like adding polymorphism, on this case overload SP.
This is my original SP: On my iBatis side I'm calling this SP with this number of Params (5), If I add a new param, I'll have to add a new one to my DDL, right?
Not necessarily, because If you add another parameter but you don't declare it as IN neither OUT, it will be optional!!!
Then I can do this: And nobody will notice that I change it, because you can call it with 5 params (The 6th param will be given by default in the signature: DEFAULT 1) or with 6 (assigning 0 for example to the 6th parameter)
Inside the body of my SP I'm doing something like this:
Set Timeout when accessing Oracle with iBatis
There is a call which takes too much time, we don't want to wait until it's done, so in this case we can timeout our transaction and kill it on the Oracle side (well we don't kill/stop anything, we just abandon the process without any adverse impact);
Then we'll receive something like this from the DB:
ORA-01013: user requested cancel of current operationHow do you do that??
According to iBatis documentation, we can do it globally or for each statement/call we make by changing the value of defaultStatementTimeout
defaultStatementTimeout This setting is an integer value that will be applied as the JDBC query timeout for all statements. This value can be overridden with the “statement” attribute of any mapped statement. If not specified, no query timeout will be set unless specified on the “statement” attribute of a mapped statement. The specified value is the number of seconds the driver will wait for a statement to finish. Note that not all drivers support this setting.
Or we can do it Specifically for each statement element by setting the attribute timeout, for example:
Thursday, October 14, 2010
Create List of STRUCT based on a Query
In Oracle to create a new instance of this kind of object, the default Contructor is given by definition of the object, for example in this case to create a new instance of CUST_ACCNT_MTN_PRE_ORDER, my contructor will be something like this
And this is my Collection/List/Table of Objects
My SP is something like this (As you'll see I'm using the same objects I defined in that entry)
And my solution is something like this
The secret is in this line: SELECT CUST_ACCNT_MTN_PRE_ORDER(CUST_ID, ACCT_NUM, NPA || NXX || TLN, -1, 'X', MTN_ORDER_TYPE, SYSDATE, NVL(EO_ALT_NPA||EO_ALT_NXX||EO_ALT_TLN,0)) BULK COLLECT INTO p_list
I'm creating for each row an object of type CUST_ACCNT_MTN_PRE_ORDER and then the ResultSet is set INTO p_list variable using BULK COLLECT, which fetch all rows once
IF you want to see my Stored Proc, this is what I did
CREATE OR REPLACE PROCEDURE record_ship_temp_orders( out_orders_processed OUT NUMBER ) IS my_cust_id CUST_ACCT_ORDER.cust_id%TYPE; my_acct_num CUST_ACCT_ORDER.acct_num%TYPE; my_pos_order_id CUST_ACCT_ORDER.pos_order_id%TYPE; my_pos_pre_order_id CUST_ACCT_ORDER.pos_pre_order_id%TYPE; my_pos_loc_cd CUST_ACCT_ORDER.pos_loc_cd%TYPE; my_total_order_lines CUST_ACCT_ORDER.total_order_lines%TYPE; my_ord_add_lines_cnt CUST_ACCT_ORDER.add_lines_cnt%TYPE; my_ord_upg_lines_cnt CUST_ACCT_ORDER.upg_lines_cnt%TYPE; p_list CUST_ACCNT_MTN_PRE_ORDER_LIST; OUT_CIDB_ORDER_ID NUMBER; --This is the main cursor CURSOR cur_test_init_load IS SELECT CUST_ID_NO AS CUST_ID, ACCT_NO AS ACCT_NUM, EQ_ORD_NO AS POS_ORDER_ID, NULL AS POS_PRE_ORDER_ID, NETACE_LOC_ID AS POS_LOC_CD FROM TEST_INIT_LOAD GROUP BY CUST_ID_NO, ACCT_NO, EQ_ORD_NO, NULL, NETACE_LOC_ID ORDER BY CUST_ID_NO, ACCT_NO, EQ_ORD_NO, NETACE_LOC_ID; /****************************************************************************** NAME: record_ship_temp_orders PURPOSE: Retrieve data loaded into TEST_INIT_LOAD to be processed by Record_Pre_Order and then shipped by Ship_Pre_Order. DATE: Oct 2010 Referenced by: To be executed internally ******************************************************************************/ BEGIN DBMS_OUTPUT.put_line('Starting prcess '||TO_CHAR(SYSTIMESTAMP,'hh:mi:ss.FF')); OPEN cur_test_init_load; IF cur_test_init_load%NOTFOUND THEN DBMS_OUTPUT.put_line('No data found on TEST_INIT_LOAD'); CLOSE cur_test_init_load; raise_application_error(-20102, 'No data found on TEST_INIT_LOAD'); END IF; out_orders_processed := cur_test_init_load%ROWCOUNT; --Before the first fetch, %ROWCOUNT returns 0 DBMS_OUTPUT.put_line('Start record '||TO_CHAR(SYSTIMESTAMP,'hh:mi:ss.FF')); LOOP --Iterate cursor FETCH cur_test_init_load INTO my_cust_id, my_acct_num, my_pos_order_id, my_pos_pre_order_id, my_pos_loc_cd; IF out_orders_processed = 0 THEN out_orders_processed := cur_test_init_load%ROWCOUNT; --Set a value to the OUT param END IF; EXIT WHEN cur_test_init_load%NOTFOUND;--Exits when process is completed DBMS_OUTPUT.put_line('Processing '||my_cust_id||'-'||my_acct_num||', my_pos_order_id='||my_pos_order_id||', my_pos_pre_order_id='||my_pos_pre_order_id||', my_pos_loc_cd='||my_pos_loc_cd); --Calculate total_order_lines, add_lines_cnt & upg_lines_cnt SELECT count(1) AS TOTAL_ODER_LINES INTO my_total_order_lines FROM TEST_INIT_LOAD WHERE CUST_ID_NO = my_cust_id AND ACCT_NO = my_acct_num AND EQ_ORD_NO = my_pos_order_id; SELECT count(1) AS ADD_LINES_CNT INTO my_ord_add_lines_cnt FROM TEST_INIT_LOAD WHERE CUST_ID_NO = my_cust_id AND ACCT_NO = my_acct_num AND EQ_ORD_NO = my_pos_order_id AND ESN_CHG_RSN_CD IS NULL; SELECT count(1) AS UPG_LINES_CNT INTO my_ord_upg_lines_cnt FROM TEST_INIT_LOAD WHERE CUST_ID_NO = my_cust_id AND ACCT_NO = my_acct_num AND EQ_ORD_NO = my_pos_order_id AND ESN_CHG_RSN_CD IS NOT NULL; DBMS_OUTPUT.put_line('my_total_order_lines '||my_total_order_lines||', my_ord_add_lines_cnt='||my_ord_add_lines_cnt||', my_ord_upg_lines_cnt='||my_ord_upg_lines_cnt); --Generate List of Items to be inserted into CUST_ACCT_MTN_ORDER SELECT CUST_ACCNT_MTN_PRE_ORDER(CUST_ID, ACCT_NUM, NPA || NXX || TLN, -1, 'X', MTN_ORDER_TYPE, SYSDATE, NVL(EO_ALT_NPA||EO_ALT_NXX||EO_ALT_TLN,0)) BULK COLLECT INTO p_list FROM ( SELECT CUST_ID_NO AS CUST_ID, ACCT_NO AS ACCT_NUM, NPA , NXX , TLN, NVL(ESN_CHG_RSN_CD,'A') AS MTN_ORDER_TYPE, EO_ALT_NPA,EO_ALT_NXX,EO_ALT_TLN FROM TEST_INIT_LOAD WHERE CUST_ID_NO = my_cust_id AND ACCT_NO = my_acct_num AND EQ_ORD_NO = my_pos_order_id AND ESN_CHG_RSN_CD IS NULL UNION SELECT CUST_ID_NO AS CUST_ID, ACCT_NO AS ACCT_NUM, NPA , NXX , TLN, 'U' AS MTN_ORDER_TYPE, EO_ALT_NPA,EO_ALT_NXX,EO_ALT_TLN FROM TEST_INIT_LOAD WHERE CUST_ID_NO = my_cust_id AND ACCT_NO = my_acct_num AND EQ_ORD_NO = my_pos_order_id AND ESN_CHG_RSN_CD IS NOT NULL ); FOR i in 1 .. p_list.count LOOP DBMS_OUTPUT.put_line ('STRUCT '||i||'=> mtn='||p_list(i).mtn||', mtn_order_type='||p_list(i).mtn_order_type||', bdy_mtn='||p_list(i).bdy_mtn); END LOOP; --Call SP's BEGIN DBMS_OUTPUT.put_line('Calling Record_Pre_Order'); RECORD_PRE_ORDER ( my_cust_id, my_acct_num, my_pos_order_id, my_pos_pre_order_id, my_pos_loc_cd, my_total_order_lines, my_ord_add_lines_cnt, my_ord_upg_lines_cnt, 0, p_list, OUT_CIDB_ORDER_ID ); DBMS_OUTPUT.put_line('Calling Ship_Pre_Order'); SHIP_PRE_ORDER ( my_cust_id, my_acct_num, my_pos_order_id, my_pos_loc_cd, OUT_CIDB_ORDER_ID ); DBMS_OUTPUT.put_line('End record '||TO_CHAR(SYSTIMESTAMP,'hh:mi:ss.FF')); DBMS_OUTPUT.put_line('-------'); p_list := NULL; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.put_line ('***ERROR*** '||SQLERRM); out_orders_processed := out_orders_processed - 1; --Decrease failed orders END; END LOOP; DBMS_OUTPUT.put_line('Process completed'); DBMS_OUTPUT.put_line('End of process '||TO_CHAR(SYSTIMESTAMP,'hh:mi:ss.FF')); CLOSE cur_test_init_load; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.put_line (SQLERRM); ROLLBACK; RAISE; END; /
Friday, October 8, 2010
SQL Joins explained with Venn's Diagrams
Una simple ayuda
El lenguaje SQL es aveces el gran olvidado por los desarrolladores, cada vez abundan mas los frameworks que abstraen al desarrollador del contacto con el modelo de negocio.
He escrito este documento, basƔndome en otros similares para ayudar a entender con un diagrama de Vann, los diferentes tipos de Join's que SQL92 soporta.
Existen tecnologĆas que abstraen completamente del modelo de negocio, para el desarrollador funcionan creando una serie de clases de Dominio que define el modelo, sin importar quĆ© base de datos o de quĆ© fabricante sea esta. Por ejemplo Ruby on Rails, GRails, ... usando un conjunto de tecnologĆas, como Hibernate configuradas por convenciĆ³n dentro del propio framework.
TambiƩn es muy extendido el uso de aplicaciones que permiten modelar el negocio de forma grƔfica, ERM (como DBSchema), y normalmente despuƩs se usa un ORM's que les hacen el trabajo sucio de forma elegante y segura.
Todo vale, pero la realidad de las empresas TIC es que necesitan profesionales serios y conscientes que entiendan y controlen todas las capas para que un sistema funciona como se espera y estƔ diseƱado, y no se deje nada al azar.
El desarrollador, muy frecuentemente recurre a activar trazas o aplicaciones de monitorizaciĆ³n de actividad que nos desvelen, quĆ© estĆ” haciendo nuestro framework con nuestro modelo de negocio. Existen aplicaciones que esnifan directamente de la base de datos esta informaciĆ³n para que podamos analizarla, el obsoleto Profile y Analyzer que incluĆa Microsoft SQL Server es un ejemplo de ellos.
Finalmente cuando tenemos delante la query sucede que hace tanto tiempo que no trabajamos con SQL que no entendemos quƩ hace exactamente, sobre todo si estƔ trabajando con tablas relacionadas y nos encontramos con una consulta que afecta a varias entidades.
Espero que este documento ayude a reducir el tiempo invertido a descubrir porquƩ se comporta una SQL de un modo u otro.
ConvencionesEste documento asume que siempre que la "TABLA A" esta a la izquierda y la "TABLA B" a la derecha de las sentencias. Para los ejemplos vamos a utilizar 2 tablas que van a contener los siguientes datos:
|
|||||||||||||||||||||||||||||||||||||
INNER JOINSELECT * FROM TableA INNER JOIN TableB ON TableA.name = TableB.name
El resultado son solo el conjunto de registros que coinciden en ambas tablas. |
|||||||||||||||||||||||||||||||||||||
FULL OUTER JOINSELECT * FROM TableA FULL OUTER JOIN TableB ON TableA.name = TableB.name
El resultado es el conjunto total de registros de ambas tablas, coincidiendo aquellos registros cuando sea posible. Si no hay conicidencias, se asignan nulos. |
|||||||||||||||||||||||||||||||||||||
FULL OUTER JOIN WHERESELECT * FROM TableA FULL OUTER JOIN TableB ON TableA.name = TableB.name WHERE TableA.id IS null OR TableB.id IS null
El resultado es un conjunto de records Ćŗnicos en la TablaA y en la TablaB, hacemos el Full Outer Join y excluimos los registros que no queremos con el Where |
|||||||||||||||||||||||||||||||||||||
LEFT OUTER JOINSELECT * FROM TableA LEFT OUTER JOIN TableB ON TableA.name = TableB.name
El resultado son todos los registros de la TablaA, y si es posible las coincidencias de la TablaB. Si no hay coincidencias, el lado derecho mostrarĆ” nulos. |
|||||||||||||||||||||||||||||||||||||
LEFT OUTER JOIN WHERESELECT * FROM TableA LEFT OUTER JOIN TableB ON TableA.name = TableB.name WHERE TableB.id IS null
El resultado es un conjunto de registros que solo estƔn en la TablaA, no en la TablaB. Hacemos lo mismo que en un Left Outer Join, pero eliminamos los registros que no queremos de la TablaB con el Where |
|||||||||||||||||||||||||||||||||||||
CROSS JOINExiste tambiƩn la posibilidad de cruzar todos los registros con todos (producto cartesiano), imposible de dibujar con un diagramas VennSELECT * FROM TableA CROSS JOIN TableB Imaginarse el resultado de todos los registros por todos es muy fƔcil, si tenemos 4 registros en cada tabla 4 x 4 = 16. |
¡Ojo al hacer esto en tablas con muchos registros! |
Thursday, September 30, 2010
Validation Query on WebSphere DataSource
Monday, September 20, 2010
Pass Collection of Objects with Attributes to a Stored Procedure using iBatis
But now the problem becomes more complex, because, what happen if I'm expecting on my Stored Proc and Type (STRUCT)
This is my Collection in Oracle!
And this is my Stored Proc (this is just a sample which receives the TABLE of Records)
This is the table where I'm going to INSERT
Obviously, the solution is Create a Handler like I did on my last entry, but is not going to be as simple, because I need to Map my Oracle STRUCT with my Java Code, so I have to do an domain object (POJO) coupled to Oracle and my Handler.
Once we have our Mapper class, then let's do the Handler!!!
Friday, September 17, 2010
Pass Collection to Stored Procedure using iBatis
It sounds simple, Isn't it??? Ok, then try to do it with an Stored Procedure in Oracle :P
Then, this is my Stored Proc (I had to create a Type to have support for Arrays in Oracle, because an Array is not a simple-provided data type):
TYPE NUMBER_ARRAY AS TABLE OF NUMBER)
The solution to this problem is easier than it seems, just create a Handler dude!!!
Let's analyze this monster:
* Get Native Connection
*Create my ArrayDescriptor for my Type (these NUMBER_ARRAY is my TYPE I created previously)
*Create my parameter, an ARRAY (al fin y al cabo) and we're set!
Finally this is my mapping file for my stored procedure
And my code lived happily ever after!!! Abur!!!
Friday, September 10, 2010
JDBC url for oracle RAC
jdbc:oracle:thin:@<HOST>:1521:<SID>doesn’t work and you get the error ORA – 12505.
Instead, you must use this url:
jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=on)
(ADDRESS=(PROTOCOL=TCP)(HOST=host1) (PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=host2) (PORT=1521))
(CONNECT_DATA=(SERVICE_NAME=service)))
Wednesday, September 8, 2010
Log SQL Statements on Hibernate
There are two ways (due to the legacy of Hibernate) to enable SQL logging. The first is to simply enable SQL logging in the Hibernate configuration By setting the hibernate.show_sql to TRUE
This is a nice quick and dirty solution, but it is relatively inflexible. SQL statements are always logged to System.out when that property is enabled, and on some servers, System.out isn't accessible by the average developer; or is cluttered with a million other log statements.
Alternatively, Hibernate uses the Apache-Jakarta Commons Logging package, which means that it will utilize log4j , java.util.logging , or potentially another logging framework. Typically, log messages are sent to commons logging, and then they are dispatched to one of these logging frameworks. Then, those logging frameworks determine where the message should be sent (log files, sockets, emails, database records, system out, system err, etc). It is easy to see how using these log frameworks will increase the flexibility of log statements. With Hibernate, simply setting the org.hibernate.SQL logger to 'DEBUG' or 'ALL' will ensure that all SQL statements are logged to the console.
If you set up a log4j category for org.hibernate.type
Get it to write out to the same log file as the org.hibernate.SQL
The type one will list the parameters for you after the SQL e.g.
2006-07-28 09:57:12,061 DEBUG org.hibernate.SQL - insert into BASKET_LINE_ALLOC (LAST_UPDATED, QUANTITY, CUSTOMER_REF, NOTES, BRANCH_ID, FUND_ID, TEMPLATE_ID, BASKET_LINE_ALLOC_ID) values (?, ?, ?, ?, ?, ?, ?, ?) 2006-07-28 09:57:12,081 DEBUG org.hibernate.type.TimestampType - binding '2006-07-28 09:57:12' to parameter: 1 2006-07-28 09:57:12,081 DEBUG org.hibernate.type.IntegerType - binding '3' to parameter: 2 2006-07-28 09:57:12,082 DEBUG org.hibernate.type.StringType - binding '' to parameter: 3 2006-07-28 09:57:12,082 DEBUG org.hibernate.type.StringType - binding '' to parameter: 4 2006-07-28 09:57:12,082 DEBUG org.hibernate.type.LongType - binding '511' to parameter: 5 2006-07-28 09:57:12,082 DEBUG org.hibernate.type.LongType - binding '512' to parameter: 6 2006-07-28 09:57:12,082 DEBUG org.hibernate.type.LongType - binding null to parameter: 7 2006-07-28 09:57:12,082 DEBUG org.hibernate.type.LongType - binding '180030' to parameter: 8
@Autowired and @Qualifier
I have to migrate data from DB2 to Oracle, both databases have the same structure, well, my Oracle has better design, but I'm reusing the some objects, like POJO's and DAO's, the only thing I changed were my mappings, because I have to keep my mappings for DB2 and for Oracle.
If I have the same DAO for both databases, what can I do?
daoApplicationContext.xml
As you can see, I have 2 different DAO's sharing the same Interface & Implementation, but each one belongs to a different "sessionFactory"
Nothing special, right? But now here it comes the interesting part, because @Autowired by itself it will inject the given bean in your ServiceImpl, but you must have only one bean of that type. In my case I have more than 1, so @Autowired will throw an error when loading the context.
Then it comes @Qualifier which will match based on the given name, and problem solved chavos!!!
Notes: I used org.springframework.beans.BeanUtils to create a copy of my bean (pojo) returned from DB2 into a non-persistent Pojo which I'll manipulate before inserting into Oracle (DB2 completes each column value with spaces to achieve the given size of that column, so each time you query a DB2 column you'll get a lot of extra spaces)
Wednesday, September 1, 2010
EmbeddedId in Hibernate, AnnotatedClasses
Nothing special, I decided to use Hibernate with annotations (but what about the PK: just create another class -duh, but How can I tell hibernate this is my PK? @EmbeddedId and @Embeddable):
@EmbeddableDefines my composite PK
@EmbeddedIdIncludes my composite Pk in my main Pojo
If you want to include in your sessionFactory (daoApplicationContext.xml) my annotated pojos, add this entry
As a reminder, if you want to use a propeties file to provide parameter for your DataSource, you have to do this:
Thursday, August 19, 2010
How to test servlet using Telnet
$> telnet 127.0.0.1 9086Ok, I'm connected, and now what??
I know which servlet I want to test, I know which parameters is expecting, then "let's do it":
Which method should I use? POST or GET?? let's use POST (due to well known limitations with GET)
This is my URL:
/MyWebApp/proxyServlet?operation=doSomethingNice&consumerName=myActiveMQConsumers&server=192.168.5.122:9080&targetServlet=/MyOtherWebApp/utilsServletI'll finish my command with the HTTP version I want to use: HTTP/1.0 (if I use 1.1 it'll keep you connected)
And finally let's put all together:
Important: Once you have copied this full line in your telnet body, please type ENTER twice.
How do I know if this works? You should see this on your telnet console:
HTTP/1.0 200 OK Content-Type: text/xml;charset=ISO-8859-1 Cache-Control: no-cache Content-Language: en-US Content-Length: 21 Date: Thu, 19 Aug 2010 18:38:45 GMT Server: WebSphere Application Server/6.1true Connection to host lost.
Tuesday, August 17, 2010
Small Proxy App based on Apache Mina 2.0.0-RC1
My small app is just a standalone app based on Apache Mina, is going to be listening on "X" port and it's going to broadcast message received to another app which is a blackbox. So simple, Isn't it?
What do you need?
- mina-filter-compression-2.0.0-RC1.jar
- mina-integration-xbean-2.0.0-RC1.jar
- slf4j-log4j12-1.5.0.jar
- mina-integration-beans-2.0.0-RC1.jar
- jzlib-1.0.7.jar
- jaxen-1.1.1.jar
- mina-transport-apr-2.0.0-RC1.jar
- log4j-1.2.15.jar
- slf4j-api-1.5.0.jar
- mina-core-2.0.0-RC1.jar
This jar is just a luxury, but it's necesary, because I don't want to reinvent the wheel: commons-lang-2.3.jar
Well, time to work, the first thing you should code is the main class, my ProxyServer and 2 IoHandlers (ProxyHandlerAdapter & ClientHandlerAdapter).
And this is my code
I didn't include other classes because they're not important
Log4J tips
ConversionPattern=%d [%5p] [%t] %c{1}.%m%n
That's right just by adding "%t", you can see which thread is doing what.
Friday, August 13, 2010
Spring MVC - Binding VO to a Form
I have a VO and I wanted to populate it on my JSP and on my controller just process the VO already populated.
Solution:
On my POST method I'll handle my VO already populated.
This entry will do 50% of the job @ModelAttribute(value="LoggerVO") LoggerVO loggerVO
On my JSP I'll map using spring's tag library
By doing this modelAttribute="LoggerVO" commandName="LoggerVO"
I'm matching what I have on my form and what I have on my Controller
I hope this will help you!
Salu2
Wednesday, August 11, 2010
Cross Domain issue - Ajax
I was working in a GUI for controlling components in different servers from one server - stopping, starting, purging queues & consumers; finally beans
The firSt thing it came to my mind was: "let's do it with AJAX to avoid multiple calls and decrease the traffic!!!"
Which AJAX framework should I choose??? Let's learn jQuery, because that one has a bunch of cool features which will be really helpfull to develop my GUI (check this site: flowplayer.org they have a bunch of demos which are really easy to follow and all based on jQuery)
My first issue was learnign that Ajax call, but after a few hours I could do my first ajax call using jQuery (I have a servlet which returns XML or JSON)
Now what??? If I'm accessing the servlet in the same context - domain, everything works fine, but... If I try to access my servlet but in another server
Tons tuve que eccharle coco
My solution was to create a ProxyServlet which basically will take my request and pass it to the remote server & servlet using an HttpClient and in the same way, it will get the response coming from the remote servlet, in other words, my ProxyServlet (in the same domain - context) will be the only one talking to my Ajax call, eventhough ProxyServlet will be talking to the remote server & servlet. Then I did it again
This is my code:
This is my main servlet (the one which returns XML or JSON using json-simple project)
And this now, these are portions of my jQuery code:
You can get the additional JavaScript libraries from: JSON2 and my version of jQuery Tools