복붙노트

[SPRING] 스프링 MVC가 리다이렉트를하지 못하게하려면 어떻게해야합니까?

SPRING

스프링 MVC가 리다이렉트를하지 못하게하려면 어떻게해야합니까?

엔티티를 업데이트하는 AJAX 요청을 처리하려고합니다. 나는 아무것도 돌려 줄 필요가 없다. 문제는 Spring MVC가 같은 URL로 리다이렉트를 보낸다는 것이다. (분명히 리다이렉트 된 포스트 일을한다.) 브라우저가 충실히 따라한다.

Spring MVC 컨트롤러 메소드를 방금 완료하고 리다이렉트를 보내지 않고 리턴 할 수있는 방법은 무엇입니까? 웹에서 검색하는 것은 리디렉션을 수행하는 방법에 대한 무분별한 논의 일뿐, 회피를 피하는 방법이 아닙니다.

다음 헤더가있는 http : // localhost : 9090 / pex / api / testrun / f0a80b46-84b1-462a-af47-d1eadd779f59e에 대한 PUT 요청입니다.

Host: localhost:9090
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0
Accept: */*
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Length: 20
Content-Type: application/json
Referer: http://localhost:9090/pex/api/testrun/f0a80b46-84b1-462a-af47-d1eadd779f59e/visualizations/common-api?slas=lp,internal,external
X-Requested-With: XMLHttpRequest
Connection: keep-alive
Authorization: Basic xxxx

응답에 상태 코드 "302 Found"가 있으며 본문 내용 및 다음 헤더가 없습니다.

Content-Language: "de"
Content-Length: "0"
Location: "http://localhost:9090/pex/api/testrun/f0a80b46-84b1-462a-af47-d1eadd779f59e"
Server: "Jetty(6.1.10)"
access-control-allow-origin: "*"

다음은 서버 측 코드입니다.

@RequestMapping(value = "/api/testrun/{testrunId}", method = RequestMethod.PUT, consumes = "application/json")
@ResponseBody
public Testrun updateOverview(@PathVariable("testrunId") final String testrunId, @RequestBody final String body) {
    return testrunService.updateOverview(testrunId, body);
}

다음은 AJAX 호출을 만드는 자바 스크립트 코드입니다.

$(document).ready(function() {
    $("#update_name_form").submit(function (e) {
        update_testrun($("#name"));
        return false;
    });
}
function update_testrun(element) {
    var name = element.attr('name');
    var new_value = element.val().trim();
    var data = {};
    data[name] = new_value;
    $.ajax({url: config.urls.api.testrun + testrun.id,
            type: "PUT",
            contentType: "application/json",
            data: JSON.stringify(data),
            error: function(jqXHR, textStatus, errorThrown) {
                    alert(errorThrown);
            },
            success: function (data, textStatus, jqXHR) {
                    testrun.overview[name] = new_value;
            }
    });
}

해결법

  1. ==============================

    1.Spring MVC는 Servlet API 위에 구축된다. 따라서 HttpServletResponse에 액세스 할 수있는 모든 구성 요소는 이론적으로이를 사용하여 sendRedirect (String) 또는 응답 코드를 수동으로 설정할 수 있습니다. (이론적으로 말하면 응답이 이루어지면 응답이 커밋되지 않아야하기 때문입니다.)

    Spring MVC는 Servlet API 위에 구축된다. 따라서 HttpServletResponse에 액세스 할 수있는 모든 구성 요소는 이론적으로이를 사용하여 sendRedirect (String) 또는 응답 코드를 수동으로 설정할 수 있습니다. (이론적으로 말하면 응답이 이루어지면 응답이 커밋되지 않아야하기 때문입니다.)

    일반적으로 Spring MVC 애플리케이션에서 @Controller는 @RequestMapping 메소드의 HttpServletResponse (또는 ServletResponse)를 인수로 수신 할 수 있습니다.

    HandlerInterceptor는 DispatcherServlet의 요청 처리 라이프 사이클의 일부로 세 번 수신합니다.

    등록 된 서블릿 필터 인스턴스는 필터가 서블릿보다 먼저 작동하기 때문에 Spring의 DispatcherServlet 이전 및 이후에 ServletResponse에 대한 액세스 권한도 갖습니다.

    Spring은 이러한 모든 의존성을 Servlet API에 숨기고 프로그래밍 웹 서버를 더 쉽게 만들려고한다. 따라서 리디렉션을 발생시키는 다른 방법을 제공합니다. 이들은 주로 지원되는 핸들러 메소드 리턴 유형에 의존합니다. 더 구체적으로 말하자면 String, View, ModelAndView 및 ResponseEntity입니다.

    다음은 모두 기본 사례입니다.

    String을 반환하면 Spring은 ViewResolver를 사용하여 뷰의 이름을 식별하는 String 값을 기반으로 View를 해결합니다. Spring의 UrlBasedViewResolver는 String view 이름에서 redirect : 접두어를 감지하여 리다이렉트 응답을 보내기위한 표시로 간주한다. RedirectView를 생성합니다 (이 중 일부는 ViewNameMethodReturnValueHandler에서 실제로 수행되지만, UrlBasedViewResolver는 HttpServletResponse로 리디렉션을 담당 할 뷰를 생성합니다).

    이것은 구현 세부 사항이지만, Spring의 기본 ViewResolver 클래스 대부분이이를 수행합니다.

    View를 사용하면 직접 RedirectView를 만들고 반환 할 수 있습니다. 동일한 작업을 수행 할 자체 View 클래스를 구현할 수도 있습니다. Spring은 적절한 HandlerMethodReturnValueHandler를 사용하여 처리한다.

    ModelAndView를 사용하면 뷰 이름이나 뷰 자체를 제공 할 수 있으므로 두 가지 옵션이 혼합되어 있습니다.

    ResponseEntity를 사용하면 전체 응답을 제어하기 때문에 더욱 흥미로워집니다. 즉, 상태 코드, 헤더, 본문, 모든 것을 설정할 수 있습니다. 따라서 상태 코드를 302로 설정하고 리디렉션 할 URL이있는 Location 헤더를 입력하면됩니다.

    마지막으로, @ResponseStatus와 혼합하여 헤더를 수동으로 수정할 수있는 비슷한 반환 유형의 @ExceptionHandler 메서드에서도 비슷한 동작을 수행합니다.

    이것들은 모두 기본적인 경우이지만, Spring MVC가 거의 완벽하게 사용자 정의 가능하기 때문에,주의해야 할 다른 구성 요소가 있습니다. 이들은 HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler, HandlerAdapter, HandlerExceptionResolver 및 ExceptionHandler 등입니다. 당신은 거의 이것들을 가지고 놀지 않을 것이고 Spring과 함께 온 사람들은 거의 모든 일을 할 것임을 주목하십시오.

  2. ==============================

    2.그래서,

    그래서,

    귀하의 코드를 가져 와서 응용 프로그램을 만들었습니다. 브라우저 플러그인 POSTMAN을 사용하여 PUT 요청을 보내려고했지만 응답은 있지만 리다이렉션은 없었습니다. 이것이 작동하는지 확인하십시오. 나는 전체 수업을 첨부하고 있습니다, 당신은 복사하여 직접 응용 프로그램에서 사용할 수 있습니다.

    다음은 네트워크 헤더입니다.

    Remote Address:::1:8080
    Request URL:http://localhost:8080/test/api/testrun/hello
    Request Method:PUT
    Status Code:200 OK
    
    **Request Headers**
    Accept:*/*
    Accept-Encoding:gzip,deflate,sdch
    Accept-Language:en-GB,en-US;q=0.8,en;q=0.6,pl;q=0.4
    Authorization:Basic ZWFzeWwtbWFpbi1pbnQ6cHJnc3VzZXI=
    Cache-Control:no-cache
    Connection:keep-alive
    Content-Length:0
    Content-Type:application/json
    Host:localhost:8080
    Origin:chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm
    User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36
    
    **Response Headers**
    Cache-Control:private
    Content-Length:5
    Content-Type:text/plain;charset=ISO-8859-1
    Date:Tue, 10 Jun 2014 10:58:50 GMT
    Expires:Thu, 01 Jan 1970 05:30:00 IST
    Server:Apache-Coyote/1.1
    ConsoleSearchEmulationRendering
    

    다음은 코드입니다. 부팅을위한 스프링 구성

    @Configuration
    @EnableWebMvc
    @Profile("production")
    @ComponentScan(basePackages = "com", excludeFilters = { @ComponentScan.Filter(Configuration.class) })
    public class WebConfig extends WebMvcConfigurationSupport {
    
        @Override
        protected void configureContentNegotiation(
                ContentNegotiationConfigurer configurer) {
            configurer.favorPathExtension(false).favorParameter(true)
                    .parameterName("mediaType").ignoreAcceptHeader(true)
                    .useJaf(false).defaultContentType(MediaType.APPLICATION_JSON)
                    .mediaType("xml", MediaType.APPLICATION_XML)
                    .mediaType("json", MediaType.APPLICATION_JSON);
        }
    
        @Bean(name = "viewResolver")
        public InternalResourceViewResolver viewResolver() throws Exception {
            InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
    
            viewResolver.setPrefix("/jsp/");
            viewResolver.setSuffix(".jsp");
    
            return viewResolver;
        }
    }
    

    제어 장치

    @Controller
    public class TestController {
    
        @RequestMapping(value = "/api/testrun/{testrunId}", method = RequestMethod.PUT, consumes = "application/json")
        @ResponseBody
        public String updateOverview(@PathVariable("testrunId") final String testrunId) {
            System.out.println(testrunId);
    
            return "hello";
        }
    }
    

    을 포함한다.

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
    <display-name>test</display-name>
    
        <context-param>
          <param-name>contextClass</param-name>
          <param-value>
             org.springframework.web.context.support.AnnotationConfigWebApplicationContext
          </param-value>
        </context-param>
        <context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>com.WebConfig</param-value>
        </context-param>
        <context-param>
            <param-name>spring.profiles.active</param-name>
            <param-value>production</param-value>
        </context-param>
        <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    
        <servlet>
          <servlet-name>ui</servlet-name>
          <servlet-class>
             org.springframework.web.servlet.DispatcherServlet
          </servlet-class>
          <init-param>
             <param-name>contextClass</param-name>
             <param-value>
                org.springframework.web.context.support.AnnotationConfigWebApplicationContext
             </param-value>
          </init-param>
          <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
          <servlet-name>ui</servlet-name>
          <url-pattern>/</url-pattern>
        </servlet-mapping> 
    </web-app>
    
  3. ==============================

    3.Spring은 post-redirect 패턴을 사용할 것을 권장하지만 id는 기본적으로 아무것도하지 않습니다. 내 컨트롤러에서는 return "redirect : / url"에 의해 게시물을 다루는 메소드를 명확하게 끝내야합니다.

    Spring은 post-redirect 패턴을 사용할 것을 권장하지만 id는 기본적으로 아무것도하지 않습니다. 내 컨트롤러에서는 return "redirect : / url"에 의해 게시물을 다루는 메소드를 명확하게 끝내야합니다.

    리디렉션이 testrunService.updateOverview (testrunId, body);에서 수행 된 것으로 의심됩니다. 요구.

    편집 : 현실에서는 아무것도 testrunService.updateOverview (testrunId, 본문); @ResponseBody 주석으로 인해 리디렉션이 발생할 수 있습니다. 이와 같은 코드를 사용하면 인터셉터 나 필터 만 리디렉션을 수행 할 수 있습니다.

  4. from https://stackoverflow.com/questions/24086207/how-can-i-prevent-spring-mvc-from-doing-a-redirect by cc-by-sa and MIT license