В этой статье я покажу некоторые рекомендации по созданию веб-приложения Spring, его запуску с использованием Jetty и использованию внешней библиотеки ROME для чтения RSS.
Генеральная
Недавно я создал образец веб-приложения, которое выполняет функцию чтения RSS. Я хотел изучить РИМ для чтения RSS. Я также хотел создать приложение, используя Spring контейнер и MVC для простейшего представления. Для быстрой разработки я использовал Jetty в качестве сервера, используя для этого простой Java-класс.
Весь код можно найти на GitHub, eyalgo / rss-reader .
содержание
- Maven Зависимости
- Jetty Server
- Зависимость весны
- Spring MVC
- РИМ
Maven Зависимости
Сначала я не мог получить правильную версию Jetty для использования. Один с групповым идентификатором, а другой — по затмению. После тщательного изучения, проб и ошибок я взял библиотеку затмения. Весна просто стандартная. Я нашел ROME с новейшей версией под GutHub. Это все еще SNAPSHOT.
Вот список зависимостей:
- весна
- мол
- Рим и Рим-сборщик
- logback и slf4j
- Для тестирования
- Junit
- Mockito
- Hamcrest
- весна-тест
- Файл pom проекта можно найти по адресу: https://github.com/eyalgo/rss-reader/blob/master/pom.xml.
Jetty Server
Несколько лет назад я работал с Wicket Framework и познакомился с Jetty и его простым использованием для создания сервера. Я решил пойти в этом направлении и пропустить стандартный веб-сервер, работающий с развертыванием WAR.
Существует несколько способов создания сервера Jetty. Я решил создать сервер, используя контекст веб-приложения.
Сначала создайте контекст:
1
2
3
4
5
6
|
private WebAppContext createContext() { WebAppContext webAppContext = new WebAppContext(); webAppContext.setContextPath( "/" ); webAppContext.setWar(WEB_APP_ROOT); return webAppContext; } |
Затем создайте сервер и добавьте контекст в качестве обработчика:
1
2
|
Server server = new Server(port); server.setHandler(webAppContext); |
Наконец, запустите сервер:
1
2
3
4
5
6
|
try { server.start(); } catch (Exception e) { LOGGER.error( "Failed to start server" , e); throw new RuntimeException(); } |
Все находится по адресу https://github.com/eyalgo/rss-reader/tree/master/src/test/java/com/eyalgo/rssreader/server .
Весенняя структура проекта
Зависимость весны
В web.xml я объявляю application-context.xml и web-context.xml. В web-context.xml я говорю, что Spring должен был сканировать компоненты: <context:component-scan base-package="com.eyalgo.rssreader"/>
.
В application-context.xml я добавляю bean-компонент, который является внешним классом, и поэтому я не могу его сканировать (используйте аннотации):
<bean id="fetcher" class="org.rometools.fetcher.impl.HttpURLFeedFetcher"/>
.
Помимо сканирования, я добавляю правильную аннотацию в правильные классы.
@Repository
@Service
@Controller
@Autowired
Spring MVC
Для того, чтобы иметь некоторое представление о RSS-каналах (и атомах), я использовал простые страницы MVC и JSP. Чтобы создать контроллер, мне нужно было добавить @Controller
для класса. Я добавил @RequestMapping("/rss")
поэтому все запросы должны иметь префикс rss . Каждый метод имеет объявление @RequestMapping
. Я решил, что все ПОЛУЧИТЬ .
Добавление параметра в запрос
Просто добавьте @RequestParam("feedUrl")
перед параметром метода.
Перенаправление запроса
После добавления местоположения RSS я хотел перенаправить ответ, чтобы показать все текущие элементы RSS. Таким образом, метод добавления RSS-канала необходим для возврата строки. Возвращаемое значение: «redirect: all» .
1
2
3
4
5
|
@RequestMapping (value = "feed" , method = RequestMethod.GET) public String addFeed( @RequestParam ( "feedUrl" ) String feedUrl) { feedReciever.addFeed(feedUrl); return "redirect:all" ; } |
Вернуть класс ModelAndView
В Spring MVC, когда метод возвращает String, платформа ищет JSP-страницу с этим именем. Если его нет, мы получим ошибку. (Если вы хотите вернуть только строку, вы можете добавить @ResponseBody
в метод.)
Чтобы использовать ModelAndView , вам нужно создать его с именем: ModelAndView modelAndView = new ModelAndView("rssItems");
Имя сообщит Spring MVC, на какую JSP ссылаться. В этом примере он будет искать rssItems.jsp .
Затем вы можете добавить в ModelAndView «объекты»:
1
2
3
|
List<FeedItem> items = itemsRetriever.get(); ModelAndView modelAndView = new ModelAndView( "rssItems" ); modelAndView.addObject( "items" , items); |
На странице JSP вам нужно ссылаться на имена добавленных вами объектов. И тогда вы можете получить доступ к их свойствам. Итак, в этом примере у нас будет следующее в rssItems.jsp :
1
2
3
4
5
6
|
< c:forEach items = "${items}" var = "item" > < div > < a href = "${item.link}" target = "_blank" >${item.title}</ a >< br > ${item.publishedDate} </ div > </ c:forEach > |
Запись
Spring «знает», как добавить jsp в качестве суффикса к имени ModelAndView, потому что я объявил его в web-context.xml. В компоненте класса: org.springframework.web.servlet.view.InternalResourceViewResolver . Установив префикс, этот бин также сообщает Spring, что нужно искать страницы jsp. Пожалуйста, посмотрите:
- https://github.com/eyalgo/rss-reader/blob/master/src/main/java/com/eyalgo/rssreader/web/RssController.java
- https://github.com/eyalgo/rss-reader/blob/master/src/main/webapp/WEB-INF/views/rssItems.jsp
Обработка ошибок
Существует несколько способов обработки ошибок в Spring MVC. Я выбрал общий способ, при котором для любой ошибки будет отображаться страница с общей ошибкой. Сначала добавьте @ControllerAdvice в класс, который вы хотите обрабатывать ошибки. Во-вторых, создайте метод для каждого типа исключения, которое вы хотите перехватить. Вам нужно аннотировать метод с помощью @ExceptionHandler . Параметр сообщает, какое исключение будет обрабатывать этот метод. У вас может быть метод для IllegalArgumentException и другой для другого исключения и так далее. Возвращаемое значение может быть любым, и оно будет действовать как обычный контроллер. Это означает, что jsp (например) с именем объекта, который возвращает метод. В этом примере метод перехватывает все исключения и активирует error.jsp , добавляя сообщение на страницу.
1
2
3
4
5
6
|
@ExceptionHandler (Exception. class ) public ModelAndView handleAllException(Exception e) { ModelAndView model = new ModelAndView( "error" ); model.addObject( "message" , e.getMessage()); return model; } |
РИМ
ROME — это простая в использовании библиотека для обработки RSS-каналов: https://github.com/rometools/rome .
rome-fetcher — это дополнительная библиотека, которая помогает получать (извлекать) RSS-каналы из внешних источников, таких как HTTP или URL: https://github.com/rometools/rome-fetcher
На данный момент последняя сборка — 2.0.0-SNAPSHOT.
Пример того, как читать входной XML-файл RSS, можно найти по адресу: https://github.com/eyalgo/rss-reader/blob/master/src/test/java/com/eyalgo/rssreader/runners/MetadataFeedRunner. Ява
Чтобы облегчить жизнь, я использовал Рим-сборщик. Это дает вам возможность указать URL (канал RSS) и исключить из него весь SyndFeed . При желании вы можете добавить кэширование, чтобы оно не загружало кэшированные элементы (элементы, которые уже были загружены). Все, что вам нужно, это создать сборщик с параметром FeedFetcherCache в конструкторе.
Использование:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
@Override public List<FeedItem> extractItems(String feedUrl) { try { List<FeedItem> result = Lists.newLinkedList(); URL url = new URL(feedUrl); SyndFeed feed = fetcher.retrieveFeed(url); List<SyndEntry> entries = feed.getEntries(); for (SyndEntry entry : entries) { result.add( new FeedItem(entry.getTitle(), entry.getLink(), entry.getPublishedDate())); } return result; } catch (IllegalArgumentException | IOException | FeedException | FetcherException e) { throw new RuntimeException( "Error getting feed from " + feedUrl, e); } } |
Запись
Если вы получите предупреждающее сообщение (выглядит как System.out), в котором говорится, что fetcher.properties отсутствует, просто добавьте пустой файл под ресурсами (или в корень пути к классам).
Резюме
Этот пост охватывал несколько тем. Вы также можете посмотреть, как тестируется большая часть кода. Проверьте совпадения и издевательства. Если у вас есть какие-либо замечания, пожалуйста, оставьте записку.
Ссылка: | RSS Reader Использование: ROME, Spring MVC, Embedded Jetty от нашего партнера JCG Эяля Голана в блоге « Обучение и совершенствование в качестве мастера» . |