All my attempts to get a working example of both, pure restful configuration together with at least one non-restful URL failed.
I have this page as a guide: https://cwiki.apache.org/confluence/display/WW/REST+Plugin
I have one model, Receipt
with a few test fields.
The pure REST solution works as expected, so doing this:
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
<constant name="struts.devMode" value="true"/>
<constant name="struts.mapper.class" value="rest" />
<constant name="struts.convention.action.suffix" value="Controller"/>
<constant name="struts.convention.action.mapAllMatches" value="true"/>
<constant name="struts.convention.default.parent.package" value="rest-default"/>
<constant name="struts.convention.package.locators" value="controllers"/>
works well with these results:
receipt.json
=> display the list of all the receipts
receipt/1.json
=> display the receipt with id = 1
But if I try to mix restful with non-restful URLs, (the same way I'm told to in the wiki article) like this:
<constant name="struts.action.extension" value="xhtml,,xml,json,action"/>
<constant name="struts.mapper.class" value="org.apache.struts2.dispatcher.mapper.PrefixBasedActionMapper" />
<constant name="struts.mapper.prefixMapping" value="/rest:rest,:struts"/>
<constant name="struts.convention.action.suffix" value="Controller"/>
<constant name="struts.convention.action.mapAllMatches" value="true"/>
<constant name="struts.convention.default.parent.package" value="rest-default"/>
<constant name="struts.convention.package.locators" value="controllers"/>
it blows up with this:
Struts has detected an unhandled exception:
Messages:
com.immaculate.receipto.controllers.ReceiptController.execute()
File: java/lang/Class.java
Line number: 1,778
I am confused. Why is it searching for execute()? execute() should be a method present on actions. I'm not giving it an action, I'm giving it a controller like before.
How do I fix this?
Here's the ReceiptController
:
public class ReceiptController implements ModelDriven<Object> {
private ReceiptManager receiptManager = new ReceiptManager();
private String id;
private Receipt model = new Receipt();
private Collection list;
public Object getModel(){
if(list==null){
return model;
} else {
return list;
}
}
public HttpHeaders create() {
receiptManager.save(model);
return new DefaultHttpHeaders("show");
}
public HttpHeaders show() {
model = receiptManager.find(id);
return new DefaultHttpHeaders("show");
}
public HttpHeaders destroy() {
model = receiptManager.destroy(id);
return new DefaultHttpHeaders("show");
}
public HttpHeaders index() {
list = receiptManager.list();
return new DefaultHttpHeaders("show");
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
Obviously I'm doing something wrong here. Do I need to know something else besides what's explained here?
Also, how do I read this? :
<constant name="struts.mapper.prefixMapping" value="/rest:rest,:struts"/>
Does this mean that everything starting with /rest
will map to my pure restful controller that will, in turn map to my receipt and anything without the /rest
prefix will map to the default struts mappings? or am I going entirely in the wrong direction here?
Prefix based action mapper delegates finding mapping to the corresponding mapper defined by the
<constant name="struts.mapper.prefixMapping" value="/rest:rest,:struts"/>
This means all URLs that have /rest
in the URL before the last slash /
are mapped to the rest mapper, others to the default mapper. If you have a receipt
controller, then you should use the value "/receipt:rest,:struts"
.
References: