I am creating file using Java and generating link for download.
Let's say I create file myFile.xls and have link as below.
Please download data from here.
This will result as below.
Please download data from here.
Everytime I create new file, and click on above link, I always see the earlier file that I downloaded for the first time.
Is it happening because jsf cache the files?
Note : When I download file manually, I always see the updated file.
However using link, I always see the first file.
Any idea why this happening?
I think this is because of caching. If yes, how can I ignore this for this excel file only?
JSF isn't caching those resources at all. JSF is in the context of this question merely a HTTP traffic controller and HTML code generator. It's the webbrowser who's caching them. You can control this by setting the proper response headers as listed in this answer: How to control web page caching, across all browsers?.
The simplest way would be creating a servlet filter which is mapped on the URL pattern matching those downloads, e.g. /excel/* (your JSF source code and actual URL doesn't match each other, so it's somewhat guessing here), and set the headers in the doFilter() method:
#WebFilter("/excel/*")
public class NoCacheFilter implements Filter {
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0); // Proxies.
chain.doFilter(req, res);
}
// ...
}
Or, if you're serving those files via a servlet, then you could also just set those headers over there.
An alternative is to fool the webbrowser that it's a brand new resource by inlining a query string with a timestamp.
Please download data from here.
where #{now} is just an java.util.Date registered as request scoped bean in faces-config.xml (in case you're using JSF utility library OmniFaces; it has already one builtin). The webbrowser will treat any resource with a different query string as an unique and independent resource and therefore not reuse the cached version of the resource on the same URI (if the query string is different).
Related
I have Json data being pulled from a REST API. On success I have created a simple alert that will display the Json results inside of an $http.get. I found a sample URL that points to Json data online for testing and I get the alert with the results just fine. But when I try to do this with my URL pointing back to the api, I get no results (not even an alert). However, when I take that same URL and put it into the browser, all of my Json data is there. Any ideas or thoughts on what might be causing this issue? Thanks.
JavaScript (with test Json data)
var myApp = angular.module('paladinMonitor', ["highcharts-ng"]);
myApp.controller('SizeCtrl', function ($scope, $http, $timeout) {
$http.get('http://ip.jsontest.com/?callback=showMyIP').success(function (data, status) {
alert(data)
});
I had something similar happen to me. Restful web services must use the Access-Control-Allow-Origin header to specify what origins are allowed to access the service. Without it, you can hit the web service successfully by putting the address directly in your browser but it won't work from your app. If your REST service is written in Java, you can see this question for details on how to add the appropriate headers. Other languages will use a similar mechanism.
My other guess is that the web service requires authorization to access. It works fine from your browser because at one time you provided the proper credentials and
your browser cached them. If your service does require authorization, see the "Setting HTTP Headers" section on this page for information on how to add the appropriate headers.
As Alvin Thompson mentioned, you have to set your access-control-allow origin and should also set your access-control-allow-headers, access-control-allow-credentials on the server side. In my case I had to do this in my WebAPIcontroller. This is because in order for CORS to work (cross-domain) you have to have the service 1 (RESTApi in my case) allow permissions for service 2(client) to receive call it. In order, to allow this I had to add the following NuGet packages
NuGet
- Microsoft.AspNet.Cors NuGet package
- Microsoft.Owin.Cors NuGet package
Once these were installed I went to my config file on the API project and added
API App_Start/WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
config.EnableCors();
}
Then in my controller that inherits the API controller I referenced the NuGet package I installed and enabled CORS on the client side and this is where you set you origin, headers and methods
YourController : ApiController
namespace YourNamespace.Controllers
{
[EnableCors(origins: "https://localhost:.....", headers: "*", methods: "*")]
public class YourController : ApiController
{
//The rest of your controller functionality
}
}
The rest of the issue I was having was how the Json Web Token variable is being passed into my javascript file. I am still working on this, I will post the answer to this as well when I figure it out.
To read more about the CORS issue, this was the best reference for me: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
back again with another question related to the ics format and its browser specific management.
I wrote a server, if you care a RestFUL server generated with Spring 3.2, which returns a String directly to the calling client (here, for client, I mean a browser). The signature of my method is like
#RequestMapping(value="/path_and_params", method = RequestMethod.GET)
public ResponseEntity<String> myMethod (#PathVariable("first") long first, #PathVariable("second") String second)
Somewhere in myMethod I tweak the response with
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "text/calendar; charset=utf-8");
headers.add("Content-Disposition", "inline;filename=calendar.ics");
so that in the end what I return is
return new ResponseEntity<String> ( icsAsString, headers, HttpStatus.CREATED );
My desire is to have the browser to automatically create a file named calendar.ics from String icsAsString (note that icsAsString is created using iCal4J therefore is syntactically correct) and choose the right application to deal with this file. This desire comes from my understanding of the Content-Disposition header (https://www.rfc-editor.org/rfc/rfc2183). This works finely with Firefox (at least, with Firefox 22). However, this does not work with Chrome, in which the file is simply shown as content inside the calling tab. Moreover, I am not able to find any proof about the automatically create a file which makes me think that is a feature of Firefox and that problems may arise with IE or other browsers as well.
So, to conclude, my questions are:
did I understand correctly the Content-Disposition header? Should it serve the purpose to tell the browser to create a file based on the incoming response body content or was this a Firefox-specific feature?
should it be better if I create a file on the server and then transfer that file?
Apparently I forgot/misunderstood the behavior of http status codes. Somewhere in my code I was setting the response code to 201 instead of 200. Probably FF cares less about status codes than other browsers. In fact, the definition on code 201 states
The response SHOULD include an entity containing a list of resource characteristics and location(s) from which the user or user agent can choose the one most appropriate
and
The origin server MUST create the resource before returning the 201 status code
while I was not creating the file on the server. Now everything works as I was expecting!
Is it possible to obtain the source of a MediaWiki page programmatically? I'd like to write a function that does the following (in Java-like pseudocode):
public static String getWikiText(articleURL){
//return the source of the page as wiki markup
}
Send a HTTP request with action=raw. (You could use the API as well, but that is more complicated.)
I have a self-hosted WCF service running as a windows service using the WebAPI to handle the REST stuff and it works great.
I realise that I should really use IIS or similar to dish out actual web pages, but is there ANY way to get a service call to return "just" html?
Even if I specify "BodyStye Bare", I still get the XML wrapper around the actual HTML, ie
<?xml version="1.0" encoding="UTF-8"?>
<string> html page contents .... </string>
[WebGet(UriTemplate = "/start", BodyStyle = WebMessageBodyStyle.Bare)]
public string StartPage()
{
return System.IO.File.ReadAllText(#"c:\whatever\somefile.htm");
}
Is there any way to do this or should I give up?
The bodystyle attribute has no effect on WCF Web API. The example below will work. It's not necessarily the best way of doing it, but it should work assuming I didn't make any typos :-).
[WebGet(UriTemplate = "/start")]
public HttpResponseMessage StartPage() {
var response = new HttpResponseMessage();
response.Content = new StringContent(System.IO.File.ReadAllText(#"c:\whatever\somefile.htm"));
response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
return response;
}
It would probably make more sense to read the file as a stream and use StreamContent instead of StringContent. Or it is easy enough to make your own FileContent class that accepts the filename as a parameter.
And, the self-host option is just as viable way to return static HTML as using IIS. Under the covers they use the same HTTP.sys kernel mode driver to deliver the bits.
You'll have to use a formatter that accepts "text/html" as content type and request the content type "text/html" in your request header.
If you don't add a formatter that handles the text/html, Web API falls back to the XML-formatter as default.
In your case the formatter doesn't need to format anything but just return your return value as you're returning formatted html already.
I'm trying to send JSON data to a server.
RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, url);
builder.setHeader("Content-Type", "application/json");
builder.setRequestData(getJSONString());
builder.setCallback(myCallbackObject);
builder.send();
I do this in eclipse and I saw in the TCP/IP Monitor that my JSON Data is not transmitted as post in the request. If I ask for
builder.getRequestData();
I can see the JSON data is right there.
What do I need for the data to get on the server?
You might be running into the browser's same-origin policy if the url that you are attempting to connect to is not from the same origin as your GWT nocache.js file. Is your callback's onFailure() being called? Also, see if Request.getSatusCode() returns 0, which is indicative of SOP problems.
To simply post JSON data with HTTP post, you can use GWT Overlay Types to define a post method using JQuery. A possible snapshot:
public static native void post(String json) /*-{
var data = JSON.parse(json);
$wnd.$.post(url, data);
}-*/;
I don't know if it is necessary to add JQuery to your HTML. I did, and worked. You can do this by adding the following line to your .html file:
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Then, you can simply call that method in your java code:
post(json);
(: