You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@olingo.apache.org by "Michael Bolz (JIRA)" <ji...@apache.org> on 2013/09/13 06:07:51 UTC

[jira] [Comment Edited] (OLINGO-15) Content Type of response hard coded in EntityProvider

    [ https://issues.apache.org/jira/browse/OLINGO-15?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13764266#comment-13764266 ] 

Michael Bolz edited comment on OLINGO-15 at 9/13/13 4:06 AM:
-------------------------------------------------------------

With the last commits (see list below) I refactored the *content negotiation* and handling/setting of the {{Content-Type}} header information.
Now it is intently in the {{ContentNegotiator}} which therefore got more *OData specific logic* in the form of {{UriInfo}} and {{ODataRequest}}.
Each {{EntityProvider}} now only provides the {{Entity}} without setting of the {{Content-Type}}.
The {{ODataProcessor}} implementation can set the {{ContentType}} in the {{ODataResponse}} if wished. If it is not set the {{ContentNegotiator}} will set it (on behalf of the {{ODataRequestHandler}}. 

IMHO this is a far better solution as before and hence this issue is fixed (for me) and can be closed.

* {{b538067}} Refactored to one content negotiation method
* {{99e549d}} Moved complete content type handling into ContentNegotiator
* {{31c3d8f}} Refactored content negotiation from RequestHandler into ContentNegotiator
* {{060f9c6}} Refactoring for OLINGO-15 (ATOM/XML-Part)
* {{ce78a0b}} Refactoring for OLINGO-15 (JSON-Part)
                
      was (Author: mirbo):
    With the last commits (see list below) I refactored the *content negotiation* and handling/setting of the {{Content-Type}} header information.
Now it is intently in the {{ContentNegotiator}} which therefore got more *OData specific logic* in the form of {{UriInfo}} and {{ODataRequest}}.
Each {{EntityProvider}} now only provides the {{Entity}} without setting of the {{Content-Type}}.
The {{ODataProcessor}} implementation can set the {{ContentType}} in the {{ODataResponse}} if wished. If it is not set the {{ContentNegotiator}} will set it (on behalf of the {{ODataRequestHandler}}. 

IMHO this is a far better solution as before and hence this issue is fixed (for me) and can be closed.

* {{99e549d}} Moved complete content type handling into ContentNegotiator
* {{31c3d8f}} Refactored content negotiation from RequestHandler into ContentNegotiator
* {{060f9c6}} Refactoring for OLINGO-15 (ATOM/XML-Part)
* {{ce78a0b}} Refactoring for OLINGO-15 (JSON-Part)
                  
> Content Type of response hard coded in EntityProvider
> -----------------------------------------------------
>
>                 Key: OLINGO-15
>                 URL: https://issues.apache.org/jira/browse/OLINGO-15
>             Project: Olingo
>          Issue Type: Improvement
>          Components: odata2-core
>    Affects Versions: 0.0.0, 1.0.0
>            Reporter: Michael Bolz
>            Assignee: Michael Bolz
>             Fix For: 1.0.0
>
>
> Content Type Negotiation is done correctly (in most cases) but in the end the content type which is set is hard coded in the response (see example for JSON below).
> After a review of the {{AcceptHeader}} content type process flow through the {{Dispatcher}}, the {{RequestHandler}}, the {{Processor Implementation}}, the {{EntityProvider}} and back it would be better to refactor the behavior were the {{Content-Type Header}} of the response is set. 
> Suggested is to do the content negotiation at the {{RequestHandler}}, give the result to the {{Dispatcher}} which simply pass through it to the {{Processor}} implementation. The {{EntityProvider}} based classes *MUST NOT* set the {{Content-Type Header}} of the {{ODataResponse}}. The only exception is when the resulting {{Content-Type}} can only have one valid value, which is e.g. the case for a {{$count}} request which only can be {{Content-Type: text/plain}}.
> The {{Processor}} implementation returns with the {{ODataResponse}} back to the {{RequestHandler}} which then checks if the {{Content-Type Header}} is set and *only if it is not set* the {{RequestHandler}} set the header with the resulted content type from the before done content negotiation. If the header is already set (from the {{Processor}}) it is not changed.
> With this solution the {{Content-Type}} handling and set for the response is not spreaded through several layers of the library. It then is clear that it is done by the {{RequestHandler}} and can be overwritten by the implementing {{Processor}}.
> In addition the {{EntityProvider}} does not have the {{Content-Type}} hard coded which allows a better pre defined content negotiation in the library (especially with parameters in the {{AcceptHeader}}).
> Appendix:
> JsonEntityProvider:
> {code}
>   @Override
>   public ODataResponse writeFeed(final EdmEntitySet entitySet, final List<Map<String, Object>> data, final EntityProviderWriteProperties properties) throws EntityProviderException {
>     final EntityInfoAggregator entityInfo = EntityInfoAggregator.create(entitySet, properties.getExpandSelectTree());
>     CircleStreamBuffer buffer = new CircleStreamBuffer();
>     try {
>       BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(buffer.getOutputStream(), DEFAULT_CHARSET));
>       new JsonFeedEntityProducer(properties).append(writer, entityInfo, data, true);
>       writer.flush();
>       buffer.closeWrite();
> ---->      return ODataResponse.entity(buffer.getInputStream()).contentHeader(HttpContentType.APPLICATION_JSON).build();
>     } catch (EntityProviderException e) {
>       buffer.close();
>       throw e;
>     } catch (Exception e) {
>       buffer.close();
>       throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass().getSimpleName()), e);
>     }
>   }
> {code}

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira