Why is this URL not opened from Play! Framework 1.

2019-07-18 10:58发布

问题:

I have a URL in my Play! app that routes to either HTML or XLSX depending on the extension that is passed in the URL, with a routes line like :-

# Calls
GET     /calls.{format}                         Call.index

so calls.html renders the page, calls.xlsx downloads an Excel file (using Play Excel module). All works fine from the browser, a cURL request, etc.

I now want to be able to create an email and have the Excel attached to it, but I cannot pull the attachment. Here's the basic version of what I tried first :-

public static void sendReport(List<Object[]> invoicelines, String emailaddress) throws MalformedURLException, URISyntaxException
    {
        setFrom("Telco Analysis <test@test.com>");
        addRecipient(emailaddress);
        setSubject("Telco Analysis report");
        EmailAttachment emailAttachment = new EmailAttachment();
        URL url = new URL("http://localhost:9001/calls.xlsx");

        emailAttachment.setURL(url);
        emailAttachment.setName(url.getFile());
        emailAttachment.setDescription("Test file");
        addAttachment(emailAttachment);
        send(invoicelines);
    }

but it just doesn't pull the URL content, it just sits there without any error messages, with Chrome's page spinner going and ties up the web server (to the point that requests from another browser/machine don't appear to get serviced). If I send the email without the attachment, all is fine, so it's just the pulling of the file that appears to be the problem.

So far I've tried the above method, I've tried Play's WS webservice library, I've tried manually-crafted HttpRequests, etc. If I specify another URL (such as http://www.google.com) it works just fine.

Anyone able to assist?

回答1:

I am making an assumption that you are running in Dev mode.

In Dev mode, you will likely have a single request execution pool, but in your controller that send an email, you are sending off a second request, which will block until your previous request has completed (which it won't because it is waiting for the second request to respond)...so....deadlock! The resaon why external requests work fine, is because you are not causing the deadlock on your Play request pool.

Simple answer to your problem is to increase the value of the play.pool in the application.conf. Make sure that it is uncommented, and choose a value greater than 1!

# Execution pool
# ~~~~~
# Default to 1 thread in DEV mode or (nb processors + 1) threads in PROD mode.
# Try to keep a low as possible. 1 thread will serialize all requests (very useful for debugging purpose)
play.pool=3