您的位置:首页 > 其它

WebX实践指南_请求处理(一)

2015-11-26 16:03 344 查看
通过WebX入门指南,相信大家都能开始尝试添加自己的处理页面了。基本上能够完成简单的页面设计了。我们通常说网站是B/S架构的,那这种模式只要掌握前后端的分工和交互,就能游刃有余。因此,本节就从前后端交互方式来说明如何实现高效的代码设计。

前后端交互方式

Http协议请求方法

这一节的详细内容请参考HTTP权威指南,这里只关注WebX中如何实现交互。

网站的前后端交互,都是通过HTTP协议实现的,因此网站的前后端交互也是在HTTP协议下展开的,因此前端的交互模式也受限于通信协议,标准的协议中支持的请求方式有get、post、put、delete、head、options。WebX框架中通过Servlet来处理具体的业务逻辑处理。关于Servlet的知识,后面讲解WebX原理时,再做说明。

Request

get: 获取资源,例如html网页、图片、视频等

head:本质上和get一样,不过请求中不包含数据信息

put: 提交请求,表单不支持,通常要指定资源的地址

post: 向服务端提交数据

delete: 用于删除资源文件,很少用

options: 询问服务端支持的请求方式,请求的结果保存在Allow的协议头中。

Response

每一次HTTP请求,通常都有对应的HTTP响应,消息返回结果通常包含Request处理的状态信息,以及返回结果的格式信息。

返回结果支持的格式有(Context-Type)种类很多,常见的有:

[参考]: /article/7826852.html

常见的媒体格式类型如下:

text/html : HTML格式
text/plain :纯文本格式
text/xml :  XML格式
image/gif :gif图片格式
image/jpeg :jpg图片格式
image/png:png图片格式


以application开头的媒体格式类型:

application/xhtml+xml :XHTML格式
application/xml     : XML数据格式
application/atom+xml  :Atom XML聚合格式
application/json    : JSON数据格式
application/pdf       :pdf格式
application/msword  : Word文档格式
application/octet-stream : 二进制流数据(如常见的文件下载)
application/x-www-form-urlencoded : <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)


另外一种常见的媒体格式是上传文件之时使用的:

multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式


对一个Http请求,用户只需要通过解析Request请求,并返回处理结果Response。只不过这里的Request和Respose是满足HTTP协议的消息。因此,大家可以简单地把这个过程理解成一个函数调用:

Response get/post/ (Request request);
//把request, response简单地理解成遵循HTTP协议的结构体


WebX中如何处理Request && Response

WebX中处理请求是通过Module来实现的,包括了Screen、Control以及Action三类。具体的实现中是通过HttpServletRequest、HttpServletResponse以及HttpServletSession对象来完成的。当然WebX的实现中,对相关的Servlet进行了其他的处理。后续的文章中再讲解。

WebX中的请求响应处理

WebX中请求响应处理时,之前的使用都是从页面驱动来认识的。现在从Request/Response角度看下。只需要在对应的Module对象中注入Servlet对象就可以使用了。关于对象注入可以去看下Spring相关的知识。

举例说明:

场景:通过http://localhost:8081/user/get_user_name.do?userId=10000,获取用户名

在讲解代码实现之前,对上述的URL路径做下解析,WebX在处理该请求时,会对该路径进行解析,获取对应的Target,用于加载对应的处理方法。这里target后缀是.do,默认的会去查找对应的Screen/Action对象。查找时,对于该路径可能的两种解释是 user下的GetUserName对象或者是User对象的doGetUserName方法。WebX会先按第一中方法解析,失败后换第二种方法解析,如果再找不到对应的方法,报错。在之前的Screen对象中我们看到的对象方法往往只有一个 execute()方法,实际上在调用一个对象时,如果不指定对象的方法名,默认采用的就是execute方法。

实现:/screen目录下新建一个User对象,实现getUserName(int userId)方法

public class User {

@Autowired
private HttpServletResponse response;
@Autowired
private HttpServletRequest request;

public void doGetUserName() throws IOException {
String userId = request.getParameter("userId");
//response.setContentType("text/plain");
System.out.println("userId is " + userId);
//do  something

//response
PrintWriter writer = response.getWriter();
writer.write("get user name!!");
}
}


WebX中的 Screen对象使用说明

Response结果的处理可以通过两种方式,一种方式.do的方式,如上例所示通过response.write()返回处理结果。可以通过response.setContentType(“application/json”);以及response.addHeader(“Cache-Control”);设置对应的来设置返回结果的格式。也可以直接返回结果对象: http://localhost:8081/user/get_user_name.json?userId=10000

public class User {
@Autowired
private HttpServletRequest request;

public UserResult doGetUserName() throws IOException {
String userId = request.getParameter("userId");
//response.setContentType("text/plain");
System.out.println("userId is " + userId);
//do  something

//result
UserResult userResult = new UserResult();
userResult.setName("liujie");
userResult.setStateCode(1);
userResult.setErrorMsg("success");
return userResult;
}
}

class UserResult {
private int stateCode;
private String errorMsg;
private String name;

public int getStateCode() {
return stateCode;
}
public void setStateCode(int stateCode) {
this.stateCode = stateCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}


可以看到以上两种交互中和以往的页面驱动设计是不同的,以往的页面驱动的场景多是获取页面资源,而这两个场景更多的是提交任务,反馈结果,更类似于函数调用。具体的使用中这两种场景多用于获取对象数据,而不是资源文件。

WebX中的Action对象使用说明

Action主要用于表单的处理,本例使用了WebX示例程序中的注册来讲解。一个典型的表单包括了一下几部分:

<form name="input" action="/login.htm" method="post">
Username:
<input type="text" name="user" />
<input type="submit" value="Submit" />
</form>


对于 WebX中典型的表单:

<form action="$app1Link.setTarget("form/register")" method="post">
$csrfToken.hiddenField
<input type="hidden" name="action" value="register_action"/>
#set ($group = $form.register.defaultInstance)

<p>Hello, what's your name?</p>
#if (!$group.name.valid)
<p>$group.name.message</p>
#end

<p>
<input type="text" name="$group.name.key" value="$!group.name.value"/>
<input type="submit" name="event_submit_do_register"/>
</p>
</form>


input action值用于表明action对象, submit按钮中的event_submit_do_register注明处理该表单的方法是doRegister()。$group变量是通过WebX的form service提供的,需要通过表单配置完成。关于WebX服务见后续的详细讲解。接下来设计对应的Action对象,其实他和普通的对象也一样:

public class RegisterAction {
public void doRegister(@FormGroup("register") Visitor visitor) {
String name = visitor.getName();
nav.redirectTo("app1Link").withTarget("form/welcome").
withParameter("name", name);
}
}


这里先不关注怎么用,只是说明调用的逻辑关系。调用之后,怎么将结果返回呢?这里只是用了界面跳转,如果开发者想知道添加一个用户是否成功怎么办呢?目前没有发现好的方法,即使可以注入HttpServletResponse。 这个和Action的定位和设计应该是有关系的。Action用于页面表单数据和应用数据的传递,以及页面的跳转,因此在使用时也尽量以这种方式实现。而且在实际的应用中,大家多是以跳转的方式来实现的。比如注册、或者添加新的数据后通过,页面跳转回原页面,刷新页面,从而验证操作的结果,而不需要返回一个成功的标志。这一点不知道读者怎么理解?

各种交互场景下的代码设计

通过对Action、Control、Screen的介绍中,相信基本的使用场景和场合都有所了解了。对于一般的get请求,使用Templates和Screen Module就可以完成基本的页面渲染。对于一些业务数据的处理和返回,数据资源的查找可以通过Screen返回值或者Response Write的方式完成。对于设计数据的增、删、改操作,通过表单实现,这里的缺陷是,如何将操作的结果返回给客户端。

好吧,这里就不再总结各种场景了,上面的讲解中都有涉及到,就不再赘述,读者可以自己再整理整理。通过对交互场景的介绍,前后端的代码交互就有了,接下来就单独看看前后端开发的一些技术。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: