BAEL-1273: RSS improvements with a custom model (#3665)

* BAEL-1216: improve tests

* BAEL-1448: Update Spring 5 articles to use the release version

* Setting up the Maven Wrapper on a maven project

* Add Maven Wrapper on spring-boot module

* simple add

* BAEL-976: Update spring version

* BAEL-1273: Display RSS feed with spring mvc (AbstractRssFeedView)

* Move RSS feed with Spring MVC from spring-boot to spring-mvc-simple

* BAEL-1285: Update Jackson articles

* BAEL-1273: implement both MVC and Rest approach to serve RSS content

* RSS(XML & Json) with a custom model

* BAEL-1273: remove a resource
This commit is contained in:
Dassi orleando 2018-02-18 00:08:19 +01:00 committed by maibin
parent 2a127b3df3
commit 1b0e859d3a
6 changed files with 169 additions and 23 deletions

View File

@ -31,9 +31,16 @@
<junit.jupiter.version>5.0.2</junit.jupiter.version> <junit.jupiter.version>5.0.2</junit.jupiter.version>
<junit.platform.version>1.0.2</junit.platform.version> <junit.platform.version>1.0.2</junit.platform.version>
<rome.version>1.9.0</rome.version> <rome.version>1.9.0</rome.version>
<jackson.version>2.9.4</jackson.version>
<xstream.version>1.4.9</xstream.version>
</properties> </properties>
<dependencies> <dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId> <artifactId>javax.servlet-api</artifactId>
@ -121,6 +128,23 @@
<artifactId>rome</artifactId> <artifactId>rome</artifactId>
<version>${rome.version}</version> <version>${rome.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>${xstream.version}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
<pluginManagement> <pluginManagement>

View File

@ -1,26 +1,33 @@
package com.baeldung.spring.configuration; package com.baeldung.spring.configuration;
import com.baeldung.spring.controller.rss.ArticleRssFeedViewResolver; import com.baeldung.spring.controller.rss.ArticleRssFeedViewResolver;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.feed.RssChannelHttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver; import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver; import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.accept.ContentNegotiationManager;
import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
@Configuration @Configuration
@EnableWebMvc @EnableWebMvc
@ComponentScan(basePackages = { "com.baeldung.springmvcforms", "com.baeldung.spring.controller", "com.baeldung.spring.validator" }) @ComponentScan(basePackages = { "com.baeldung.springmvcforms", "com.baeldung.spring.controller", "com.baeldung.spring.validator" })
class ApplicationConfiguration implements WebMvcConfigurer { class ApplicationConfiguration extends WebMvcConfigurerAdapter {
@Override @Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
@ -49,4 +56,19 @@ class ApplicationConfiguration implements WebMvcConfigurer {
multipartResolver.setMaxUploadSize(5242880); multipartResolver.setMaxUploadSize(5242880);
return multipartResolver; return multipartResolver;
} }
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.xml();
builder.indentOutput(true);
XmlMapper xmlMapper = builder.createXmlMapper(true).build();
xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
converters.add(new RssChannelHttpMessageConverter());
converters.add(new MappingJackson2HttpMessageConverter());
converters.add(new MappingJackson2XmlHttpMessageConverter(xmlMapper));
super.configureMessageConverters(converters);
}
} }

View File

@ -0,0 +1,27 @@
package com.baeldung.spring.controller.rss;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@JacksonXmlRootElement(localName="articles")
public class ArticleFeed extends RssData implements Serializable {
@JacksonXmlElementWrapper(localName = "items", useWrapping = true)
private List<ArticleItem> items = new ArrayList<ArticleItem>();
public void addItem(ArticleItem articleItem) {
this.items.add(articleItem);
}
public List<ArticleItem> getItems() {
return items;
}
public void setItems(List<ArticleItem> items) {
this.items = items;
}
}

View File

@ -0,0 +1,25 @@
package com.baeldung.spring.controller.rss;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.io.Serializable;
@JacksonXmlRootElement(localName="article")
public class ArticleItem extends RssData implements Serializable {
private String author;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString() {
return "ArticleItem{" +
"author='" + author + '\'' +
'}';
}
}

View File

@ -14,46 +14,38 @@ import java.util.List;
@Controller @Controller
public class ArticleRssController { public class ArticleRssController {
@GetMapping(value = "/rssMvc") @GetMapping(value = "/rss1")
public String articleMvcFeed() { public String articleMvcFeed() {
return "articleFeedView"; return "articleFeedView";
} }
@GetMapping(value = "/rssRest", produces = "application/rss+xml") @GetMapping(value = "/rss2")
@ResponseBody @ResponseBody
public String articleRestFeed() throws FeedException { public ArticleFeed articleRestFeed2() {
SyndFeed feed = new SyndFeedImpl(); ArticleFeed feed = new ArticleFeed();
feed.setFeedType("rss_2.0");
feed.setLink("http://localhost:8080/spring-mvc-simple/rss"); feed.setLink("http://localhost:8080/spring-mvc-simple/rss");
feed.setTitle("Article Feed"); feed.setTitle("Article Feed");
feed.setDescription("Article Feed Description"); feed.setDescription("Article Feed Description");
feed.setPublishedDate(new Date()); feed.setPublishedDate(new Date());
List list = new ArrayList<SyndEntry>(); ArticleItem item1 = new ArticleItem();
SyndEntry item1 = new SyndEntryImpl();
item1.setLink("http://www.baeldung.com/netty-exception-handling"); item1.setLink("http://www.baeldung.com/netty-exception-handling");
item1.setTitle("Exceptions in Netty"); item1.setTitle("Exceptions in Netty");
SyndContent description1 = new SyndContentImpl(); item1.setDescription("In this quick article, well be looking at exception handling in Netty.");
description1.setValue("In this quick article, well be looking at exception handling in Netty.");
item1.setDescription(description1);
item1.setPublishedDate(new Date()); item1.setPublishedDate(new Date());
item1.setAuthor("Carlos"); item1.setAuthor("Carlos");
SyndEntry item2 = new SyndEntryImpl(); ArticleItem item2 = new ArticleItem();
item2.setLink("http://www.baeldung.com/cockroachdb-java"); item2.setLink("http://www.baeldung.com/cockroachdb-java");
item2.setTitle("Guide to CockroachDB in Java"); item2.setTitle("Guide to CockroachDB in Java");
SyndContent description2 = new SyndContentImpl(); item2.setDescription("This tutorial is an introductory guide to using CockroachDB with Java.");
description2.setValue("This tutorial is an introductory guide to using CockroachDB with Java.");
item2.setDescription(description2);
item2.setPublishedDate(new Date()); item2.setPublishedDate(new Date());
item2.setAuthor("Baeldung"); item2.setAuthor("Baeldung");
list.add(item1); feed.addItem(item1);
list.add(item2); feed.addItem(item2);
feed.setEntries(list);
return new SyndFeedOutput().outputString(feed); return feed;
} }
} }

View File

@ -0,0 +1,56 @@
package com.baeldung.spring.controller.rss;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class RssData implements Serializable {
private String link;
private String title;
private String description;
private String publishedDate;
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getPublishedDate() {
return publishedDate;
}
public void setPublishedDate(Date publishedDate) {
DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
this.publishedDate = df.format(publishedDate);
}
@Override
public String toString() {
return "RssData{" +
"link='" + link + '\'' +
", title='" + title + '\'' +
", description='" + description + '\'' +
", publishedDate=" + publishedDate +
'}';
}
}