适用于Atom Feed的Spring MVC

如何仅使用两个类就将提要(Atom)添加到Web应用程序?
Spring MVC呢?

这是我的假设:

  • 您正在使用Spring框架
  • 您有一些要发布在供稿中的实体,例如“新闻”
  • 您的“新闻”实体具有creationDate,title和shortDescription
  • 您有一些存储库/仓库,例如“ NewsRepository”,它将从数据库中返回新闻
  • 你想写得尽可能少
  • 您不想手动格式化Atom(xml)

实际上,您实际上不需要在应用程序中使用Spring MVC。 如果这样做,请跳至步骤3。

步骤1:将Spring MVC依赖项添加到您的应用程序

使用Maven将是:

<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>3.1.0.RELEASE</version>
</dependency>

步骤2:添加Spring MVC DispatcherServlet

使用web.xml将是:

<servlet><servlet-name>dispatcher</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/feed</url-pattern>
</servlet-mapping>

注意,我将url-pattern设置为“ / feed”,这意味着我不希望Spring MVC处理我的应用程序中的任何其他URL(我在其余的应用程序中使用了不同的Web框架)。 我还给它提供了一个全新的contextConfigLocation,其中仅保留了mvc配置。

请记住,将DispatcherServlet添加到已经具有Spring的应用程序时(例如,从ContextLoaderListener继承),您的上下文是从全局实例继承的,因此您不应创建在该全局实例中再次存在的bean,也不应该包含定义它们的xml。 注意两次Spring上下文,并查阅spring或servlet文档以了解发生了什么。

步骤3.添加ROME –处理Atom格式的库

与Maven是:

<dependency><groupId>net.java.dev.rome</groupId><artifactId>rome</artifactId><version>1.0.0</version>
</dependency>

步骤4.编写非常简单的控制器

@Controller
public class FeedController {static final String LAST_UPDATE_VIEW_KEY = 'lastUpdate';static final String NEWS_VIEW_KEY = 'news';private NewsRepository newsRepository;private String viewName;protected FeedController() {} //required by cglibpublic FeedController(NewsRepository newsRepository, String viewName) {notNull(newsRepository); hasText(viewName);this.newsRepository = newsRepository;this.viewName = viewName;}@RequestMapping(value = '/feed', method = RequestMethod.GET)        @Transactionalpublic ModelAndView feed() {ModelAndView modelAndView = new ModelAndView();modelAndView.setViewName(viewName);List<News> news = newsRepository.fetchPublished();modelAndView.addObject(NEWS_VIEW_KEY, news);modelAndView.addObject(LAST_UPDATE_VIEW_KEY, getCreationDateOfTheLast(news));return modelAndView;}private Date getCreationDateOfTheLast(List<News> news) {if(news.size() > 0) {return news.get(0).getCreationDate();}return new Date(0);}
}

如果您想复制并粘贴(谁不想要),这里有一个测试:

@RunWith(MockitoJUnitRunner.class)
public class FeedControllerShould {@Mock private NewsRepository newsRepository;private Date FORMER_ENTRY_CREATION_DATE = new Date(1);private Date LATTER_ENTRY_CREATION_DATE = new Date(2);private ArrayList<News> newsList;private FeedController feedController;@Beforepublic void prepareNewsList() {News news1 = new News().title('title1').creationDate(FORMER_ENTRY_CREATION_DATE);News news2 = new News().title('title2').creationDate(LATTER_ENTRY_CREATION_DATE);newsList = newArrayList(news2, news1);}@Beforepublic void prepareFeedController() {feedController = new FeedController(newsRepository, 'viewName');}@Testpublic void returnViewWithNews() {//givengiven(newsRepository.fetchPublished()).willReturn(newsList);//whenModelAndView modelAndView = feedController.feed();//thenassertThat(modelAndView.getModel()).includes(entry(FeedController.NEWS_VIEW_KEY, newsList));}@Testpublic void returnViewWithLastUpdateTime() {//givengiven(newsRepository.fetchPublished()).willReturn(newsList);//whenModelAndView modelAndView = feedController.feed();//thenassertThat(modelAndView.getModel()).includes(entry(FeedController.LAST_UPDATE_VIEW_KEY, LATTER_ENTRY_CREATION_DATE));}@Testpublic void returnTheBeginningOfTimeAsLastUpdateInViewWhenListIsEmpty() {//givengiven(newsRepository.fetchPublished()).willReturn(new ArrayList<News>());//whenModelAndView modelAndView = feedController.feed();//thenassertThat(modelAndView.getModel()).includes(entry(FeedController.LAST_UPDATE_VIEW_KEY, new Date(0)));}
}

注意:在这里,我正在使用fest-assert和mockito。 依赖项是:

<dependency><groupId>org.easytesting</groupId><artifactId>fest-assert</artifactId><version>1.4</version><scope>test</scope>
</dependency>
<dependency><groupId>org.mockito</groupId><artifactId>mockito-all</artifactId><version>1.8.5</version><scope>test</scope>
</dependency>

步骤5.编写非常简单的视图

这是所有魔术格式化发生的地方。 一定要看一看Entry类的所有方法,因为您可能想使用/填充很多东西。

import org.springframework.web.servlet.view.feed.AbstractAtomFeedView;
[...]public class AtomFeedView extends AbstractAtomFeedView {private String feedId = 'tag:yourFantastiSiteName';private String title = 'yourFantastiSiteName: news';private String newsAbsoluteUrl = 'http://yourfanstasticsiteUrl.com/news/'; @Overrideprotected void buildFeedMetadata(Map<String, Object> model, Feed feed, HttpServletRequest request) {feed.setId(feedId);feed.setTitle(title);setUpdatedIfNeeded(model, feed);}private void setUpdatedIfNeeded(Map<String, Object> model, Feed feed) {@SuppressWarnings('unchecked')Date lastUpdate = (Date)model.get(FeedController.LAST_UPDATE_VIEW_KEY);if (feed.getUpdated() == null || lastUpdate != null || lastUpdate.compareTo(feed.getUpdated()) > 0) {feed.setUpdated(lastUpdate);}}@Overrideprotected List<Entry> buildFeedEntries(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {@SuppressWarnings('unchecked')List<News> newsList = (List<News>)model.get(FeedController.NEWS_VIEW_KEY);List<Entry> entries = new ArrayList<Entry>();for (News news : newsList) {addEntry(entries, news);}return entries;}private void addEntry(List<Entry> entries, News news) {Entry entry = new Entry();entry.setId(feedId + ', ' + news.getId());entry.setTitle(news.getTitle());entry.setUpdated(news.getCreationDate());entry = setSummary(news, entry);entry = setLink(news, entry);entries.add(entry);}private Entry setSummary(News news, Entry entry) {Content summary = new Content();summary.setValue(news.getShortDescription());entry.setSummary(summary);return entry;}private Entry setLink(News news, Entry entry) {Link link = new Link();link.setType('text/html');link.setHref(newsAbsoluteUrl + news.getId()); //because I have a different controller to show news at http://yourfanstasticsiteUrl.com/news/IDentry.setAlternateLinks(newArrayList(link));return entry;}}

步骤6.将类添加到Spring上下文

我正在使用xml方法。 因为我老了,我喜欢xml。 不,很认真,我使用xml是因为我可能想用不同的视图(RSS 1.0,RSS 2.0等)声明FeedController几次。

这就是前面提到的spring-mvc.xml

<?xml version='1.0' encoding='UTF-8'?>
<beans xmlns='http://www.springframework.org/schema/beans'xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd'><bean class='org.springframework.web.servlet.view.ContentNegotiatingViewResolver'><property name='mediaTypes'><map><entry key='atom' value='application/atom+xml'/><entry key='html' value='text/html'/></map></property><property name='viewResolvers'><list><bean class='org.springframework.web.servlet.view.BeanNameViewResolver'/></list></property></bean><bean class='eu.margiel.pages.confitura.feed.FeedController'><constructor-arg index='0' ref='newsRepository'/><constructor-arg index='1' value='atomFeedView'/></bean><bean id='atomFeedView' class='eu.margiel.pages.confitura.feed.AtomFeedView'/>
</beans>

您完成了。

之前曾有人要求我将所有工作代码放入某个公共存储库中,所以这又是另一回事了。 我已经描述了我已经发布的内容,您可以从bitbucket中获取提交。

参考: Solid Craft博客上来自我们JCG合作伙伴 Jakub Nabrdalik的Atom Feeds与Spring MVC 。


翻译自: https://www.javacodegeeks.com/2012/10/spring-mvc-for-atom-feeds.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/370826.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python数据类型所占字节数_python标准数据类型 Bytes

预备知识&#xff1a; bin()&#xff1a; """ Return the binary representation of an integer. >>> bin(2796202) 0b1010101010101010101010 """ pass ord(): """ Return the Unicode code point for a one-character…

java第六次作业

《Java技术》第六次作业 &#xff08;一&#xff09;学习总结 1.用思维导图对本周的学习内容进行总结。 2.当程序中出现异常时&#xff0c;JVM会依据方法调用顺序依次查找有关的错误处理程序。可使用printStackTrace 和getMessage方法了解异常发生的情况。阅读下面的程序&#…

华为鸿蒙不再孤,华为鸿蒙OS系统不再孤单!又一款国产系统启动内测:再掀国产替代化...

【5月10日讯】相信大家都知道&#xff0c;备受广大花粉们期待的鸿蒙OS系统终于开始推送公测版本了&#xff0c;并且适配机型也开始不断地增多&#xff0c;而根据华为官方最新消息&#xff0c;华为鸿蒙OS系统将会在6月份开始大规模推送正式版鸿蒙系统&#xff0c;这无疑将会成为…

Spring系列合并

Spring Collection合并是我第一次遇到的功能&#xff0c;它是对StackOverflow 问题的回答 这是一种创建基本集合&#xff08;列表&#xff0c;集合&#xff0c;地图或属性&#xff09;并在其他Bean中修改此基本集合的方法&#xff0c;下面通过一个示例对此进行最好的解释- 考虑…

CSS 水平垂直居中

方法一&#xff1a; 容器确定宽高&#xff1a;知识点&#xff1a;transform只能设置在display为block的元素上。 <head> <meta charset"UTF-8"> <title>Title</title> <style type"text/css"> #container{…

linux怎么进入文件夹_Linux基础命令《上》

上一节介绍了VMware中安装centos7以及克隆系统&#xff0c;之中用到的几个命名还都是开发不常用的&#xff0c;这节课就准备讲解一下入门的Linux命名&#xff0c;都是日常使用的。首先呢&#xff0c;我们进入系统后&#xff0c;得先知道我是谁&#xff0c;我在哪儿&#xff1f;…

UML学习(一)-----用例图

1、什么是用例图 用例图源于Jacobson的OOSE方法&#xff0c;用例图是需求分析的产物&#xff0c;描述了系统的参与者与系统进行交互的功能&#xff0c;是参与者所能观察和使用到的系统功能的模型图。它的主要目的就是帮助开发团队以一种可视化的方式理解系统的功能需求&#xf…

首款鸿蒙系统终端n,荣耀智慧屏正式发布,首款搭载鸿蒙系统终端,家庭C位新选择...

原标题&#xff1a;荣耀智慧屏正式发布&#xff0c;首款搭载鸿蒙系统终端&#xff0c;家庭C位新选择智能手机的普及率越来越高&#xff0c;其所能够承担的功能也越来越多&#xff0c;电视机对于很多中青年的用户来讲&#xff0c;更多的时候就是个摆设。在家庭中&#xff0c;看电…

oracle如何保证数据一致性和避免脏读

oracle通过undo保证一致性读和不发生脏读 1.不发生脏读2.一致性读3. 事务槽&#xff08;ITL&#xff09;小解1.不发生脏读 例如&#xff1a;用户A对表更新了&#xff0c;没有提交&#xff0c;用户B对进行查询&#xff0c;没有提交的更新不能出现在用户的查询结果中 举例并通个d…

Google Guava BloomFilter

当Guava项目发布版本11.0时&#xff0c;新添加的功能之一是BloomFilter类。 BloomFilter是唯一的数据结构&#xff0c;用于指示元素是否包含在集合中。 使BloomFilter有趣的是&#xff0c;它将指示元素是否绝对不包含或可能包含在集合中。 永远不会出现假阴性的特性使BloomFil…

php 编程祝新年快乐_用于测试自动化的7种编程语言

导读&#xff1a;本文重点介绍测试自动化中排名前七位的编程语言。当人们想要开始做自动化测试&#xff0c;此时却需要开发自动化测试脚本&#xff0c;也就是要学习一门编程语言。那么&#xff0c;我们怎样迈出这一步&#xff1f;也有你已经精通一种编程语言&#xff0c;也可以…

Day1 了解web前端

Day1 了解web前端 一.职业发展路线: 前端页面制作、前端开发、前端架构师 二.1)前端工程师主要职责: 利用HTML/CSS/JavaScript等各种Web技术进行客户端产品的开发。完成客户端程序&#xff08;也就是浏览器端&#xff09;的开发&#xff0c;同时结合后台技术模拟整体效果&am…

已阻止应用程序访问图形硬件_玩转智能硬件之Jetson Nano(三)深度学习环境搭建...

0、前言iotboy&#xff1a;玩转智能硬件&#xff08;一&#xff09;Jetson Nano安装篇​zhuanlan.zhihu.comiotboy&#xff1a;玩转智能硬件&#xff08;二&#xff09;Jetson Nano配置篇​zhuanlan.zhihu.com在玩转智能硬件&#xff08;一&#xff09;和&#xff08;二&#x…

Vue.js开发环境搭建的介绍

包含了最基础的Vue.js的框架&#xff0c;包含了打包工具和测试工具&#xff0c;开发调试的最基本的服务器&#xff0c;不需要关注细节&#xff0c;只需关注Vuejs对项目的实现 npm在国内的网络使用较慢&#xff0c;所以推荐下载安装淘宝的镜像 1&#xff1a; 2&#xff1a;安装c…

html文件转换html格式,pdf文件怎么转换成html格式

PDF文件怎么转换成html格式呢&#xff1f;html格式其实就是网页格式&#xff0c;PDF文件和网页文件一般情况下是两种完全不搭边的格式&#xff0c;但是不可否定的是办公室的多样化总有人会有这样的需求&#xff0c;只要有需求就会有其相应的解决方案。我们可以利用PDF转Word一样…

Eclipse中的Github Gists

我想描述有关在Eclipse中集成GitHub Gists的简单步骤。 有几个来源促使我这样做&#xff1a; Eclipse的GitHub Mylyn连接器 EGit / GitHub /用户指南 http://eclipse.github.com 我一直在使用Eclipse Java EE发行版&#xff0c;其中已经安装了Mylyn插件&#xff1a; 1.通…

CSS3景深-perspective

3D视图正方体&#xff1a; 1 <!DOCTYPE html>2 <html lang"en">3 <head>4 <meta charset"UTF-8">5 <title>CSS3景深-perspective</title>6 </head>7 <style>8 #div1{9 position: rel…

python pool_派松水潭(Python Pool)

派松水潭(Python Pool)旅游景点类型&#xff1a;名胜Roebourne Winternoom Road , Roebourne , Western Australia , 6718Email:roetourbigpond.net.auWebsite:www.pilbaracoast.com派松水潭(Python Pool)坐落于罗伯恩(Roebourne)以南风景如画的米尔斯特姆-奇切斯特国家公园内。…

【BZOJ4262】Sum 单调栈+线段树

【BZOJ4262】Sum Description Input 第一行一个数 t&#xff0c;表示询问组数。第一行一个数 t&#xff0c;表示询问组数。接下来 t 行&#xff0c;每行四个数 l_1, r_1, l_2, r_2。Output 一共 t 行&#xff0c;每行一个数 Sum。Sample Input 4 1 3 5 7 2 4 6 8 1 1 9 9 9 9 1…

父类一实现serializable_我的java基础学习易错点和易忘点总结(一)

一.继承A:子类只能继承父类所有非私有的成员(成员方法和成员变量)B:子类不能继承父类的构造方法&#xff0c;但是可以通过super关键字去访问父类构造方法。二.继承中构造方法的关系A:子类中所有的构造方法默认都会访问父类中空参数的构造方法B:为什么呢?因为子类会继承父类中的…