Я пытаюсь отправить запрос POST на сервлет. Запрос отправляется через jQuery таким образом:
var productCategory = new Object();
productCategory.idProductCategory = 1;
productCategory.description = "Descrizione2";
newCategory(productCategory);
где newCategory
function newCategory(productCategory)
{
$.postJSON("ajax/newproductcategory", productCategory, function(
idProductCategory)
{
console.debug("Inserted: " + idProductCategory);
});
}
и postJSON
$.postJSON = function(url, data, callback) {
return jQuery.ajax({
'type': 'POST',
'url': url,
'contentType': 'application/json',
'data': JSON.stringify(data),
'dataType': 'json',
'success': callback
});
};
С firebug я вижу, что JSON отправлен правильно:
{"idProductCategory":1,"description":"Descrizione2"}
Но я получаю 415 неподдерживаемых типов носителей. Spring Контроллер mvc имеет подпись
@RequestMapping(value = "/ajax/newproductcategory", method = RequestMethod.POST)
public @ResponseBody
Integer newProductCategory(HttpServletRequest request,
@RequestBody ProductCategory productCategory)
Несколько дней назад это сработало, теперь это не так. При необходимости я покажу больше кода. Благодаря
Мне удалось, как это сделать. Скажи мне, если я ошибаюсь.
Я использовал только один способ сериализации/десериализации: я удалил все аннотации относительно этого (@JSONSerialize
и @JSONDeserialize
) и зарегистрировал сериализаторы и десериализаторы в классе CustomObjectMapper
.
Я не нашел статьи, объясняющей это поведение, но я решил таким образом. Надеюсь, это полезно.
У меня это было раньше с Spring @ResponseBody, и это было потому, что не было заголовка accept, отправленного с запросом. Принять заголовок может быть болью для установки с помощью jQuery, но это сработало для меня source
$.postJSON = function(url, data, callback) {
return jQuery.ajax({
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
'type': 'POST',
'url': url,
'data': JSON.stringify(data),
'dataType': 'json',
'success': callback
});
};
Заголовок Content-Type используется @RequestBody для определения формата, который данные отправляют от клиента в запросе. Заголовок принятия используется @ResponseBody для определения формата отправки данных обратно клиенту в ответ. Вот почему вам нужны оба заголовка.
У меня была аналогичная проблема, но я обнаружил, что проблема в том, что я забыл предоставить конструктор по умолчанию для DTO, который был аннотирован с помощью @RequestBody.
Я считаю, что я точно столкнулся с той же проблемой. После бесчисленных часов борьбы с JSON, JavaScript и сервером, я нашел виновника: в моем случае у меня был объект Date в DTO, этот объект Date был преобразован в String, чтобы мы могли показать его в представлении с помощью формат: ЧЧ: мм.
Когда информация JSON была отправлена обратно, этот объект String даты должен был быть преобразован обратно в полный объект Date, поэтому нам также нужен метод его установки в DTO. Большой BUT - вы не можете иметь 2 метода с тем же именем (Overload) в DTO, даже если у них есть другой тип параметра (String vs Date), потому что это также даст вам 415 неподдерживаемый тип носителя.
Это был мой метод контроллера
@RequestMapping(value = "/alarmdownload/update", produces = "application/json", method = RequestMethod.POST)
public @ResponseBody
StatusResponse update(@RequestBody AlarmDownloadDTO[] rowList) {
System.out.println("hola");
return new StatusResponse();
}
Это был мой пример DTO (id get/set и preAlarm get Методы не включены для сокращения кода):
@JsonIgnoreProperties(ignoreUnknown = true)
public class AlarmDownloadDTO implements Serializable {
private static final SimpleDateFormat formatHHmm = new SimpleDateFormat("HH:mm");
private String id;
private Date preAlarm;
public void setPreAlarm(Date date) {
this.preAlarm == date;
}
public void setPreAlarm(String date) {
try {
this.preAlarm = formatHHmm.parse(date);
} catch (ParseException e) {
this.preAlarm = null;
} catch (NullPointerException e){
this.preAlarm = null;
}
}
}
Чтобы сделать все, вам нужно удалить метод с параметром Date type. Эта ошибка очень расстраивает. Надеюсь, это может сэкономить часы отладки.
public void setParameters(List<Parameter> parameters)
и public void setParameters(Parameter... parameters)
в addParameters
, и изменение последнего на addParameters
решило проблему для меня.
добавление типа контента в запрос как application/json
разрешило проблему
Я столкнулся с этой проблемой, когда я интегрировал загрузку spring с spring mvc. Я решил это, просто добавив эти зависимости.
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>
Я столкнулся с подобной проблемой, и именно так я ее исправил,
Проблема связана с процессом преобразования с JSON на Java, необходимо иметь правильные библиотеки Jackson для запуска, чтобы преобразование произошло правильно.
Добавьте следующие банки (через зависимость или путем загрузки и добавления в путь к классам.
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>
Это должно решить проблему.
Полный код:
function() {
$.ajax({
type: "POST",
url: "saveUserDetails.do",
data: JSON.stringify({
name: "Gerry",
ity: "Sydney"
}),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
success: function(data) {
if (data.status == 'OK')
alert('Person has been added');
else
alert('Failed adding person: ' + data.status + ', ' + data.errorMessage);
}
и подпись контроллера выглядит следующим образом:
@RequestMapping(value = "/saveUserDetails.do", method = RequestMethod.POST)
public @ResponseBody Person addPerson( @RequestBody final Person person) {
Надеюсь это поможет
jackson-databind
.
Небольшая сторона примечания - наткнулась на эту же ошибку при разработке веб-приложения. Ошибка, которую мы обнаружили, благодаря использованию сервиса с Firefox Poster, заключалась в том, что оба поля и значения в Json должны быть окружены двойными кавычками. Например..
[ {"idProductCategory" : "1" , "description":"Descrizione1"},
{"idProductCategory" : "2" , "description":"Descrizione2"} ]
В нашем случае мы заполнили json через javascript, что может немного запутать, когда дело касается одиночных/двойных кавычек, из того, что я слышал.
То, что было сказано ранее в этом и других сообщениях, например, включая заголовки "Accept" и "Content-Type", также применяется.
Надежды.
У меня была та же проблема. Я должен был выполнить следующие действия, чтобы решить проблему:
1. Убедитесь, что у вас есть следующие зависимости:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-version}</version> // 2.4.3
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-version}</version> // 2.4.3
</dependency>
2. Создайте следующий фильтр:
public class CORSFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String origin = request.getHeader("origin");
origin = (origin == null || origin.equals("")) ? "null" : origin;
response.addHeader("Access-Control-Allow-Origin", origin);
response.addHeader("Access-Control-Allow-Methods", "POST, GET, PUT, UPDATE, DELETE, OPTIONS");
response.addHeader("Access-Control-Allow-Credentials", "true");
response.addHeader("Access-Control-Allow-Headers",
"Authorization, origin, content-type, accept, x-requested-with");
filterChain.doFilter(request, response);
}
}
3. Применить указанный фильтр для запросов в web.xml
<filter>
<filter-name>corsFilter</filter-name>
<filter-class>com.your.package.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>corsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Надеюсь, это полезно кому-то.
jackson-core
- это зависимость jackson-databind
, поэтому нет необходимости добавлять его напрямую.
Весенний ботинок + весенний мвн
с проблемой @PostMapping ("/addDonation") public String addDonation (@RequestBody DonatorDTO donatorDTO) {
с решением @RequestMapping (value = "/addDonation", method = RequestMethod.POST) @ResponseBody public GenericResponse addDonation (окончательный DonatorDTO donatorDTO, окончательный запрос HttpServletRequest) {
Я решил эту проблему, добавив данные привязки джексон-json к моему pom.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.3</version>
</dependency>
pom.xml:
...
<properties>
<springframework.version>4.3.1.RELEASE</springframework.version>
</properties>
...
<packaging>war</packaging>
...
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<finalName>spring-rest-demo</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>dependency-jars/</classpathPrefix>
</manifest>
</archive>
<webXml>${project.basedir}\src\main\webapp\WEB-INF\web.xml</webXml>
</configuration>
</plugin>
</plugins>
</build>
...
SRC/Основной/Java/WebApp/WEB-INF/web.xml:
...
<display-name>Spring MVC Application</display-name>
<servlet>
<servlet-name>RestDemo</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>RestDemo</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
...
SRC/Основной/Java/WebApp/WEB-INF/RestDemo-servlet.xml:
...
<mvc:annotation-driven/>
<context:component-scan base-package="your.package.path" />
...
Контроллер REST:
без каких-либо проверок данных, только для образовательных целей
@RestController
public class SpringRestServiceImpl implements SpringRestService {
@Autowired
private VideoGameDao videoGameDao;
...
@RequestMapping(value = "/rest/save", method = RequestMethod.POST, consumes = {"application/json"})
@Override
public ResponseEntity save(@RequestBody VideoGame videoGame) {
return ResponseEntity.ok(videoGameDao.save(videoGame));
}
...
}
с curl:
curl -i -POST -H "Content-Type: application/json" -d "your-json-here" http://yourserver:8080/spring-rest-demo/rest/save
или с помощью Postman tool
1.а. Добавьте в applicationContext-mvc.xml следующее
XMLNS: = MVC "http://www.springframework.org/schema/mvc" XSI: SchemaLocation = " http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc
var productCategory = { idProductCategory: 1, description: "Descrizione2" };
быть более кратким и легким для чтения? Вам нужно сказать Spring, чтобы он принималapplication/json
? Другими словами, это ожидает, что данные придут в форме?