tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dmitri Pisarenko <dmitri.pissare...@gmail.com>
Subject Re: How to fix the problem of partial loading of images?
Date Sat, 01 Nov 2014 19:20:33 GMT
Hello Felix!

Thanks for your response.

> What is serving the images (default servlet, own servlet, ...)?

The system consists of following parts:

1) The web app based on Primefaces Mobile
2) A server

In the web app, I have following xhtml page, which is supposed to display
the image:

Source (start)

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui"
      xmlns:pm="http://primefaces.org/mobile">

<f:view renderKitId="PRIMEFACES_MOBILE"/>

<h:head>

</h:head>

<f:event listener="#{main.loadFirstImage}" type="preRenderView" />

<h:body id="body">

    <pm:page id="page">
        <pm:header title="myapp">
        </pm:header>

        <pm:content id="content">
            <h:form>
                <p:graphicImage id="image" rendered="false"
value="#{main.currentImage()}"
                                cache="false">
                </p:graphicImage>

            </h:form>
        </pm:content>

        <pm:footer title="m.myapp.info"></pm:footer>
    </pm:page>
</h:body>

</html>

Source (end)

The main bean looks like this:

Source (start)

@ManagedBean(name = MainView.NAME)
@SessionScoped
public class MainView {
    public static final String NAME = "main";
    public static final String IMAGE_COMPONENT_ID = "image";
    private byte[] currentImageData;

    public void loadFirstImage()
    {
        fetchNextImage();
    }

    protected void fetchNextImage() {
        final String userEmail = getAuthenticatedUserEmail();
        System.out.println("email: " + userEmail);

        final GetNextImageRequest request = new GetNextImageRequest();
        request.setUserEmail(userEmail);

        final RequestSender<GetNextImageRequest, GetNextImageResponse>
                requestSender = createGetNextImageRequestSender();

        final GetNextImageResponse response =
requestSender.sendRequest(request);

        final RecommendationResult result = response.getResult();

        final GraphicImage image =
(GraphicImage)findComponent(IMAGE_COMPONENT_ID);

        System.out.println("result: " + result);

        if (RecommendationResult.NEW_IMAGE_AVAILABLE.equals(result))
        {
            setCurrentImageData(response);
            setImageId(response.getImage().getUserProductImageId());
        }
        else
        {
            System.out.println("Disabling controls");

            image.setRendered(false);


        }
    }

    protected void setCurrentImageData(final GetNextImageResponse
aResponse) {
        currentImageData = aResponse.getImage().getImageData();
    }

    public StreamedContent currentImage()
    {
        FacesContext context = FacesContext.getCurrentInstance();

        if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
            // So, we're rendering the view. Return a stub StreamedContent
so that it will generate right URL.
            return new DefaultStreamedContent();
        }
        else {
            // So, browser is requesting the image. Return a real
StreamedContent with the image bytes.
            return new DefaultStreamedContent(new
ByteArrayInputStream(currentImageData));
        }
    }
}

Source (end)

The result of currentImage() method is fed to the p:graphicImage component
in the XHTML file.

Where does the data come from?

It comes from the server.

Source (start)

final GetNextImageRequest request = new GetNextImageRequest();
request.setUserEmail(userEmail);

final RequestSender<GetNextImageRequest, GetNextImageResponse>
        requestSender = createGetNextImageRequestSender();

final GetNextImageResponse response = requestSender.sendRequest(request);

Source (end)

The piece of code before sends a request to server
(requestSender.sendRequest), and the response contains an image.

RequestSender looks like this:

Source (start)

public class RequestSender<RequestType extends MyAppRequest, ResponseType
extends MyAppResponse> {
    private static final Logger LOGGER =
LoggerFactory.getLogger(RequestSender.class);
    public static final String REQUEST = "request";
    private final String serverUrl;
    private final String serviceName;
    private final Class<ResponseType> responseClass;

    public RequestSender(final Class<ResponseType> aResponseClass, final
String aServiceName,
                         final String aServerUrl) {
        responseClass = aResponseClass;
        serverUrl = aServerUrl;
        serviceName = aServiceName;
    }

    public ResponseType sendRequest(final RequestType aRequest)
    {
        final ObjectMapper mapper = new ObjectMapper();
        String json = null;

        try {
            json = mapper.writeValueAsString(aRequest);

            final CloseableHttpClient httpclient =
HttpClients.createDefault();

            HttpPost post = new HttpPost(serverUrl + serviceName);

            final List<NameValuePair> nameValuePairs = new
ArrayList<NameValuePair>();
            nameValuePairs.add(new BasicNameValuePair(REQUEST, json));

            post.setEntity(new UrlEncodedFormEntity(nameValuePairs));

            final CloseableHttpResponse response2 =
httpclient.execute(post);

            final ResponseType response =
mapper.readValue(response2.getEntity().getContent(),
                    responseClass);

            EntityUtils.consume(response2.getEntity());

            return response;
        } catch (final JsonProcessingException exception) {
            LOGGER.error("", exception);
        } catch (UnsupportedEncodingException e) {
            LOGGER.error("", e);
        } catch (IOException e) {
            LOGGER.error("", e);
        }

        return null;
    }
}

Source (end)

On the server side, there is an Apache CXF based web service. The class,
which is responsible for handling the GetNextImageRequest looks like shown
below.

Source (start)

@Path("/"+ GetNextImageRequest.SERVICE_NAME)
public class GetNextImage extends AbstractMyAppService {
    private static final Logger LOGGER =
LoggerFactory.getLogger(GetNextImage.class);

    @POST
    @Produces("text/plain")
    public String GetNextImage(@FormParam("request") final String aRequest)
{
        try {
            final ObjectMapper mapper = new ObjectMapper();
            final GetNextImageRequest request = mapper.readValue(aRequest,
                    GetNextImageRequest.class);

            final GetNextImageResponse response =
                    getMyAppPersistence().runAction(new
GetNextImageAction(request));

            return mapper.writeValueAsString(response);
        } catch (final JsonParseException exception) {
            LOGGER.error(GetNextImageRequest.SERVICE_NAME, exception);
        } catch (final JsonMappingException exception) {
            LOGGER.error(GetNextImageRequest.SERVICE_NAME, exception);
        } catch (final IOException exception) {
            LOGGER.error(GetNextImageRequest.SERVICE_NAME, exception);
        } catch (final InterruptedException exception) {
            LOGGER.error(GetNextImageRequest.SERVICE_NAME, exception);
        } catch (final Exception exception) {
            LOGGER.error(GetNextImageRequest.SERVICE_NAME, exception);
        }

        return "";
    }

}

Source (end)

GetNextImageAction reads image data from MongoDB and puts them into
response.

I have a suspicion that there may be something wrong with

a) the way the data are stored in MongoDB and/or
b) the data are packed into the response,

but there is another web app, which uses the same code for reading image
data (written in Vaadin, not in Primefaces Mobile) and there the images are
displayed correctly.

Therefore, for now it's not my #1 suspect.

> Are there any filters involved?

Not.

The Primefaces app has following web.xml:

Source (start)

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp"
         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id="WebApp_ID"
         version="3.0">
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/f/*</url-pattern>
    </servlet-mapping>
</web-app>


Source (end)

> Are there any expetions in the log files (catalina.out, localhost.DATE,
...)?

No, but Primefaces logs do not appear there (I'm already investigating it).

> Are there any other components in the path from browser to tomcat?

Yes. As said above:

1) The user visits the Primefaces app.

2) The Primefaces app sends a request to server.

3) The server sends image data back to the Primefaces app.

4) The Primefaces app displays it.

Both server and the Primefaces app run on the same Tomcat instance.

> Exact tomcat version maybe java version?

Tomcat version: Apache Tomcat/7.0.42

Java version:

~# java -version
java version "1.7.0_51"
OpenJDK Runtime Environment (IcedTea 2.4.4) (7u51-2.4.4-0ubuntu0.13.10.1)
OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)


OS: Ubuntu 13.10 (GNU/Linux 3.11.0-12-generic x86_64), runs on a
DigitalOcean droplet.

Best regards

Dmitri

2014-11-01 20:05 GMT+03:00 Felix Schumacher <
felix.schumacher@internetallee.de>:

> Am 01.11.2014 um 09:28 schrieb Dmitri Pisarenko:
>
>  Hi!
>>
>> I have a web application, which runs on an Apache Tomcat 7 instance.
>>
>> The application loads images from a web service and then displays it.
>>
>> Sometimes, but not always, the image is displayed only partially (for an
>> example, see http://i.stack.imgur.com/Nup8o.png ).
>>
>> Provided that the problem is with Tomcat (not with data being stored
>> incorrectly, or something else), how can I fix it?
>>
>> Up to now I tried following:
>>
>> 1) Disabling cache for all elements of that Primefaces page.
>>
>> 2) Disabling response chunking (as recommended at
>> http://forum.primefaces.org/viewtopic.php?f=3&t=40174 ) by setting
>> maxExtensionSize and maxTrailerSize (server.xml) to "-1" (
>> http://i.imgur.com/VhDxEUA.png ).
>>
> What is serving the images (default servlet, own servlet, ...)?
> Are there any filters involved?
> Are there any expetions in the log files (catalina.out, localhost.DATE,
> ...)?
> Are there any other components in the path from browser to tomcat?
> Exact tomcat version maybe java version?
>
> Felix
>
>>
>> Thanks
>>
>> Dmitri
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message