403 по запросу JSON PUT для Tomcat с Spring 3.0.5 и Джексоном - PullRequest
2 голосов
/ 25 марта 2011

Мое веб-приложение начало возвращать 403 ошибки при запросах PUT.Тем не менее, я не вижу никаких сообщений отладки в журналах для этого запроса, поэтому я озадачен тем, как отлаживать это дальше.

Этот код работал, но произошел ряд недавних изменений:Клиент - Sencha JS:

Ext.Ajax.request({
        url       : '/RestWAR/personal/trailSegment/' + trailSegment.id + '.json',
        method    : 'PUT',
        headers   : {'Content-Type': 'application/json'},
        jsonData  : segmentDto
});

Контейнер - Apache Tomcat 6.0.Запрос отправляется в Spring Security 3.0.0.RC1 перед переходом на Spring 3.0.5.

@Controller
@RequestMapping("/personal")
public class PersonalController {
    @RequestMapping(value = "trailSegment/{trailSegmentId}", method=RequestMethod.PUT)
    public void updateTrailSegment(@PathVariable long trailSegmentId, @RequestBody PersonalTrailSegmentDTO trailSegmentDto) {
    //...
    }
}

Последние изменения: Spring был на 3.0.0.M4, а библиотека json была net.sf.json-lib 1.0.2.Spring теперь 3.0.5, а библиотека json теперь Jackson Mapper ASL 1.4.2 (то есть, что рекомендует Spring).

GET и POST работают нормально.Это просто ПУТЫ, которые терпят неудачу.

Если бы была задействована Spring Security, я бы видел отладочные сообщения от Spring Security, но вообще ничего не вижу.Похоже, что Tomcat останавливает запрос.

Заранее благодарен за любую помощь, особенно в том, что касается отладки.

Ответы [ 2 ]

1 голос
/ 26 марта 2011

Проблема возвращала нуль из метода updateTrailSegment().Это заставляет Spring пытаться отобразить запрос, используя InternalResourceView с URL-адресом того, что находится в запросе - то есть /RestWAR/personal/trailSegment/1761.InternalResourceView означает, что он пытается разрешить этот URL-адрес как путь в приложении.Так как его нет - он терпит неудачу.

Исправление должно использоваться в качестве типа возврата:

@ResponseBody ExtResponse

ExtResponse - это просто простой POJO для возврата кода ответа.* Полный метод теперь:

@RequestMapping(value = "trailSegment/{trailSegmentId}", method=RequestMethod.PUT)
public @ResponseBody ExtResponse updateTrailSegment(@PathVariable long trailSegmentId, @RequestBody PersonalTrailSegmentDTO trailSegmentDto) {
    trailSegmentDto.setId(trailSegmentId);
    PersonalTrailSegment trailSegment = trailSegmentAssembler.assembleDomain(trailSegmentDto);
    trailSegmentDataGateway.update(trailSegment);
    return new ExtResponse("true", "");
}
1 голос
/ 25 марта 2011

Мне интересно посмотреть, есть ли Решение этого, мы попали в ту же вещь с Tomcat 6.0.x и Spring 3.0.1 с использованием PUT & @RequestParam (я думаю, что мы тоже пробовали @RequestBody), PUT работали нормально с Jetty, но не с Tomcat, если вы не добавите Параметр для ссылки как? someParam = значение. Мы решили обойти это просто с помощью POST вместо.

Я только что опубликовал это как комментарий несколько минут назад, теперь, когда я вспомнил, когда мы нажали на это, я вспомнил, что нашел эту тему ( Параметры исчезают из PUTs ) о проблема тогда. Читая его, кажется, что разработчики Tomcat интерпретировали HTTP-спецификацию как означающую, что PUT не должен поддерживать параметры:

Ну, вы уверены, что запрос PUT на самом деле признает "параметры"? http://www.ietf.org/rfc/rfc2616.txt, раздел 9,6

Запрос PUT запрашивает, чтобы присоединенный объект (в теле запроса) храниться в месте, указанном URI. Но я не вижу ссылки на параметры здесь.

-

В любом случае, у них достаточно свободы действий абзацы, чтобы оправдать тот факт, что разработчики Tomcat, возможно, были оправдано не реализовывать обработка «параметров» для PUT Запросы; в то время как разработчики других двигатели сервлета, возможно, чувствовали оправдано в предоставлении такой обработки. Я пытаюсь подчеркнуть, что если вы создаете приложение, которое зависит от обрабатываемых параметров в запросе PUT вы можете создать приложение, которое не является переносимым для всех двигателей сервлетов или HTTP сервера. Но это, конечно, ваш выбор.

Все это вызывает вопрос однако: в предыдущем посте вы упоминаете, что запрос отлично работает как POST. Зачем тогда вы настаиваете, чтобы отправить его как PUT

...