Internet Explorer caching behavior for RESTful data pulled by AngularJS

Hi, There:

A UI tester told me an AngularJS app doesn’t work in IE11, but works fine in Chrome or FF. So I gave it try and tested it in IE. In order to see how things are doing, I turned on the Developer tool to see what the console says and how network traffic moves – and you guessed it – everything works just fine! Soon I realized that the tester would never turn on the IE Developer tool when she was testing, so I turned it off. Then I could replicate the problems that she had described to me.

A bit later I realized, by default, IE actually cache the JSON data that AngularJS gets from the server side. But the cache is off when the Developer tool is on. Hence the behavior is different. For Chrome or FF, caching is not on by default. Searching throw sites such as StackOverflow gave similar suggestions. So it looks like force turning off caching in the application should be the right solution to the problem.

Typically there are two solutions to turn off cache, client side and server side. They both should work. But since the app is an AngularJS app that asynchronously gets data from server side’s RESTful services, html <meta> tag like this will not work well since the JSON data requested would not be affected:

<meta http-equiv="Pragma" content="no-cache">   <!-- does not work -->

The solution that will work is to enforce response to be not cached on the server side:

response.setHeader("Cache-Control", "private, no-store, no-cache, must-revalidate");
response.setHeader("Pragma", "no-cache");

 

This should ensure non-caching at the client side for a particular JSON data pulled by AngularJS. Certainly, if caching is desired, it should not be implemented as such. After implemented this, the above AngularJS application whose behavior depends fully on fresh JSON data now works well as expected!

Cheers!

-T. Yan

 

Handle BLOB XML Adapter – java.sql.Blob is an interface, and JAXB can’t handle interfaces.

Hi, There:

Started to play with JSON data. When I tried to Marshall my existing Java object which has a java.sql.Blob field,  I got this exception: java.sql.Blob is an interface, and JAXB can’t handle interfaces. etc. After googling, I found the solution is to use an XmlAdapter like this.

import java.sql.Blob;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.hibernate.Hibernate;
public class BlobXmlAdapter extends XmlAdapter<String, Blob> {
@Override
public Blob unmarshal(String v) throws Exception {
if (v ==null) v= “”;
return Hibernate.createBlob(v.getBytes());
}
@Override
public String marshal(Blob v) throws Exception {
if (v == null) return “”;
return v.getBytes(1l, (int)v.length()).toString();
}

}

and annotated it in my POJO’s getter.

@XmlRootElement
public class MyDataObject implements Serializable {

…..

@XmlJavaTypeAdapter(BlobXmlAdapter.class)
public Blob getPAYLOAD() {
return PAYLOAD;
}

……

}

It works like a charm!  My JAX-RS converts the Java into JSON nicely as expected.

-TY

java.lang.AbstractMethodError: javax.ws.rs.core.UriBuilder.uri

Hi, There:

This should be an easy one to figure out. But it took me a couple of days. :-((  When I set up my restful service using JAX-RS on Weblogic 10. I used Jersey reference implementation and defined the web.xml as:

<servlet>

<display-name>My Jersey Application</display-name>
<servlet-name>MyJerseyApp</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>MyRestApplication</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>test.package</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MyJerseyApp</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>

And my POM has

<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<!– if your container implements Servlet API older than 3.0, use “jersey-container-servlet-core” –>
<artifactId>jersey-container-servlet</artifactId>
<version>2.3</version>
</dependency>

BUT when I access the resources HelloWorld.java as restful impl class, I got this java.lang.AbstractMethodError: javax.ws.rs.core.UriBuilder.uri. It turned out I just need to include the dependency class for UriBuilderImpl. The easiest one is from CXF.

<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-bundle-jaxrs</artifactId>
<version>2.7.7</version>
</dependency>

Then the problem was gone!   I should have known that the java.lang.AbstractMethodError tells me it needed some actual Impl. class for the UriBuilder Abstract class. Duh!

Hope it helps anyone out there.

-TY