使用带有Spring和tile 2.0的displaytag(Using displaytag with Spring and tiles 2.0)
我想要一点帮助。 我有一个使用Spring MVC和tile 2的web应用程序,我昨天添加了displaytag,但是当我想以任何格式导出表格时,iget重定向到一个包含连续表格数据的页面。
这是我的web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> <filter> <filter-name>ResponseOverrideFilter</filter-name> <filter-class>org.displaytag.filter.ResponseOverrideFilter</filter-class> </filter> <!-- Filter mapping for the export --> <filter-mapping> <filter-name>ResponseOverrideFilter</filter-name> <url-pattern>*.do</url-pattern> </filter-mapping> <filter-mapping> <filter-name>ResponseOverrideFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <!-- Filter for the export, need that when using Struts and tiles --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class> org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
这是我的jsp文件
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@page contentType=" ;charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://www.springframework.org/tags" prefix="spring"%> <%@ taglib uri="http://displaytag.sf.net" prefix="display" %> <html> <head> <title><spring:message code="label.listeggrafo" /></title> <style type="text/css"> .pagingItem { font-weight: normal; text-decoration: none; color: #747474; margin: 0 2px; padding: 0 2px; background-color: #eeeeee; border: 1px solid #bababa; font-size: 0.9em; line-height: 1.5em; } .pagingItemCurrent { padding: 0 2px; margin: 0 2px; font-weight: normal; color: #FFFFFF; background-color: #bfbfbf; border: 1px solid #bfbfbf; font-size: 0.9em; } </style> </head> <body> <h1><spring:message code="label.listeggrafo" /></h1> <display:table name="eggrafa" class="table" requestURI="" id="eggrafa" export="true" pagesize="10"> <display:column property="aa" sortable="true" href="update.html" media="html" paramId="aa" paramProperty="aa" titleKey="label.aa"/> <display:column property="diabathmisi" sortable="true" titleKey="label.diab"/> <display:column property="apostoleas" sortable="true" titleKey="label.apostol"/> <display:column property="tautotitaeg" sortable="true" titleKey="label.tauteg"/>
<display:setProperty name="export.pdf.filename" value="ActorDetails.pdf"/> <display:setProperty name="export.excel.filename" value="ActorDetails.xls"/> </display:table> </body>
这是我的控制器
@RequestMapping(value = "/listeggrafo" , method = RequestMethod.GET) public ModelAndView listeggrafo(@ModelAttribute("eggrafo") Eggrafo eggrafo,@ModelAttribute("typoi") TypoiEggrafou typoi,HttpSession session,HttpServletRequest request) { if(session.getAttribute("name")!=null){ Map<String, Object> model1 = new HashMap<String, Object>(); model1.put("eggrafa", articleService.listeggrafa(session.getAttribute("name").toString())); return new ModelAndView("listeggrafa",model1); }else{ return new ModelAndView("redirect:/articles/login.html"); } }
当我选择以任何格式导出时,没有任何显示下载,只会将我重定向到一个页面
http://localhost:8080/Spring3Hibernate/articles/listeggrafo.html?d-1331701-e=3&6578706f7274=1
有人知道为什么会这样吗? 当我在互联网上看时有人说这是瓷砖的问题。 有什么建议么?
i want a little help. I have a web application using Spring MVC and tiles 2 and i add displaytag yesterday but when i want to export the table in any format iget redirected to a page with the data of the table in a row.
Here is my web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> <filter> <filter-name>ResponseOverrideFilter</filter-name> <filter-class>org.displaytag.filter.ResponseOverrideFilter</filter-class> </filter> <!-- Filter mapping for the export --> <filter-mapping> <filter-name>ResponseOverrideFilter</filter-name> <url-pattern>*.do</url-pattern> </filter-mapping> <filter-mapping> <filter-name>ResponseOverrideFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <!-- Filter for the export, need that when using Struts and tiles --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class> org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
Here is my jsp file
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@page contentType=" ;charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://www.springframework.org/tags" prefix="spring"%> <%@ taglib uri="http://displaytag.sf.net" prefix="display" %> <html> <head> <title><spring:message code="label.listeggrafo" /></title> <style type="text/css"> .pagingItem { font-weight: normal; text-decoration: none; color: #747474; margin: 0 2px; padding: 0 2px; background-color: #eeeeee; border: 1px solid #bababa; font-size: 0.9em; line-height: 1.5em; } .pagingItemCurrent { padding: 0 2px; margin: 0 2px; font-weight: normal; color: #FFFFFF; background-color: #bfbfbf; border: 1px solid #bfbfbf; font-size: 0.9em; } </style> </head> <body> <h1><spring:message code="label.listeggrafo" /></h1> <display:table name="eggrafa" class="table" requestURI="" id="eggrafa" export="true" pagesize="10"> <display:column property="aa" sortable="true" href="update.html" media="html" paramId="aa" paramProperty="aa" titleKey="label.aa"/> <display:column property="diabathmisi" sortable="true" titleKey="label.diab"/> <display:column property="apostoleas" sortable="true" titleKey="label.apostol"/> <display:column property="tautotitaeg" sortable="true" titleKey="label.tauteg"/>
<display:setProperty name="export.pdf.filename" value="ActorDetails.pdf"/> <display:setProperty name="export.excel.filename" value="ActorDetails.xls"/> </display:table> </body>
Here is my controller
@RequestMapping(value = "/listeggrafo" , method = RequestMethod.GET) public ModelAndView listeggrafo(@ModelAttribute("eggrafo") Eggrafo eggrafo,@ModelAttribute("typoi") TypoiEggrafou typoi,HttpSession session,HttpServletRequest request) { if(session.getAttribute("name")!=null){ Map<String, Object> model1 = new HashMap<String, Object>(); model1.put("eggrafa", articleService.listeggrafa(session.getAttribute("name").toString())); return new ModelAndView("listeggrafa",model1); }else{ return new ModelAndView("redirect:/articles/login.html"); } }
And when i choose to export in any format nothing shown to download and only redirect me to a page
http://localhost:8080/Spring3Hibernate/articles/listeggrafo.html?d-1331701-e=3&6578706f7274=1
Does anybody knows why this happens? While i was looking on the internet someone says tha it is problem with tiles. Any suggestions?
原文:https://stackoverflow.com/questions/13431988
最满意答案
你真的应该在这里使用数组,因为使用命名对象键实际上与数据库的基本工作方式相违背。
除了基本的查询问题,例如可能在一个集合中查找作者“Bob”的所有内容(对于数组来说很简单),在寻找“last 10”时你会遇到类似的“强力”匹配问题。 更不用说,作为一个“非阵列”,“十大”实际上变得非常主观。
即使假设这些“密钥”的示例实际上是MongoDB
ObjectID
值的相同生成值(因此是单调的并且总是增加值),计算这些的排序顺序需要强力JavaScript处理而无需来自集合索引或自然数组索引位置:db.collection.mapReduce( function() { var messages = this.messages; var newMessages = Object.keys(this.messages).sort().slice(-10).map( function(id) { return messages[id]; } ); emit(this._id,{ "messages": newMessages }); }, function() {}, // not really reducing anything here { "out": { "inline": 1 } } )
或者simillar通过“timestamp”值(看起来不像时间戳)来玩杂耍,但这里的基本前提是将不是数组的内容转换为数组,以便对结果进行排序并限制您想要返回的结果。
基本上很难看! ,而且设计非常糟糕。 也只是使用mapReduce,因为它是改变返回文档结构的唯一方法(通过JavaScript处理)。 逻辑也可以在客户端中执行,唯一的优点是在通过网络连接发送之前剥离不需要的内容。
使用数组在“更新”内容上施加一些开销的想法也是相当“笨拙”的。 MongoDB从一开始就支持匹配的位置更新,并且正确的结构和使用非常简单:
{ "_id" : ObjectId("2bjbkjb4234j134124"), "messages" : [ { "_id": "56a7b13f24236dea1247cdc7", "authorName" : "Nick", "timestamp" : 1.453699391078E12, "message" : "Hello" }, // etc ] }
因此,如果您想匹配并更新特定的数组条目(假设在任何地方都是unqiue,但只需要根据需要调整为“per-document”)只需在查询部分中应用标识符,并在“update”中应用位置
$
运算符声明的一部分:db.collection.update( { "messages._id": "56a7b13f24236dea1247cdc7" }, { "$set": { "messages.$.message": "something new", "messages.$.timestamp": aNewValue }} )
使用
$push
向数组添加项目还具有以下优点:默认情况下,所有“最新”条目都添加到数组的末尾。 因此,除非你改变它(并且不要修改并因此想要最新的时间戳),那么你需要做的只是$slice
“已经是一个数组”,而不需要进一步的杂耍:db.collection.find( {}, { "messages": { "$slice": -10 } } )
如果你真的想要一个修改过的字段(如“timestamp”)来影响排序,那么你可以简单地存储这种方式将
$sort
修饰符设置为$push
。 这通过简单应用批量操作甚至可以应用于修改的数组元素:var bulk = db.collection.initializeOrderedBulkOp(); // Update the matched element bulk.find({ "_id": ObjectId("2bjbkjb4234j134124"), "messages._id": "56a7b13f24236dea1247cdc7" }).updateOne({ "$set": { "messages.$.message": "something new", "messages.$.timestamp": aNewValue } }); // Sort the array on timestamp bulk.find({ "_id": ObjectId("2bjbkjb4234j134124"), "messages._id": "56a7b13f24236dea1247cdc7" }).updateOne({ "$push": { "messages": { "$each": [], "$sort": { "timestamp": 1 } } } }) // Send and receive from server bulk.execute();
虽然这实际上是两个更新语句(因为您无法在单个更新操作中修改具有两个运算符语句的相同文档路径),但它仍然可以作为单个请求和服务器响应,因此非常有效。
当然,如果您不想永久存储订单,那么数组至少可以在聚合框架中进行操作,其方式通常比通过mapReduce的JavaScript处理更有效:
db.collection.aggregate([ { "$match": ObjectId("2bjbkjb4234j134124") }, { "$unwind": "$messages" }, { "$sort": { "messages.timestamp": -1 } }, // in reverse order with $limit { "$limit": 10 }, { "$group": { "_id": "$_id", "messages": { "$push": "$messages" } }} ])
或者甚至超过使用新MongoDB 3.2运营商的多个文档:
db.collection.aggregate([ { "$unwind": "$messages" }, { "$sort": { "_id": 1, "messages.timestamp": 1 } }, { "$group": { "_id": "$_id", "messages": { "$push": "$messages" } }}, { "$project": { "messages": { "$slice": [ "$messages", -10 ] } }} ])
但在所有情况下,最有效的考虑因素是数据应该:
是一个“数组”,而不是嵌套在对象的命名键下
理想情况下,按照最常见的用例顺序存储,以便在阅读时访问。
在这里真正看到的最后一件事是,如果你“真的”打算在一个数组甚至一个文档中存储50,000条消息(因为在StackOverflow上提问时没有人夸大其词),那么这些信息总会比现有的更好在他们自己的收藏中,即使没有超过BSON文件限制(最可能的事件将被超过),性能考虑确实会很糟糕。
考虑数据的使用模式应该是这里的主要目标。 因为你“可以”将引用的文档存储在另一个文档中,除非你有一个用例,在一个请求中需要“all allly”(绝对不是50,000),那么你不应该这样做。
You really should be using arrays here, as using named object keys is really counterintuitive to how a database basically works.
Aside from the basic querying problems, such as maybe looking for all content by author "Bob" in a collection ( which is simple with arrays ), you have similar "brute force" matching problems in looking for the "last 10". Not to mention, as a "non-array" it becomes really subjective what the "last ten" actually is.
Even taking the example that supposing these "keys" are actually the same generated values of MongoDB
ObjectID
values ( therefore being monotonic and always increasing in value ), working out the sort order of these requires brute force JavaScript processing with no assistance from collection indexes or natural array index positions:db.collection.mapReduce( function() { var messages = this.messages; var newMessages = Object.keys(this.messages).sort().slice(-10).map( function(id) { return messages[id]; } ); emit(this._id,{ "messages": newMessages }); }, function() {}, // not really reducing anything here { "out": { "inline": 1 } } )
Or simillar juggling by the "timestamp" values ( which does not look like a timestamp ), but the basic premise here is turning something that is not an array into an array, in order to sort the results and limit those you want to return.
Basically Ugly!, and really bad design. Also just using mapReduce for the sake of that it is the only method ( via JavaScript processing ) of altering the structure of the document returned. The logic may as well be performed in the client, with the only advantage of stripping unwanted content before sending over the network connection.
The idea that using arrays imposes some overhead on "updating" content is fairly "bunk" as well. MongoDB has supported matched position updating since inception, and structuring correctly as well as usage is fairly straightforward:
{ "_id" : ObjectId("2bjbkjb4234j134124"), "messages" : [ { "_id": "56a7b13f24236dea1247cdc7", "authorName" : "Nick", "timestamp" : 1.453699391078E12, "message" : "Hello" }, // etc ] }
So if you wanted to match and update a specific array entry ( assuming unqiue everywhere, but just a matter of tuning to "per-document" if needed ) just applies the identifier in the query portion and the positional
$
operator in the "update" portion of the statement:db.collection.update( { "messages._id": "56a7b13f24236dea1247cdc7" }, { "$set": { "messages.$.message": "something new", "messages.$.timestamp": aNewValue }} )
Adding items to arrays using
$push
also has the advantage of all "newest" entries are added to the end of the array by default. So unless you change this ( and don't modify and thus want latest timestamp ) then all you need do is$slice
the "already an array", without further juggling:db.collection.find( {}, { "messages": { "$slice": -10 } } )
If you really wanted a modified field such as "timestamp" to affect the ordering, then you could simply store that way usign the
$sort
modifier to$push
. This can even apply to modified array elements by simple application of Bulk Operations:var bulk = db.collection.initializeOrderedBulkOp(); // Update the matched element bulk.find({ "_id": ObjectId("2bjbkjb4234j134124"), "messages._id": "56a7b13f24236dea1247cdc7" }).updateOne({ "$set": { "messages.$.message": "something new", "messages.$.timestamp": aNewValue } }); // Sort the array on timestamp bulk.find({ "_id": ObjectId("2bjbkjb4234j134124"), "messages._id": "56a7b13f24236dea1247cdc7" }).updateOne({ "$push": { "messages": { "$each": [], "$sort": { "timestamp": 1 } } } }) // Send and receive from server bulk.execute();
Which while this is effectively two update statements ( since you cannot modify the same document path with two operator statements in a single update operation ), it does still work out as a single request and response to the server, and is therefore pretty efficient.
And of course if you did not want to store the order permanantly, then arrays can at least be manipulated in the aggregation framework, in a manner that will usually be more efficient than processing via JavaScript of mapReduce:
db.collection.aggregate([ { "$match": ObjectId("2bjbkjb4234j134124") }, { "$unwind": "$messages" }, { "$sort": { "messages.timestamp": -1 } }, // in reverse order with $limit { "$limit": 10 }, { "$group": { "_id": "$_id", "messages": { "$push": "$messages" } }} ])
Or even super fancy over multiple documents with new MongoDB 3.2 operators:
db.collection.aggregate([ { "$unwind": "$messages" }, { "$sort": { "_id": 1, "messages.timestamp": 1 } }, { "$group": { "_id": "$_id", "messages": { "$push": "$messages" } }}, { "$project": { "messages": { "$slice": [ "$messages", -10 ] } }} ])
But the most performant consideration in all cases is that the data should:
Be an "array" and not nested under named keys of an object
Ideally be stored in the order of the most common use case for access on reading.
The final thing to really look at here is that if you "really" intend to store 50,000 messages in an array or even a single document ( because no-one ever exaggerates wildly when asking questions on StackOverflow ) then these would always be better off existing in their own collection, where even if the BSON document limit were not exceeded ( the most likely event would be it was exceeded ), the performance considerations would indeed be terrible.
Considering usage patterns of the data should be the prime objective here. So just because you "can" store referenced documents within another, unless you have a use case where "all of them" ( definately never 50,000 ) are needed in one request, then you should not be doing so.
相关问答
更多-
您不能在mongoose中创建不明确的键,因为它的全部目的是为您处理文档结构。 但是,您可以创建一个对象数组。 Schema4: { schemaRefs: [{ refToSchema1: {type: mongoose.Types.ObjectId, ref: 'Schema1'}, refToSchema2: {type: mongoose.Types.ObjectId, ref: 'Schema2'} }] } 为了将来参考,当您提供真实示例而不是假名时,更容易理解您的问题 ...
-
您可以在3.4中使用以下聚合来获取具有最高日期的Action元素。 db.col.aggregate({"$project":{ "maxEle":{ "$reduce":{ "input":"$history.Actions", "initialValue":{"Date":""}, "in":{ "$cond":[ {"$gt":[{"$max":"$$this.Date"},"$$value.Date"]}, ...
-
Doctrine MongoDb嵌入式文档 - 如何指定字段(Doctrine MongoDb Embedded Document - How to specify fields)[2021-05-08]
Specialization类使用Document映射,该映射不适用于嵌入。 您应该使用EmbeddedDocument 。 鉴于您希望自己和嵌入形式使用相同的类,最好创建一个使用MappedSuperclass注释的抽象类。 在那里,您可以定义文档和嵌入文档中应存在的任何字段映射。 在您的情况下,您可以在继承文档类上保持visible 。 另外,请注意,通过使用set策略,您将嵌入式集合存储为对象而不是通常的数组。 如果您要在非规范化的嵌入式文档中索引字段,这可能会产生影响,因为您将无法使用多键索引 。 ... -
这是测试代码,效果很好 > db.createCollection('name', {validator: {$and: [{"name.first_name": {$type: 'string'}}, {"name.last_name": {$type: 'string'}}]}}) { "ok" : 1 } 看来你应该在name.last_name添加"" , 用有效数据测试它 > db.name.insert({name: {first_name: 'xx', last_name: 'yy'}}) ...
-
mongoDB:如何获取嵌入文档的最新字段(非数组)(mongoDB : How to get most recent fields of an embedded document(non-array))[2023-07-24]
你真的应该在这里使用数组,因为使用命名对象键实际上与数据库的基本工作方式相违背。 除了基本的查询问题,例如可能在一个集合中查找作者“Bob”的所有内容(对于数组来说很简单),在寻找“last 10”时你会遇到类似的“强力”匹配问题。 更不用说,作为一个“非阵列”,“十大”实际上变得非常主观。 即使假设这些“密钥”的示例实际上是MongoDB ObjectID值的相同生成值(因此是单调的并且总是增加值),计算这些的排序顺序需要强力JavaScript处理而无需来自集合索引或自然数组索引位置: db.colle ... -
Collection.find返回一个游标,而不是一个数组。 游标没有sort方法。 请尝试以下方法: Rooms.findOne({}, {fields: {_id: 1}, sort: {_id: -1}}); http://docs.meteor.com/api/collections.html#Mongo-Collection-find 编辑: 正如@MichelFloyd指出的那样,由Meteor生成的_id 并不像MongoDB本身创建的那样按时间顺序排序。 要按创建日期排序,您必须将这些时间 ...
-
您可能想尝试聚合方法(有关详细示例,请参阅http://docs.mongodb.org/manual/tutorial/aggregation-with-user-preference-data/ ) db.user.aggregate( { $match: { "_id": ObjectId("52426846311fc102641ef332") } } , { $unwind: "$weightTracker"}, {$ ...
-
你可以做到这一点 db.test.update( { _id : 133 }, { $set : { PackSizes: {_id: 123, PackSizeName:"xyz", UnitName:"pqr"}} } ) PackSizes可以是任何文档,包含数组或不包含它。 你的结果文件将是 { "_id" : 133, "Name" : "abc", "Price" : 20, "PackSizes" : { "_id" : 123, ...
-
mongoDB重命名嵌入字段(mongoDB Rename embedded field)[2022-05-20]
看着 MongoDB.Driver.Builders.Update.Rename(string oldElementName, string newElementName) 它返回一个IUpdateQuery,您可以将其传递给collection.Update()并重命名您的字段。 C#Update构建器具有可以在mongo中用作构建查询的可调用函数的所有特殊命令。 Builders命名空间是MongoDB C#驱动程序中的 ... -
它看起来像你的查询是好的。 正如错误消息所述,问题在于您试图显示无法转换为字符串的对象。 TL; DR 使用{{ i.address[0].city }} 这是为什么? {{ i.address }}类型为Doctrine \ ODM \ MongoDB \ PersistentCollection 。 集合是一个包含其他几个对象的对象(在你的情况下是类型地址)。 这个集合类实现了构建到PHP中的ArrayAccess接口。 您可以像使用任何普通的PHP数组一样使用实现此接口的对象,这意味着您可以使用obj ...