В данном уроке решил поделится проблемой, которая у меня возникла, и как я её решил, дело пойдет о том как в Spring MVC, а точней с контроллера отправить JSON ответ который Ajax примет и обработает.
Задача
Создать Spring MVC приложение, которое будет общаться с клиентской частью (в нашем случае это JSP) посредством JSON c использованием Ajax.
Проблема!
В процессе решение данной задачи возникла проблема, а именно когда я обращался по URL к контролеру, который отдает JSON я получал Error 406.
Теперь давайте посмотрим решение этой проблемы и почему она возникла.
Шаг 1
Создадим простой Spring MVC проект, это можно сделать в Intelij IDEA нажав File -> New Project -> Spring MVC.
Теперь открываем src\main\webapp\WEB-INF\web.xml и меняем мапинг на *.html:
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>Spring MVC Application</display-name> <servlet> <servlet-name>mvc-dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc-dispatcher</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> </web-app>
Теперь наши контролеры будут в url как <name controller>.html
Шаг 2
Теперь давайте добавим зависимости в pom.xml:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.2.2</version> </dependency>
Это Jackson библиотека, которая позволяет конвертировать с Java Object в JSON и обратно детальней тут Конвертация Java объектов в JSON
Шаг 3
Теперь заходим в контролер src\main\java\com\devcolibri\mvc\HelloController.java и у вас должно быть следующее содержимое:
package com.devcolibri.mvc; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import java.util.HashSet; import java.util.Set; @Controller public class HelloController { @RequestMapping(value = "/page", method = RequestMethod.GET) public String printWelcome(){ return "hello"; } @RequestMapping(value = "/ajaxtest", method = RequestMethod.GET) @ResponseBody public Set<String> ajaxTest() { Set<String> records = new HashSet<String>(); records.add("Record #1"); records.add("Record #2"); return records; } }
После этого если собрать и запустить, по URL http://localhost:8080/test/ajaxtest.html, то вы увидите проблему, с которой я боролся.
Шаг 4 (Решение)
Первое, что нужно сделать это добавить в mvc-dispatcher-servlet.xml конфигурацию, которая поддерживает @ResponseBody:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans ... > <context:component-scan base-package="com.devcolibri.mvc"/> <mvc:annotation-driven /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
И второе, это изменить мапинг в web.xml с *.html обратно на ‘/’
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>Spring MVC Application</display-name> <servlet> <servlet-name>mvc-dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc-dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
После этого пересобираем проект и деплоим его, после этого обращаемся по URL http://localhost:8080/test/ajaxtest и вы увидите:
["Record #1","Record #2"]
Теперь когда в web.xml мы перемапились на <url-pattern>/</url-pattern> мы не сможем видеть такие файл как css, js, png и другие.
Для того, что бы решить это перечислите нужные вам форматы в том же web.xml:
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.css</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.js</url-pattern> </servlet-mapping>
После этого эти форматы будут мапиться.
UPD: Или есть еще один способ мапить все ресурсы без явного указывания их, для этого в mvc-dispatcher-servlet.xml укажите следующий tag.
<mvc:resources mapping="/**" location="/" />
Шаг 5
Теперь сделаем обращение к этому контроллеру через Ajax.
Изменим содержимое файла src\main\webapp\WEB-INF\pages\hello.jsp на это:
<html> <script src="http://code.jquery.com/jquery-1.10.2.min.js" type="text/javascript" ></script> <script type="text/javascript"> $(document).ready(function() { $("#test").click(function(){ $.get("/test/ajaxtest",function(data,status){ alert("Data: " + data + "\nStatus: " + status); }); }); }); </script> <body> <button id="test">Load</button> </body> </html>
После деплоя заходим на URL http://localhost:8080/test/page и жмем на кнопку:
На этом все. Надеюсь я вам помог. Если будут вопросы пишите в комментариях.
ПОХОЖИЕ ПУБЛИКАЦИИ
- None Found
4 комментариев к статье "Spring MVC и Ajax или как я боролся с получением JSON ответа от сервера?"