Struts 2处理Dojo Ajax请求的一点经验

4 篇文章 0 订阅

从Struts 1到Struts 2,从Dojo 1.5到Dojo 1.7、1.8,技术一直在进步,经验却需要时时更新。对于Web应用中最常碰到的Ajax请求处理,新版本的Struts 2和dojo 1.7做法就和以前不一样(在JAVA servlet中返回不同类型的AJAX response)。现在就拿一个例子说明如何从前台用Dojo通过Ajax请求将Json数据送回后台,后台检测后返回信息;顺便也看看到底新技术进步在哪里。

 

例子:前台录入人员信息,并保存到后台,后台返回保存后的id。

 

1. 在主页上增加一个按钮,点击时打开填写人员信息的对话框

main.jsp

<div style="width: 100%;">
		<button id="new_person_btn" data-dojo-type="dijit.form.Button"
			type="button">New Person</button>
	</div>
<div class="dijitHidden">
		<div data-dojo-type="test.person" style="width: 400px;"
			id="new_person_dlg"></div>
	</div>
<script>
		require([ "dojo/ready", "dojo/on", "dijit/registry"],
				function(ready, on, registry) {
					ready(function() {

						var new_person_btn = registry.byId("new_person_btn");
						on(new_person_btn, "click", function(evt) {
							registry.byId("new_person_dlg").show();
						});

					});

				});
	</script>

2. 对话框页面,可以填写人员姓名、描述、是否正式员工

person.jsp

<div data-dojo-type="dijit.form.Form" id="new_person_form"
	data-dojo-id="new_person_form" encType="multipart/form-data">
	<table cellspacing="10" style="width: 100%">
		<tr>
			<td><label for="name">Name:</label></td>
			<td><input type="text" id="new_person_name" name="name"
				style="width: 100%" required="true"
				data-dojo-type="dijit.form.ValidationTextBox" /></td>
		</tr>
		<tr>
			<td><label for="description">Description:</label></td>
			<td><textarea id="new_person_description" name="description"
					data-dojo-type="dijit.form.SimpleTextarea" rows="4"
					style="width: 99%"></textarea></td>
		</tr>
		<tr>
			<td><label for="regular">Regular:</label></td>
			<td>
				<div data-dojo-type="dojo.store.Memory" data-dojo-id="new_person_regular_store"
					data-dojo-props="data: [{id: 'y', name: 'yes'}, {id: 'n', name: 'no'}]"></div>
				<input data-dojo-type="dijit.form.ComboBox" value="yes" style="width: 100%" 
				data-dojo-props="store:new_person_regular_store, searchAttr:'name'" name="regular"
				id="new_person_regular" />
			</td>
		</tr>
	</table>
	<div style="text-align: right; margin-right: 6px;">
		<button id="new_person_submit_btn" data-dojo-type="dijit.form.Button">OK</button>
		<button id="new_person_cancel_btn" data-dojo-type="dijit.form.Button">Cancel</button>
	</div>
</div>

3. 对话框对应的JavaScript对象,里面包含了所有对话框相关的JS代码和事件处理。这些代码也可以放在person.jsp中,但鉴于分离视图和控制逻辑有诸多好处(MVC框架中的模型-视图分离问题(一) —— “你必将业务逻辑由显示中分离”),这儿还是分开吧。

person.js

define([ "dojo/_base/declare", "dijit/Dialog", "dijit/_WidgetBase",
		"dijit/_TemplatedMixin", "dojo/on", "dijit/registry", "dojo/_base/xhr",
		"dijit/form/Form", "dijit/form/ValidationTextBox",
		"dijit/form/SimpleTextarea", "dojo/store/Memory", "dijit/form/ComboBox"], function(declare, Dialog, _WidgetBase,
		_TemplatedMixin, on, registry, xhr) {
	return declare("test.person",
			[ Dialog, _WidgetBase, _TemplatedMixin ], {
				title : "New Person",

				postCreate : function() {
					this.set('href', "dialog_newperson.action");

					this.inherited(arguments);
				},

				onDownloadEnd : function() {
					var new_person_form = registry.byId("new_person_form");
					var new_person_submit_btn = registry
							.byId("new_person_submit_btn");
					on(new_person_submit_btn, "click", function(evt) {
						if (!new_person_form.validate()) {
							return false;
						}

						/*为了让后台认识json格式的数据,这儿有几个地方需要注意的。*/
						
						var data = {
							person : dojo.formToObject("new_person_form")
						};
						// Post the data to the server
						xhr.post({
							url : "submit_newperson.action",
							handleAs : "json",
/*注意点1:json数据必须转成json格式*/
/*注意点2:json数据要放在postData中,而不是content中*/
							postData : dojo.toJson(data),
/*注意点3:设置contentType为application/json */
							contentType : 'application/json; charset=utf-8',
							handle : function(response, ioArgs) {
								return response;
							}
						});
					});

					var new_person_cancel_btn = registry
							.byId("new_person_cancel_btn");
					on(new_person_cancel_btn, "click", function(evt) {
						registry.byId("new_person_dlg").hide();
					});

					this.inherited(arguments);
				}
			});
});

4. 为了让Struts 2能认识json格式的数据,需要引入struts2-json-plugin包。这儿用Maven管理项目,就可以直接在pom文件中加入相应dependency。如果不用Maven,则直接将jar包加入到项目buildpath中。

pom.xml

<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-json-plugin</artifactId>
			<version>2.3.12</version>
		</dependency>

5. 重点!struts.xml中需要进行相应配置

struts.xml

<!--注意点1:在package的extends里,必须有json-default -->
<package name="workbench" namespace="/"
		extends="struts-default,json-default">
		<action name="submit_newperson" class="test.SubmitNewPersonAction">
			<!--注意点2:在action里,加入json interceptor信息 -->
			<interceptor-ref name="json">
				<param name="contentType">application/json</param>
			</interceptor-ref>
			<!--注意点3:设置result为json格式 -->
			<result type="json">
				<!--注意点4:设置result包含的内容。这儿只包含result变量的数据,而没有person的数据 -->
				<param name="includeProperties">result</param>
			</result>
		</action>
	</package>

6. 保存人员信息的java对象

Person.java

public class Person {
	private String name;
    private String description;
    private String regular;
    
    public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getRegular() {
		return regular;
	}

	public void setRegular(String regular) {
		this.regular = regular;
	}
}

7. 相应的action。接收传入的人员数据,返回相应的id

TestAction.java

public class TestAction extends ActionSupport {

	private static final long serialVersionUID = 1L;

	private int result;
	 
    private Person person;
    
    public void setPerson(Person person) {
		this.person = person;
	}

	public Person getPerson() {
		return person;
	}

	@Override
	public String execute() {
		System.out.println(person);

		int result = savePerson(person);
		return SUCCESS;
	}

	public int getResult() {
		return result;
	}

}

8. 最后返回的Response:

{"result":1}

总结

相比较Struts 1而言,Struts 2在处理接收的数据方面,确实有很大的改进。数据传送到后台后,不需要手工写代码解析json格式的数据,只要schema一致,就可以用相应的POJO对象接收。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值