2

We are using Tridion 2013 SP1 with DXA 1.5 java. One of our requirement we want to serve the JSON formated data file( apple-app-site-association ) in my web site.

My component schema has only one rich text field (without Rich Text Formatting) and Only one component presentation is enough for the page. I have published the page in to broker DB. I built the page in CM (apple-app-site-association.json) but When I request the page (http://localhost:9080/apple-app-site-association) without extension.

Note: The page response content type should be "Content-Type: application/json"

The page response should be like this:

http://localhost:9080/apple-app-site-association (without page .json extension)

{
  "applinks": {
    "apps": [],
    "details": [
      {
        "appID": "xxx.com.xx.AccidentToolkit",
        "paths": [
          "/cp/mobile/*"
        ]
      }
    ]
  }
}

Updated:

I have created a schema "CodeSchema" with only one rich text field name "code"(without Rich Text Formatting) I created a component for this shcema it's has JSON data. I have created a page(JSON PT and only one component presentation for my component) I published the page. it's in broker DB.

I'm trying to get the page/component data through my custom controler then return it to my view (jsp):

RegisteredViewModel:

@RegisteredViewModel(viewName = "CodeJSONPage", modelClass = CodeComponentModel.class, controllerName = "AppleAppSiteAssociationController")

Model:

@SemanticEntity(entityName = "Code", vocabulary = SDL_CORE, prefix = "c")
    public class CodeComponentModel extends AbstractEntityModel {

        @JsonProperty("code")
        @SemanticProperty("c:code")
        private RichText code;

        public RichText getCode() {
            return code;
        }

        public void setCode(RichText code) {
            this.code = code;
        }
  }

Controller:

@Controller
@RequestMapping(method = RequestMethod.GET, value="/apple-app-site-association", headers="content-type=application/json")
public class AppleAppSiteAssociationController extends EntityController {

    private static final Logger LOG = LoggerFactory.getLogger(AppleAppSiteAssociationController.class);

    @RequestMapping() 
    public String GetAppleAppSiteAssociationJSON(@RequestHeader("Content-Type") String ContentType, @RequestHeader("Accept") String acceptType, ModelMap modelMap, HttpServletRequest request) {

        // Am trying to get the getCode() data here

        //modelMap.put("entity",  jObjects);
        return "Nationwide/Page/CodeJSONPage";
    }
}
2
  • How does the expected output JSON relate to the rich text field content of the Component? Does that rich text field contain the JSON? If so, why is it rich text (and not plain, multi-line text)? May 1, 2018 at 20:15
  • Yes It has JSON data. The rich text field (without Rich Text Formatting) - we are using this filed to copy the the complete JSON data. Whenever content loader want to change the JSON data as well as any kind of JSON structure they can. May 3, 2018 at 17:23

2 Answers 2

2

You can create your own Controller with its own route (/apple-app-site-association) and let it return whatever kind of JSON data you need.

UPDATE:

If you don't want to use your own Controller, but use DXA's default Page Controller, you will have to ensure that your CM Pages use an .html file extension; DXA supports extensionless URLs, but it expects the CM Page to always have an .html file extension (even though the published Page Content will actually be JSON).

The default Page Controller will serve JSON (with Content-Type: application/json) if the HTTP request has an Accept: application/json header (or if the request URL contains ?format=json), but the response JSON will represent the entire Page Model.

If you want to have control over the returned JSON, you should create your own Controller. For example, see: https://github.com/sdl/dxa-web-application-java/blob/master/dxa-webapp/src/main/java/org/example/controller/AdminController.java

12
  • 1
    Thanks for you response @Rick Pannekoek. Yes I can create own controller route (/apple-app-site-association) but not sure how Can I get the JSON response data without any default tag's. Do you mean that, do I need to parse all the data again ? Do you have some example ? Apr 26, 2018 at 18:58
  • Also When I request localhost:9080/apple-app-site-association - without .json extension it's throwing 404. When I debug i can see the log. look like the DXA by default it's appending in the end "/index.html" Apr 26, 2018 at 19:24
  • Please clarify what you mean with “default tags” Apr 30, 2018 at 19:11
  • I thought you mean to get the JSON data using "/apple-app-site-association.json?format=json " using the query string it's returning as below Ex: {\n \"applinks\": {\n \"apps\": [],\n \"details\": [\n {\n \"appID\": \"9JA89QQLNQ.com.apple.wwdc\",\n } Apr 30, 2018 at 19:38
  • I’m sorry, but I really don’t undestand what you are trying to achieve and what the problem is, exactly. Can you update the Question with more explanation? For example, you show the desired JSON output, but where does the data come from? What are the “additional/default tags” you’re mentioning? May 1, 2018 at 17:02
1

OK, it is finally getting clear what you want to achieve and how you are trying to achieve it; thanks for providing the additional details, that helps a lot!

I'm still wondering why you are trying to manage raw output JSON in Content Manager (and why you're using a Rich Text Field for that). It seems very error-prone to me. But let's not go there now.

Note that, in general, you shouldn't use DXA's "JSON" Page Template for your CM Pages; that PT is intended for raw JSON files which DXA uses for its settings. Regular DXA Pages use a PT which invokes the "Render Page Content" TBB. This renders a DXA Page Model (JSON), which can be served by the default Page Controller.

However, given what you want to achieve, the simplest approach might be to completely bypass the DXA MVC mechanism for this Page:

  • Create a Component Template which outputs the JSON from your Code Component's Rich Text Field
  • Create a Page with one Component Presentation based on that CT. Use the DXA "JSON" Page Template like you're currently doing.
    • When you preview or publish this Page, it should contain the raw JSON from your Component.
  • Create your own Controller.
    • Don't let it inherit from EntityController; these are intended for use within DXA's MVC mechanism.
    • Let your Controller use the CD API to retrieve the (JSON) content of your Page
    • Let your Controller return this JSON and set the response header Content-Type: application/json

Alternatively, you can let your CT be dynamic. In that case, you don't need a Page at all; your Code Component can be published directly as Dynamic Component Presentation. Your Controller can then use the CD API to retrieve this DCP.

UPDATE:

Examples of how to retrieve Page and DCP content using CD APIs can be found here: https://github.com/sdl/dxa-model-service/blob/master/java/dxa-model-service/dxa-model-service-controller/src/main/java/com/sdl/dxa/modelservice/service/ContentService.java

5
  • Thanks Rick for your detailed steps. I agree the raw JSON content is not the right way but my client want to change the JSON data structure very often without IT help. Can you please provide the detail or sample controller, how I can map model or broker DB to get the one filed value using CD API ? May 3, 2018 at 19:17
  • Thanks for the CT be dynamic suggestion. Do you have some sample controller for CD API to retrieve the DCP ? May 3, 2018 at 19:22
  • You could use a structured content model in CM which gets rendered to JSON. This also allows the client to modify the data without IT help (even more so, because the client doesn't have to understand the JSON syntax, but will be guided by CM Schemas and forms). May 3, 2018 at 19:24
  • Updated the Answer with link to examples for use of CD APIs. May 3, 2018 at 19:29
  • @RickPannekoek The link in your update is broken. Do you know where it should point to? Aug 5, 2019 at 15:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.