intellij not resolving el variables within JSP code inspection or autocomplete

18,117

Solution 1

There's a standard way to do this, which is not IntelliJ-specific.

<jsp:useBean id="someModel" scope="request" type="foo.bar.SomeModelClass"/>

The type attribute here does not need to be a concrete class, it can be an interface type as well. Typically you'd put these declarations at the start of your JSP/JSPX files, to provide something like a "declaration of model inputs".

Using JSPs in such a declarative way was recommended in the original book on Spring, in fact (Expert One-on-One J2EE Design and Development.). IntelliJ has been providing full code completion for such pages since at least 7 years.

Note that there are additional relevant convenience features in IntelliJ: if an EL variable reference is marked as undefined, you can press Alt-Enter to select a QuickFix, which will insert a declaration like above. It will even try to figure out the actual type, based on the properties you're accessing.

Solution 2

As I understand Spring, there is no declaration for definitions of variables that you may put into your model. The call model.addAttribute() may add an object to the model, either identified by a parameter or automatically generated by the class name of the object.

So imagine the following case where you have more than one method:

@RequestMapping("foo") public String foo(Model model) { 
    model.addAttribute("model", new Foo());
    return new Random().nextBoolean() ? "page" : "someOtherPage";
}
@RequestMapping("bar") public String bar(Model model) { 
    model.addAttribute("model", new Bar());
    model.addAttribute("model", new Foo());
    model.addAttribute("model", new Bar());
    return new Random().nextBoolean() ? "page" : "someOtherPage";
}

and the JSP would be something like

<c:out ${model.value} />

Since there is no proper mapping of which controllers may under some circumstances forward to which views, nor what exactly lies within the model, your IDE has no real chance to provide you with proper information.

But to support the IDE in suggesting you some useful information, you can use type hints. Therefore, you have to copy the whole reference of an object, e. g. foo and add a JSP comment like:

<%--@elvariable id="foo" type="com.mycompany.SomeObject"--%>

The warning will vanish and the full IDE support is on your side, allowing you to traverse the fields of foo. One of the nicest things is that the unused getter warnings will vanish, too. You can directly call the show usages action directly from the JSP or the POJO.

This also works with JSF and particularly within JSF components. Pretty neat feature to have this kind of code completion, showing warnings and errors.

Hope that helps you with your switch to Intellij Idea.

Edit: I also reported this finding to a friend wo wrapped the whole thing into a nice blog entry. Maybe you're interested in reading it: open link

Share:
18,117

Related videos on Youtube

NimChimpsky
Author by

NimChimpsky

side hustle : metriculous.network Spring is too bloated, I created my own web app framework Infrequent tweets What if programming languages were methods to eat an orange?

Updated on September 26, 2022

Comments

  • NimChimpsky
    NimChimpsky over 1 year

    To summarize the answer shown here Code assist in (jsp /jstl) view for Spring MVC model objects in Eclipse is not working for me at all, is there a setting that I need to change ?

    I have just downloaded the sample spring-mvc-showcase on github, and it doesn't work out of the box on that project (with either 11.1.3 or EAP 12 version both full enterprise editions), see below (I have no idea where it gets formBean from) :

    fruit and foo, both work, but not available as autocomplete options

    Here is an example from my own project,the screen shot below (bottom frame) shows my controller adding a string attribute to model and returning correct view name. I would then expect shopString to be offered up as autocomplete option when editing that view, however it is not : JSP shown abover controller, the autocomplete offered up when "s" typed

    sg is a javascript variable - so great it should be there, but where is "shopString" ?. Is there a setting I need to change or something else I am missing to get this functionality (using 11.1.3 enterprise edition with all the spring plugins).

    It is also failing on spring specific variables : enter image description here

    IS their an open source (one of the spring tutorial projects?) where this definitely works ... or is there a setting I need change in my Intellij install (I have tested with a brand new download of the version 12 EAP) ?

    One more screenshot below shows all my spring coifg files set up correctly via autodetection, but the code inspections fails ... this is the spring-mvc-showcase project : code inspection and spring config

    • NimChimpsky
      NimChimpsky over 11 years
      @duffymo have you actually got this feature working, I have just tried with a clean install of the EAP v12 release and the spring-mvc sample project on github. It doesn't work ... updated the question.
  • NimChimpsky
    NimChimpsky over 11 years
    Ok so I needed to add one line <%--@elvariable id="foo" type="com.mycompany.SomeObject"--%>. I still think it shoul dbe possibel to do it automatically, in the corner case you outlined you could just make available to "page" and "someOtherPage" two options for variable "model" each option would have a different type : foo and bar.
  • NimChimpsky
    NimChimpsky over 11 years
    I actually read that blog and posted a comment, I incorrectly assumed there was a way to get it to work without the added intellij specific comment. Bounty on its way ...
  • NimChimpsky
    NimChimpsky over 11 years
    Thanks, but the useBean tag also instantiates the bean which is unnecessary : stackoverflow.com/a/1855580/106261 but yes it does then enable the features I was lacking.
  • Pakka Pakka
    Pakka Pakka over 11 years
    It does not instantiate anything when using type. That's what the class attribute is for.
  • NimChimpsky
    NimChimpsky over 11 years
    Also, if spring recommend it in their books maybe they should put it in the example projects too. Is their any downside to adding this declaration to top of page, i think its preferable (to other solution) as it is ide-independent and achieves the same functionality
  • Pakka Pakka
    Pakka Pakka over 11 years
    One potential downside is that there might be some corner cases when specifying a generic type using <jsp:useBean>. I've seen some servlet containers other than Tomcat complain about such type declarations. If such cases, you might want to use the IntelliJ-specific declaration comments. I think that IDEA might also provide a way to have such declarations outside of the actual JSP file as well. At least, such an "external comment" feature exists for Freemarker and Velocity templates, I'm not 100% sure about JSP.