Netbeans tutorialを使用して、エンティティクラスに基づいてレストサービスを作成しました。その後、残りのリソースは、backbone.jsクライアントによって消費されます。Java EE 7/Glassfish - HTML/Knockout.jsクライアントからではなく、Curlで読み込まれたリソースからのデータ
私が抱えている問題は、html/backbone.jsページに残りのデータをロードさせないjqueryの行があることです。私は、私のブラウザに、または私がそれをカールするときに、リソースアドレスhttp://localhost:8080/mavenproject1/webresources/com.blah.project1.customer
を入力すると、XMLデータを取得できます。
WebページにデータをロードさせるJAX-RS構成ファイルがありますか? Chromeのインスペクタから
Jquery.min.js、問題のある行からは3815です:f.send(a.hasContent && a.data || null)
n.ajaxTransport(function(a) {
var b;
return k.cors || Fc && !a.crossDomain ? {
send: function(c, d) {
var e, f = a.xhr(), g = ++Cc;
if (f.open(a.type, a.url, a.async, a.username, a.password),
a.xhrFields)
for (e in a.xhrFields)
f[e] = a.xhrFields[e];
a.mimeType && f.overrideMimeType && f.overrideMimeType(a.mimeType),
a.crossDomain || c["X-Requested-With"] || (c["X-Requested-With"] = "XMLHttpRequest");
for (e in c)
f.setRequestHeader(e, c[e]);
b = function(a) {
return function() {
b && (delete Dc[g],
b = f.onload = f.onerror = null ,
"abort" === a ? f.abort() : "error" === a ? d(f.status, f.statusText) : d(Ec[f.status] || f.status, f.statusText, "string" == typeof f.responseText ? {
text: f.responseText
} : void 0, f.getAllResponseHeaders()))
}
}
,
f.onload = b(),
f.onerror = b("error"),
b = Dc[g] = b("abort");
try {
f.send(a.hasContent && a.data || null)
} catch (h) {
if (b)
throw h
}
},
abort: function() {
b && b()
}
} : void 0
}),
ページが要求されるたびにGlassFishサーバーログがこれを示しています。私はこれが去年のグラスフィッシュのバグだと知っていますが、クロムがjqueryエラーを表示しているので、私はこのグラスフィッシュが原因ではないとは思いません。
Warning: StandardWrapperValve[com.mycompany.mavenproject1.service.ApplicationConfig]: Servlet.service() for servlet
com.mycompany.mavenproject1.service.ApplicationConfig threw exception
java.lang.NoClassDefFoundError: Could not initialize class org.eclipse.persistence.jaxb.BeanValidationHelper
at org.eclipse.persistence.jaxb.JAXBBeanValidator.isConstrainedObject(JAXBBeanValidator.java:257)
at org.eclipse.persistence.jaxb.JAXBBeanValidator.shouldValidate(JAXBBeanValidator.java:208)
at org.eclipse.persistence.jaxb.JAXBMarshaller.validateAndTransformIfNeeded(JAXBMarshaller.java:587)
at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:481)
at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.writeTo(MOXyJsonProvider.java:949)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:106)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:86)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1130)
at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:683)
at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:424)
at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:414)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:312)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:292)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1139)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:460)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:386)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:334)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
at java.lang.Thread.run(Thread.java:745)
編集:
ときに最初にロードして、エラー、警告の状態このページには、エラー、警告を示しているので:Unable to fulfil the request
、私は負荷障害が何らかの理由でBACKBONE.JSスクリプトのbecuaseたまたま知っています:
var app = {
// Create this closure to contain the cached modules
module: function() {
// Internal module cache.
var modules = {};
// Create a new module reference scaffold or load an
// existing module.
return function (name) {
// If this module has already been created, return it.
if (modules[name]) {
return modules[name];
}
// Create a module and save it under this name
return modules[name] = {Views: {}};
};
}()
};
(function (models) {
// Model for Customer entity
models.Customer = Backbone.Model.extend({
urlRoot: "http://localhost:8080/mavenproject1/webresources/com.mycompany.mavenproject1.customer/",
idAttribute: 'customerId',
defaults: {
city: "",
phone: "",
name: "",
addressline2: "",
creditLimit: "",
addressline1: "",
state: "",
fax: "",
email: ""
},
toViewJson: function() {
var result = this.toJSON(); // displayName property is used to render item in the list
result.displayName = this.get('name');
return result;
},
isNew: function() {
// default isNew() method imlementation is
// based on the 'id' initialization which
// sometimes is required to be initialized.
// So isNew() is rediefined here
return this.notSynced;
},
sync: function (method, model, options) {
options || (options = {});
var errorHandler = {
error: function (jqXHR, textStatus, errorThrown) {
// TODO: put your error handling code here
// If you use the JS client from the different domain
// (f.e. locally) then Cross-origin resource sharing
// headers has to be set on the REST server side.
// Otherwise the JS client has to be copied into the
// some (f.e. the same) Web project on the same domain
alert('Unable to fulfil the request');
}
};
if (method === 'create') {
options.url = 'http://localhost:8080/mavenproject1/webresources/com.mycompany.mavenproject1.customer/';
}
var result = Backbone.sync(method, model, _.extend(options, errorHandler));
return result;
}
});
// Collection class for Customer entities
models.CustomerCollection = Backbone.Collection.extend({
model: models.Customer,
url: "http://localhost:8080/mavenproject1/webresources/com.mycompany.mavenproject1.customer/",
sync: function (method, model, options) {
options || (options = {});
var errorHandler = {
error: function (jqXHR, textStatus, errorThrown) {
// TODO: put your error handling code here
// If you use the JS client from the different domain
// (f.e. locally) then Cross-origin resource sharing
// headers has to be set on the REST server side.
// Otherwise the JS client has to be copied into the
// some (f.e. the same) Web project on the same domain
alert('Unable to fulfil the request');
}
};
var result = Backbone.sync(method, model, _.extend(options, errorHandler));
return result;
}
});
})(app.module("models"));
(function (views) {
views.ListView = Backbone.View.extend({
tagName: 'tbody',
initialize: function (options) {
this.options = options || {};
this.model.bind("reset", this.render, this);
var self = this;
this.model.bind("add", function (modelName) {
var row = new views.ListItemView({
model: modelName,
templateName: self.options.templateName
}).render().el;
$(self.el).append($(row));
$(self.el).parent().trigger('addRows', [$(row)]);
});
},
render: function (eventName) {
var self = this;
_.each(this.model.models, function (modelName) {
$(this.el).append(new views.ListItemView({
model: modelName,
templateName: self.options.templateName
}).render().el);
}, this);
return this;
}
});
views.ListItemView = Backbone.View.extend({
tagName: 'tr',
initialize: function (options) {
this.options = options || {};
this.model.bind("change", this.render, this);
this.model.bind("destroy", this.close, this);
},
template: function (json) {
/*
* templateName is element identifier in HTML
* $(this.options.templateName) is element access to the element
* using jQuery
*/
return _.template($(this.options.templateName).html())(json);
},
render: function (eventName) {
$(this.el).html(this.template(this.model.toJSON()));
return this;
},
close: function() {
var table = $(this.el).parent().parent();
table.trigger('disable.pager');
$(this.el).unbind();
$(this.el).remove();
table.trigger('enable.pager');
}
});
views.ModelView = Backbone.View.extend({
initialize: function (options) {
this.options = options || {};
this.model.bind("change", this.render, this);
},
render: function (eventName) {
$(this.el).html(this.template(this.model.toJSON()));
return this;
},
template: function (json) {
/*
* templateName is element identifier in HTML
* $(this.options.templateName) is element access to the element
* using jQuery
*/
return _.template($(this.options.templateName).html())(json);
},
/*
* Classes "save" and "delete" are used on the HTML controls to listen events.
* So it is supposed that HTML has controls with these classes.
*/
events: {
"change input": "change",
"click .save": "save",
"click .delete": "drop"
},
change: function (event) {
var target = event.target;
console.log('changing ' + target.id + ' from: ' + target.defaultValue + ' to: ' + target.value);
},
save: function() {
// TODO : put save code here
var hash = this.options.getHashObject();
this.model.set(hash);
if (this.model.isNew() && this.collection) {
var self = this;
this.collection.create(this.model, {
success: function() {
// see isNew() method implementation in the model
self.model.notSynced = false;
self.options.navigate(self.model.id);
}
});
} else {
this.model.save();
this.model.el.parent().parent().trigger("update");
}
return false;
},
drop: function() {
this.model.destroy({
success: function() {
/*
* TODO : put your code here
* f.e. alert("Model is successfully deleted");
*/
window.history.back();
}
});
return false;
},
close: function() {
$(this.el).unbind();
$(this.el).empty();
}
});
// This view is used to create new model element
views.CreateView = Backbone.View.extend({
initialize: function (options) {
this.options = options || {};
this.render();
},
render: function (eventName) {
$(this.el).html(this.template());
return this;
},
template: function (json) {
/*
* templateName is element identifier in HTML
* $(this.options.templateName) is element access to the element
* using jQuery
*/
return _.template($(this.options.templateName).html())(json);
},
/*
* Class "new" is used on the control to listen events.
* So it is supposed that HTML has a control with "new" class.
*/
events: {
"click .new": "create"
},
create: function (event) {
this.options.navigate();
return false;
}
});
})(app.module("views"));
$(function() {
var models = app.module("models");
var views = app.module("views");
var AppRouter = Backbone.Router.extend({
routes: {
'': 'list',
'new': 'create'
,
':id': 'details'
},
initialize: function() {
var self = this;
$('#create').html(new views.CreateView({
// tpl-create is template identifier for 'create' block
templateName: '#tpl-create',
navigate: function() {
self.navigate('new', true);
}
}).render().el);
},
list: function() {
this.collection = new models.CustomerCollection();
var self = this;
this.collection.fetch({
success: function() {
self.listView = new views.ListView({
model: self.collection,
// tpl-customer-list-itemis template identifier for item
templateName: '#tpl-customer-list-item'
});
$('#datatable').html(self.listView.render().el).append(_.template($('#thead').html())());
if (self.requestedId) {
self.details(self.requestedId);
}
var pagerOptions = {
// target the pager markup
container: $('.pager'),
// output string - default is '{page}/{totalPages}'; possiblevariables: {page}, {totalPages},{startRow}, {endRow} and {totalRows}
output: '{startRow} to {endRow} ({totalRows})',
// starting page of the pager (zero based index)
page: 0,
// Number of visible rows - default is 10
size: 10
};
$('#datatable').tablesorter({widthFixed: true,
widgets: ['zebra']}).
tablesorterPager(pagerOptions);
}
});
},
details: function (id) {
if (this.collection) {
this.customer = this.collection.get(id);
if (this.view) {
this.view.close();
}
var self = this;
this.view = new views.ModelView({
model: this.customer,
// tpl-customer-details is template identifier for chosen model element
templateName: '#tpl-customer-details',
getHashObject: function() {
return self.getData();
}
});
$('#details').html(this.view.render().el);
} else {
this.requestedId = id;
this.list();
}
},
create: function() {
if (this.view) {
this.view.close();
}
var self = this;
var dataModel = new models.Customer();
// see isNew() method implementation in the model
dataModel.notSynced = true;
this.view = new views.ModelView({
model: dataModel,
collection: this.collection,
// tpl-customer-details is a template identifier for chosen model element
templateName: '#tpl-customer-details',
navigate: function (id) {
self.navigate(id, false);
},
getHashObject: function() {
return self.getData();
}
});
$('#details').html(this.view.render().el);
},
getData: function() {
return {
customerId: $('#customerId').val(),
city: $('#city').val(),
phone: $('#phone').val(),
name: $('#name').val(),
addressline2: $('#addressline2').val(),
creditLimit: $('#creditLimit').val(),
addressline1: $('#addressline1').val(),
state: $('#state').val(),
fax: $('#fax').val(),
email: $('#email').val()
};
}
});
new AppRouter();
Backbone.history.start();
});
お勧めはありますか?