Struts, Ajax, Restful, and Web Service (III)

Source: Internet
Author: User

In the first article, I said that the framework should be written on the URL. Yes, this article describes how the framework makes full use of the url as much as possible.

Web development cannot be unfamiliar with URLs. As early as the web era, as a unified resource locator, URLs play a huge role in obtaining web resources. No matter when a user requests a static page or various images or script files, the url can always get the resources to be accessed from the web site. Web2.0 is often used as a get request parameter to pass url, such as http://xxx.xxx.xxx/xxx.jsp? User = admin. In recent years, restful web service has abandoned soap and uses url to transmit request parameters, which shows the feasibility and popularity of rational use of URLs.

Of course, it is not only a good practice to use URLs, but an elegant way to ensure that the levels and overall conciseness are ensured, this is also the goal of this framework for using URLs.

First, let's look at several examples:

http://www.cnblogs.com/p2
http://www.xxx.com/index.do?page=2

http://www.xxx.com/product/
http://www.xxx.com/channel.do?channel=product

http://www.xxx.com/product/mobile
http://www.xxx.com/channel.do?channel=product&&subChannel=mobile

I believe that you can understand the implementation of these groups without having to say it. The first implementation method is better. Aside from the technology that can shield the server, it can better describe the layered structure of dynamic websites, so that users can clearly know the location of the website during access, instead, I don't think it's a maze.

Of course, the examples listed above are the url Representations used by the website front-end. Because the expressions can be varied and may vary with personal preferences, this framework does not specify the front-end url representation during design, instead, it defines the interface and leaves this right to the user who uses it. The framework will consider more universal things than those with free personality.

 

The following describes in detail the url Router AMPPathRouter used by default in the framework, including the design idea and implementation method. First, AMPPathRouter is used in the background. To understand how it works quickly, we will first compare it with struts.

Struts request Configuration:

 

<action name="login" class="com.lscmjx.action.LoginAction" method="login">
<result name="success">
main.jsp
</result>
<result name="failure">
login.jsp
</result>
</action>

The submitted url will be.

Write it here. Is this the best way? Of course not. At least when I use struts, I think it is a pretty simple design. The above example only lists a login method. If there are 100 methods to be called in the background in a system, isn't it necessary to write 100 similar configurations in struts. xml. Think about it as big as it is. This tedious task should be handled by the framework itself, rather than manually configuring it.

 

Let's look at the configuration of the Unicorn web framework that implements the same function.

 

<action class="com.mh.action.UserAction"></action>

Of course, the submitted url must contain more information to ensure that the methods in the framework Action can be correctly called through the url. Here the submitted url method: http://xxx.xxx.xxx/UserAction/login/

By attaching the information of the called Action class to the url, You can omit the trouble of configuring different methods in xml. If there are 100 methods in UserAction, the framework only needs to configure this line.

With a general understanding, let's look at the specific implementation of AMPPathRouter, the core part of the framework.

 

/**
* The matching rules are as follows:
* 1. The format is in the/Action/method/param Format,
* 2. The Action does exist in actionMap.
* 3. The method exists in this Action.
*/
@ Override
Public boolean route (String relativeUri, UrlFilter urlFilter ){
Map <String, String> actionMap = urlFilter. getActionMap ();
Pattern pattern = Pattern. compile ("^/\ w +/\ S *");
Matcher matcher = pattern. matcher (relativeUri );
// Check whether the url is to be processed by this Router class. The/Action/Method/Param Format will be checked and true will be returned.
If (matcher. matches ()){
String [] params = relativeUri. split ("/");
String actionName = params [1];
String fullActionName = actionMap. get (actionName );
If (null = fullActionName ){
Return false;
}
Try {
Class <?> Clz = Class. forName (fullActionName );
ActionSupport actionSupport = (ActionSupport) clz. newInstance ();
String actionMethodName = params [2];
Method [] methods = clz. getMethods ();
For (int I = 0; I <methods. length; I ++ ){
Method method = methods [I];
String methodName = method. getName ();
If (methodName. equals (actionMethodName )){
// Intercept Action/Method/Param requests and construct the attributes of the ActionSupport class
If (params. length> 3 ){
This. boxingRequest (urlFilter. getRequest (), params [3]);
}
This. initActionSupport (actionSupport, urlFilter );
Return this. invokeActionMethod (actionSupport, method, urlFilter );
}
}
} Catch (ClassNotFoundException e ){
E. printStackTrace ();
} Catch (InstantiationException e ){
E. printStackTrace ();
} Catch (IllegalAccessException e ){
E. printStackTrace ();
}
}
Return false;
}
// Call the method in Action
Private boolean invokeActionMethod (ActionSupport actionSupport, Method method, UrlFilter urlFilter ){
Try {
String result = (String) method. invoke (actionSupport, new Object [] {});
If (null = result | ActionSupport. AJAX. equals (result) | ActionSupport. FORWARD. equals (result) | ActionSupport. WEB_SERVICE.equals (result )){
Return true;
}
If (ActionSupport. REDIRECT. equals (result )){
UrlFilter. getResponse (). sendRedirect (result );
Return true;
}
} Catch (SecurityException e ){
E. printStackTrace ();
} Catch (IllegalAccessException e ){
E. printStackTrace ();
} Catch (IllegalArgumentException e ){
E. printStackTrace ();
} Catch (InvocationTargetException e ){
E. printStackTrace ();
} Catch (Exception e ){
E. printStackTrace ();
}
Return false;
}
/**
* Add the param in the url to the attribute of the request.
* @ Param request
* @ Param parameter
*/
Private void boxingRequest (HttpServletRequest request, String parameter ){
String [] parameters = parameter. split ("&");
For (int I = 0; I <parameters. length; I ++ ){
String param = parameters [I];
String [] key_value = param. split ("= ");
If (key_value.length = 2 ){
Request. setAttribute (key_value [0], key_value [1]);
}
}
}
/**
* Initialize the request, response, session, application, and other objects required in the ActionSupport class.
* @ Param obj
* @ Param urlFilter
*/
Private void initActionSupport (ActionSupport actionSupport, UrlFilter urlFilter ){
ActionSupport. setRequest (urlFilter. getRequest ());
ActionSupport. setResponse (urlFilter. getResponse ());
ActionSupport. setSession (urlFilter. getSession ());
ActionSupport. setApplication (urlFilter. getApplication ());
}

 

This is all about AMPPathRouter, which is implemented through reflection when distributing requests to the subclass of ActionSupport and calling related methods. It is quite easy to understand elsewhere.

It is the only reason to apply the framework to practice:

 

Okay. Next we will introduce Action and json.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.