2

I have created a Java Custom Controller for training which works in DXA 1.3 and am updating it for DXA 1.4.

Here is what is going on:

  • I have an Eclipse Project that has the following: enter image description here

  • The “TrainingModuleInitializer.java” looks as follows:


package com.sdl.modules.Training;

import com.sdl.modules.Training.model.*;
import com.sdl.webapp.common.api.mapping.views.AbstractInitializer;
import com.sdl.webapp.common.api.mapping.views.RegisteredViewModel;
import com.sdl.webapp.common.api.mapping.views.RegisteredViewModels;
import com.sdl.webapp.common.api.model.page.PageModelImpl;
import com.sdl.webapp.common.api.model.region.RegionModelImpl;

import org.springframework.stereotype.Component;

@Component
@RegisteredViewModels({
        @RegisteredViewModel(viewName = "SpecialOffer", modelClass = SpecialOfferModel.class),
        @RegisteredViewModel(viewName = "NavOnRightPage", modelClass = PageModelImpl.class),      
        @RegisteredViewModel(viewName = "6-Column", modelClass = RegionModelImpl.class),      
        @RegisteredViewModel(viewName = "Story", modelClass = StoryModel.class),
        @RegisteredViewModel(viewName = "CustomStory", modelClass = CustomStoryModel.class, controllerName = “Campaign")
})
public class TrainingModuleInitializer extends AbstractInitializer{

    @Override
    protected String getAreaName(){
        return "Training";
    }
}
  • The “CampaignavigationController.java” is as follows:

package com.sdl.modules.Training.controller;

import com.sdl.modules.Training.model.CustomStoryModel;
import com.sdl.webapp.common.api.WebRequestContext;
import com.sdl.webapp.common.api.model.ViewModel;
import com.sdl.webapp.common.api.model.mvcdata.DefaultsMvcData;
import com.sdl.webapp.common.controller.ControllerUtils;
import com.sdl.webapp.common.controller.EntityController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
* CampaignController
*
* @author SDL Education
*/
@Controller
@RequestMapping(ControllerUtils.INCLUDE_PATH_PREFIX + "Training/CampaignController")
public class CampaignController extends EntityController
{

    @Autowired
    private WebRequestContext webRequestContext;

    public CampaignController() {
       System.out.println("Doing stuff!");
    }

    @RequestMapping(method = RequestMethod.GET, value = DefaultsMvcData.CoreAreaConstants.ENTITY_ACTION_NAME + "/{entityId}")
    public String handleGetEntity(HttpServletRequest request, @PathVariable String entityId) throws Exception {
        return super.handleGetEntity(request, entityId);
    }

    @Override
    protected ViewModel enrichModel(ViewModel model, HttpServletRequest request) throws Exception {
        model = super.enrichModel(model, request);

        CustomStoryModel customerStory = (CustomStoryModel)model;

        customerStory.setQueryText(request.getParameter("q"));

        return customerStory;
    }

}
  • The “CustomStoryModel.java” is as follows:

package com.sdl.modules.Training.model;

import static com.sdl.webapp.common.api.mapping.semantic.config.SemanticVocabulary.SDL_CORE;

import com.sdl.webapp.common.api.mapping.semantic.annotations.SemanticEntity;
import com.sdl.webapp.common.api.mapping.semantic.annotations.SemanticProperty;
import com.sdl.webapp.common.api.model.entity.AbstractEntityModel;
import com.sdl.webapp.common.api.model.entity.Image;

@SemanticEntity(entityName = "Story", vocabulary = SDL_CORE, prefix = "s")

public class CustomStoryModel extends AbstractEntityModel {

       @SemanticProperty("s:name")
    public String name;
       @SemanticProperty("s:email")
    public String email;
       @SemanticProperty("s:article")
    public String article;
       @SemanticProperty("s:picture")
    public Image picture;

    public String queryText;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    public String getEmail() {
        return email;
    }

    public void getEmail(String email) {
                this.email = email;
    }

    public String getArticle() {
        return article;
    }

    public void setArticle(String article) {
        this.article = article;
    }

    public Image getPicture() {
        return picture;
    }

    public void setPicture(Image picture) {
        this.picture = picture;
    }
    public String getQueryText() {
        return queryText;
    }

    public void setQueryText(String queryText) {
        this.queryText = queryText;
    }

 }

  • Here is what the CMS looks like: I Have the following Component Template "CustomStory" enter image description here

I created a new Page in the 400 Campaign Site (EN) publication and published the 020 My Story page which contains the mystory component with the CustomStory Component Template (which makes reference to my controller in it as seen above).

When I load the page I get the following: enter image description here


00:01:39.600 [http-nio-8090-exec-9] ERROR c.s.w.c.controller.PageController - Exception while processing request for: /system/mvc/Training/Campaign/Entity/784
com.sdl.webapp.common.controller.exception.BadRequestException: Request to unknown action: /system/mvc/Training/Campaign/Entity/784
    at com.sdl.webapp.common.controller.PageController.handleGetUnknownAction(PageController.java:263) ~[dxa-common-api-1.4.1.jar:1.4.1]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_73]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_73]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_73]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_73]
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219) ~[spring-web-3.1.4.RELEASE.jar:3.1.4.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) ~[spring-web-3.1.4.RELEASE.jar:3.1.4.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:100) ~[spring-webmvc-3.1.4.RELEASE.jar:3.1.4.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:604) ~[spring-webmvc-3.1.4.RELEASE.jar:3.1.4.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:565) ~[spring-webmvc-3.1.4.RELEASE.jar:3.1.4.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) ~[spring-webmvc-3.1.4.RELEASE.jar:3.1.4.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923) ~[spring-webmvc-3.1.4.RELEASE.jar:3.1.4.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852) ~[spring-webmvc-3.1.4.RELEASE.jar:3.1.4.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882) ~[spring-webmvc-3.1.4.RELEASE.jar:3.1.4.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778) ~[spring-webmvc-3.1.4.RELEASE.jar:3.1.4.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) [servlet-api.jar:na]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [servlet-api.jar:na]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) [catalina.jar:8.0.32]

The QueryText field in the Model is supposed to get a query string value from the Request and have it assigned by the Controller.

3

The issue turned out to be in the Controller code (@RequestMapping).

I had the following:


@Controller
@RequestMapping(ControllerUtils.INCLUDE_PATH_PREFIX + "Training/CampaignController")
public class CampaignController extends EntityController

It needed to be the following, without the Controller at the end of the Controller name:


@Controller
@RequestMapping(ControllerUtils.INCLUDE_PATH_PREFIX + "Training/Campaign")
public class CampaignController extends EntityController

It appears that this was changed from version 1.3 of DXA to version 1.4 of DXA.

Was this changed intentionally?

Is it Documented?

This i would believe could be considered a compatibility break.

  • Indeed, this can be considered a compatibility break. I am not aware of this change. I would argue that the new style URL mapping (if it really changed in the first place) makes more sense, though; the URL contains the Area, Controller and Action name exactly as specified in CM. – Rick Pannekoek Aug 3 '16 at 17:38
  • I have just tested on an instance with DXA 1.3 and if I make the above change in the Controller code file and remove the Controller after Campaign ("Training/Campaign"), it fails. If I place the Controller back at the end of Campaign ("Training/CampaignController") it works perfectly fine. – TridionNut Aug 3 '16 at 19:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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