REST and non-RESTful URL's Together doesn'

2019-03-31 06:23发布

问题:

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?

回答1:

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:

  • REST Plugin
  • RestfulActionMapper
  • PrefixBasedActionMapper


回答2:

I am also had the same error, i fix it by adding

<package name="api" namespace="/api" extends="rest-default">
    <action name="users/*" class="com.aurum.struts.rest.UserController">
        <param name="id">{1}</param>
    </action>
</package>

complete example for REST and Non-REST action together is here https://github.com/sivailango/struts2-rest-nonrest