Not using .form suffix on controller URLs

Hi all,

I wrote a headless controller (no fragment, no page):

@Controller
public class MyController {

  @RequestMapping(value = "/my/custom/url", method = RequestMethod.GET)
  public void doWhatever(...) {
    ...
  }
  ...
}

And it works, except that I have to append .form to the URL mapping to get there:

/openmrs/my/custom/url.form

Why is that and how can I prevent this behaviour in order to define 100% custom URLs?

Note: Ridding it of @Controller would make it return an error 404 on both the desired and .form’d URL.

This isn’t possible in the general case. You can see which file extensions are mapped to the OpenMRS servlet here:

Any URL under /ws is mapped (regardless of file extension). This is intended for web services. So, you can map an arbitrary url, as long as it starts with ws/

Thanks @darius, although it makes perfect sense, it hasn’t worked. I just prefixed my former URL with /ws as you suggested and I’m still getting an error 404 on it (with or without the .form suffix this time.) Is there anything else to configure anywhere?

Can you paste your code here?

Hi @willa , it was in my first post actually.

But things haved changed a little, I only need to do this on a POST controller method, so basically this is what I have now:

@Controller
public class MyController {    

  @RequestMapping(value = "/my/custom/url", method = RequestMethod.POST)
  @ResponseBody
  public Object doSomething(HttpServletRequest request) 
  {
    ...
  }
  ...
}
  • When value = "/my/custom/url" it can be accessed at /openmrs/my/custom/url.form
  • When value = "/ws/my/custom/url" I get an error 404 with or without .form.

I actually think it’s a bad idea to have your URLS have /ws because by convention that is reserved for webservices calls, why can’t you just append .form or .htm to your URL and not have to break conventions or go through hacks?

Well it is not a REST webservice, but it is a webservice nonetheless.

But yes sure, I can live with the .form suffix, I was just asking as I thought I was missing something (I still don’t understand why it doesn’t work with /ws though).

If it’s a web service, then I guess you need to use /ws, you shared the Controller code and not the code where you make the web service call, can you share it too?

@maurya I remember there is something that needs to be done to make this work and we had to do it at some point. If you do remember that “something” please assist us here otherwise I will have to dig somewhere :frowning:

@willa, thanks I really appreciate. I’ll be waiting for updates on this thread then.

There is nothing special that needs to be done, I think you’re using an incorrect URL when making the http request, if your controller is mapped to /my/custom/url then in your browser the URL you need to enter should be /openmrs/ws/my/custom/url

1 Like

I believe you meant /ws/my/custom/url?


As I said earlier this all works fine when the /ws prefix is not used and that I append the .form suffix. Moreover the URL is set in one unique place in a constants class:

public class MyModuleConstants {

  public static final String SERVICE_URL = "/my/custom/url";
  //  public static final String SERVICE_URL = "/ws/my/custom/url";
  ...
}

That’s the constant in use for the service-controller’s mapping:

@RequestMapping(value = MyModuleConstants.SERVICE_URL, ...)

Then it is provided to an Angular page through a JSON config object via the page Spring controller:

jsonConfig.put("serviceUrl", MyModuleConstants.SERVICE_URL);

So when the page loads, this unique URL is provided to and known by the client side as per the unique configuration through the constants class. It is finally stored in a config objet that is used all over my Angular controllers:

var config = ${jsonConfig};
config.serviceUrl = '/' + OPENMRS_CONTEXT_PATH + config.serviceUrl + '.form';
// config.serviceUrl = '/' + OPENMRS_CONTEXT_PATH + config.serviceUrl;

All this to say that when I want to change the whole thing to using the /ws prefix, it happens in one, and only one, place. Then I can play around in JS and add/remove the + '.form' to see whether things keep working or not. I left above the comments at the two places where I switch back & forth from a config to the other.

You need to read my previous comment well, if you do that it should be able to work without the .form

See

You don’t explicitly say ws.

-Darius (by phone)

Ok I thought that I had to request the mapping this way, I misunderstood this.

Thanks @wyclif, it works now.

That’s exactly what I was saying, /ws/** is already mapped to the OpenMRS SpringDispatcherServlet, so spring based controllers under the the /ws prefix don’t have to include it again in the request mapping value since that gets stripped off by spring just like you don’t include .form in your request mapping value because spring strips it off but you need to include it in the URL you enter in the browser.

Exactly, this is something I learned the hard way when trying to use /ws/**. Unfortunately I forgot about. I think we could have it documented somewhere?

2 Likes