fix 404 and 500 when there are grouped services (#669)

fix apache#61

fix apache#540
diff --git a/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/RouterController.java b/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/RouterController.java
index adf04d3..9f5a9e2 100644
--- a/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/RouterController.java
+++ b/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/RouterController.java
@@ -94,16 +94,21 @@
         return appActionWithIdandAction(null, null, type, id, action, request, response, model);
     }
 
-
     // service mapping
-    @RequestMapping("/governance/services/{service}/{type}")
+    @RequestMapping("/governance/services/{service}/{type:providers|consumers|accesses|weights|overrides|owners|applications|loadbalances|routes}")
     public String servicerRouter(@PathVariable("service") String service, @PathVariable("type") String type,
                                  HttpServletRequest request, HttpServletResponse response, Model model) {
         model.addAttribute("service", service);
         return appRouter(null, "services", service, type, request, response, model);
     }
 
-    @RequestMapping("/governance/services/{service}/{type}/{action}")
+    @RequestMapping("/governance/services/{group}/{service}/{type:providers|consumers|accesses|weights|overrides|owners|applications|loadbalances|routes}")
+    public String servicerRouter(@PathVariable("group") String group, @PathVariable("service") String service, @PathVariable("type") String type,
+                                 HttpServletRequest request, HttpServletResponse response, Model model) {
+        return servicerRouter(group + "/" + service, type, request, response, model);
+    }
+
+    @RequestMapping("/governance/services/{service}/{type:providers|consumers|accesses|weights|overrides|owners|applications|loadbalances|routes}/{action}")
     public String serviceAction(@RequestParam Map<String, String> param,
                                 @PathVariable("service") String service, @PathVariable("type") String type,
                                 @PathVariable("action") String action, HttpServletRequest request,
@@ -116,7 +121,15 @@
         return appAction(param, null, "services", service, type, action, request, response, model);
     }
 
-    @RequestMapping("/governance/services/{service}/{type}/{id}/{action}")
+    @RequestMapping("/governance/services/{group}/{service}/{type:providers|consumers|accesses|weights|overrides|owners|applications|loadbalances|routes}/{action}")
+    public String serviceAction(@RequestParam Map<String, String> param,
+                                @PathVariable("group") String group, @PathVariable("service") String service, @PathVariable("type") String type,
+                                @PathVariable("action") String action, HttpServletRequest request,
+                                HttpServletResponse response, Model model) {
+        return serviceAction(param, group + "/" + service, type, action, request, response, model);
+    }
+
+    @RequestMapping("/governance/services/{service}/{type:providers|consumers|accesses|weights|overrides|owners|applications|loadbalances|routes}/{id}/{action}")
     public String serviceActionWithId(@RequestParam Map<String, Object> param,
                                       @PathVariable("service") String service,
                                       @PathVariable("type") String type, @PathVariable("id") String id,
@@ -136,7 +149,15 @@
         return appActionWithIdandAction(app, service, type, id, action, request, response, model);
     }
 
-    // app mapping all execute goes here
+    @RequestMapping("/governance/services/{group}/{service}/{type:providers|consumers|accesses|weights|overrides|owners|applications|loadbalances|routes}/{id}/{action}")
+    public String serviceActionWithId(@RequestParam Map<String, Object> param,
+                                      @PathVariable("group") String group, @PathVariable("service") String service,
+                                      @PathVariable("type") String type, @PathVariable("id") String id,
+                                      @PathVariable("action") String action, HttpServletRequest request, HttpServletResponse response, Model model) {
+        return serviceActionWithId(param, group + "/" + service, type, id, action, request, response, model);
+    }
+
+        // app mapping all execute goes here
     //@RequestMapping("/governance/applications/{app}/services/{ids}/{action}")
     //public String serviceActionWithApp(@PathVariable("app") String app, @PathVariable("ids") String ids,
     //                                   @PathVariable("type") String type, HttpServletRequest request,
@@ -290,7 +311,6 @@
         return "";
     }
 
-
     @RequestMapping("/governance/applications/{app}/services/{service}/{type}/{id}/{action}")
     public String appActionWithIdandAction(@PathVariable("app") String app, @PathVariable("service") String service,
                                @PathVariable("type") String type, @PathVariable("id") String id,
diff --git a/dubbo-admin/src/main/resources/templates/governance/screen/consumers/index.vm b/dubbo-admin/src/main/resources/templates/governance/screen/consumers/index.vm
index 9965bb5..1f2ce7c 100644
--- a/dubbo-admin/src/main/resources/templates/governance/screen/consumers/index.vm
+++ b/dubbo-admin/src/main/resources/templates/governance/screen/consumers/index.vm
@@ -126,7 +126,7 @@
         <tr>
             <td><input type="checkbox" name="ids" value="$consumer.id"/></td>
             <td>
-                <a href="consumers/$consumer.id">#if($address)$tool.getSimpleName($consumer.service)#else$consumer.address#end</a>
+                <a href="$rootContextPath.getURI("/governance/")consumers/$consumer.id">#if($address)$tool.getSimpleName($consumer.service)#else$consumer.address#end</a>
             </td>
             <td>$consumer.application</td>
             <td>
@@ -148,14 +148,14 @@
             </td>
             <td>
                 #if($consumer.routes && $consumer.routes.size() > 0)
-                    <a href="consumers/$consumer.id/routed">#springMessageText("routed", "routed")($consumer.routes.size())</a>
+                    <a href="$rootContextPath.getURI("/governance/")consumers/$consumer.id/routed">#springMessageText("routed", "routed")($consumer.routes.size())</a>
                 #else
                     <font color="gray">#springMessageText("unrouted", "unrouted")</font>
                 #end
             </td>
             <td>
                 #if($consumer.providers && $consumer.providers.size() > 0)
-                    <a href="consumers/$consumer.id/notified">#springMessageText("notified", "notified")($consumer.providers.size())</a>
+                    <a href="$rootContextPath.getURI("/governance/")consumers/$consumer.id/notified">#springMessageText("notified", "notified")($consumer.providers.size())</a>
                 #else
                     <font color="red">#springMessageText("noProvider", "noProvider")</font>
                 #end
@@ -163,7 +163,7 @@
             #if($currentUser.role != "G")
                 <td>
                     #if($currentUser.hasServicePrivilege($consumer.service))
-                        <a href="consumers/$consumer.id/edit"><img src="$rootContextPath.getURI("images/ico_edit.png")"
+                        <a href="$rootContextPath.getURI("/governance/")consumers/$consumer.id/edit"><img src="$rootContextPath.getURI("images/ico_edit.png")"
                                                                    width="12" height="12"/><span
                                 class="ico_font">#springMessageText("edit", "edit")</span></a>
                         <span class="ico_line">|</span>
diff --git a/dubbo-admin/src/main/resources/templates/governance/screen/providers/index.vm b/dubbo-admin/src/main/resources/templates/governance/screen/providers/index.vm
index b10dff3..e608052 100644
--- a/dubbo-admin/src/main/resources/templates/governance/screen/providers/index.vm
+++ b/dubbo-admin/src/main/resources/templates/governance/screen/providers/index.vm
@@ -15,7 +15,7 @@
 #set($layout = "/templates/governance/layout/default.vm")
 <div class="ico_btn">
     #if($currentUser.role != "G")
-        <a href="providers/add"><img src="$rootContextPath.getURI("images/ico_add.png")" width="12" height="12"/><span
+        <a href="$rootContextPath.getURI("/governance/")providers/add"><img src="$rootContextPath.getURI("images/ico_add.png")" width="12" height="12"/><span
                 class="ico_font">#springMessageText("add", "add")</span></a>
         <span class="ico_line">|</span>
         <a href="#" onclick="if(! hasCheckbox('ids')) { showAlert('#springMessageText(
@@ -94,7 +94,7 @@
         <tr>
             <td><input type="checkbox" name="ids" value="$provider.id"/></td>
             <td>
-                <a href="providers/$provider.id">#if($address)$tool.getSimpleName($provider.service)#else$provider.address#end</a>
+                <a href="$rootContextPath.getURI("/governance/")providers/$provider.id">#if($address)$tool.getSimpleName($provider.service)#else$provider.address#end</a>
             </td>
             <td>$tool.getProviderWeight($provider)</td>
             <td>#if($provider.dynamic)<font color="green">#springMessageText("dynamic", "dynamic")</font>#else<font color="blue">#springMessageText(
@@ -137,11 +137,11 @@
             #if($currentUser.role != "G")
                 <td>
                     #if($currentUser.hasServicePrivilege($provider.service))
-                        <a href="providers/$provider.id/edit"><img src="$rootContextPath.getURI("images/ico_edit.png")"
+                        <a href="$rootContextPath.getURI("/governance/")providers/$provider.id/edit"><img src="$rootContextPath.getURI("images/ico_edit.png")"
                                                                    width="12" height="12"/><span
                                 class="ico_font">#springMessageText("edit", "edit")</span></a>
                         <span class="ico_line">|</span>
-                        <a href="providers/$provider.id/add"><img src="$rootContextPath.getURI("images/ico_add.png")"
+                        <a href="$rootContextPath.getURI("/governance/")providers/$provider.id/add"><img src="$rootContextPath.getURI("images/ico_add.png")"
                                                                   width="12" height="12"/><span
                                 class="ico_font">#springMessageText("copy", "copy")</span></a>
                         <span class="ico_line">|</span>
diff --git a/dubbo-admin/src/main/resources/templates/governance/screen/services/index.vm b/dubbo-admin/src/main/resources/templates/governance/screen/services/index.vm
index e49d55a..46fc352 100644
--- a/dubbo-admin/src/main/resources/templates/governance/screen/services/index.vm
+++ b/dubbo-admin/src/main/resources/templates/governance/screen/services/index.vm
@@ -18,9 +18,9 @@
 #elseif($keyword && $services.size() == 1)
 <script type="text/javascript">
         #if(! $providerServices.contains($services.iterator().next()))
-        window.location.href = "services/$services.iterator().next()/consumers";
+        window.location.href = '$rootContextPath.getURI("/governance/")services/$services.iterator().next()/consumers';
         #else
-        window.location.href = "services/$services.iterator().next()/providers";
+        window.location.href = '$rootContextPath.getURI("/governance/")services/$services.iterator().next()/providers';
         #end
 </script>
 #else
@@ -87,9 +87,9 @@
             <td><input type="checkbox" name="ids" value="$service"/></td>
             <td>
                 #if(! $providerServices.contains($service))
-                    <a href="services/$service/consumers">$service</a>
+                    <a href="$rootContextPath.getURI("/governance/")services/$service/consumers">$service</a>
                 #else
-                    <a href="services/$service/providers">$service</a>
+                    <a href="$rootContextPath.getURI("/governance/")services/$service/providers">$service</a>
                 #end
             </td>
             <td>