복붙노트

[SPRING] Spring 3.0 MVC @ModelAttribute 변수가 URL에 나타나지 않게하려면 어떻게합니까?

SPRING

Spring 3.0 MVC @ModelAttribute 변수가 URL에 나타나지 않게하려면 어떻게합니까?

Spring MVC 3.0.0.RELEASE를 사용하면 다음 컨트롤러를 사용할 수 있습니다.

@Controller
@RequestMapping("/addIntake.htm")
public class AddIntakeController{

  private final Collection<String> users;

  public AddIntakeController(){
    users = new ArrayList<String>();
    users.add("user1");
    users.add("user2");
    // ...
    users.add("userN");
  }

  @ModelAttribute("users")
  public Collection<String> getUsers(){
    return this.users;
  }

  @RequestMapping(method=RequestMethod.GET)
  public String setupForm(ModelMap model){

    // Set up command object
    Intake intake = new Intake();
    intake.setIntakeDate(new Date());
    model.addAttribute("intake", intake);

    return "addIntake";
  }

  @RequestMapping(method=RequestMethod.POST)
  public String addIntake(@ModelAttribute("intake")Intake intake, BindingResult result){

    // Validate Intake command object and persist to database
    // ...

    String caseNumber = assignIntakeACaseNumber();

    return "redirect:intakeDetails.htm?caseNumber=" + caseNumber;

  }

}

컨트롤러는 HTML 양식에서 채워진 명령 객체에서 가져 오기 정보를 읽고, 명령 객체의 유효성을 검사하고, 정보를 데이터베이스에 유지하고, 사례 번호를 반환합니다.

내가 intakeDetails.htm 페이지로 리다이렉트 할 때를 제외하고는 모든 것이 훌륭하게 작동합니다. 다음과 같은 URL이 있습니다 :

http : // localhost : 8080 / project / intakeDetails.htm? caseNumber = 1 & users = user1 & users = user2 & users = user3 & users = user4 ...

사용자 컬렉션이 URL에 나타나지 않게하려면 어떻게합니까?

해결법

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

    1.Spring 3.1부터 RequestMappingHandlerAdapter는 ignoreDefaultModelOnRedirect라는 플래그를 제공하여 컨트롤러가 리디렉션 할 때 defautl 모델의 내용을 사용하지 못하게 할 수 있습니다.

    Spring 3.1부터 RequestMappingHandlerAdapter는 ignoreDefaultModelOnRedirect라는 플래그를 제공하여 컨트롤러가 리디렉션 할 때 defautl 모델의 내용을 사용하지 못하게 할 수 있습니다.

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

    2.

    model.asMap().clear();
    return "redirect:" + news.getUrl();
    

    :)

  3. ==============================

    3.이 문제를 해결할 수있는 좋은 방법은 없습니다 (즉, 과도한 양의 명시 적 XML 구성없이 RedirectView를 수동으로 인스턴스화하지 않고도 맞춤 구성 요소를 만들지 않아도 됨).

    이 문제를 해결할 수있는 좋은 방법은 없습니다 (즉, 과도한 양의 명시 적 XML 구성없이 RedirectView를 수동으로 인스턴스화하지 않고도 맞춤 구성 요소를 만들지 않아도 됨).

    4- 인자 생성자를 통해 RedirectView를 수동으로 인스턴스화하거나 컨텍스트 (다른 ​​뷰 확인자 근처)에 다음 bean을 선언 할 수 있습니다.

    public class RedirectViewResolver implements ViewResolver, Ordered {
        // Have a highest priority by default
        private int order = Integer.MIN_VALUE; 
    
        // Uses this prefix to avoid interference with the default behaviour
        public static final String REDIRECT_URL_PREFIX = "redirectWithoutModel:";     
    
        public View resolveViewName(String viewName, Locale arg1) throws Exception {
            if (viewName.startsWith(REDIRECT_URL_PREFIX)) {
                String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length());
                return new RedirectView(redirectUrl, true, true, false);
            }
            return null;
        }
    
        public int getOrder() {
            return order;
        }
    
        public void setOrder(int order) {
            this.order = order;
        }
    }
    
  4. ==============================

    4.@ModelAttribute 메소드 주석은 참조 데이터를 뷰 레이어에 표시하는 데 사용됩니다. 귀하의 경우에는 분명히 말할 수는 없지만 참조 데이터로 자격이 부여 된 사용자 집단은 아닙니다. 이 정보를 @ RequestMapping-annotated 핸들러 메소드에서 명시 적으로 모델에 전달하는 것이 좋습니다.

    @ModelAttribute 메소드 주석은 참조 데이터를 뷰 레이어에 표시하는 데 사용됩니다. 귀하의 경우에는 분명히 말할 수는 없지만 참조 데이터로 자격이 부여 된 사용자 집단은 아닙니다. 이 정보를 @ RequestMapping-annotated 핸들러 메소드에서 명시 적으로 모델에 전달하는 것이 좋습니다.

    여전히 @ModelAttribute를 사용하려는 경우 여기에 리디렉션 문제를 설명하는 블로그 항목이 있습니다.

    그의 제안 된 솔루션 (블로그의 4 부 참조)은 HandlerInterceptorAdapter를 사용하여 공통 참조 데이터를 뷰에 표시하는 것입니다. 참조 데이터가 컨트롤러와 밀접하게 결합되어서는 안되기 때문에 설계 상 문제가되지 않습니다.

  5. ==============================

    5.나는이 질문과 대답이 오래되었다는 것을 알고 있지만, 비슷한 문제가 나 자신을 발견 한 후에 우연히 만났고 거기에서 내가 찾을 수있는 많은 다른 정보가 없다.

    나는이 질문과 대답이 오래되었다는 것을 알고 있지만, 비슷한 문제가 나 자신을 발견 한 후에 우연히 만났고 거기에서 내가 찾을 수있는 많은 다른 정보가 없다.

    나는 받아 들여진 대답이 아주 좋은 것이 아니라고 생각한다. axtavt에 의한 그 바로 아래의 대답이 훨씬 낫습니다. 컨트롤러의 모델 속성에 주석을다는 것이 의미가 있는지 여부가 문제가됩니다. 그것은 일반적으로 ModelAttributes를 사용하는 컨트롤러 내에서 "깨끗한"리디렉션을 발행하는 방법입니다. 컨트롤러 자체는 일반적으로 참조 데이터를 필요로하지만 때로는 예외적 인 조건이나 기타 상황을 위해 다른 곳으로 리디렉션해야하며 참조 데이터를 전달하는 것이 의미가 없습니다. 나는 이것이 유효한 공통 패턴이라고 생각한다.

    (Fwiw, 나는이 문제를 예기치 않게 Tomcat으로 돌렸다. 리다이렉트는 단순히 작동하지 않고 java.lang.ArrayIndexOutOfBoundsException : 8192와 같은 이상한 오류 메시지가 나타났다. 결국 나는 Tomcat의 기본 최대 헤더 길이가 8192라는 결론을 내렸다. ModelAttributes가 자동으로 리디렉션 URL에 추가되어 헤더 길이가 Tomcat의 최대 헤더 길이를 초과하게되었습니다.

  6. ==============================

    6.나는 복사와 붙여 넣기를 덜하면서 Sid의 답변을 변형시켰다 :

    나는 복사와 붙여 넣기를 덜하면서 Sid의 답변을 변형시켰다 :

    public class RedirectsNotExposingModelUrlBasedViewResolver extends UrlBasedViewResolver {
    
        @Override
        protected View createView(String viewName, Locale locale) throws Exception {
            View view = super.createView(viewName, locale);
            if (view instanceof RedirectView) {
                ((RedirectView) view).setExposeModelAttributes(false);
            }
            return view;
        }
    
    }
    

    또한 뷰 해석기 Bean을 정의해야합니다.

    <bean id="viewResolver" class="com.example.RedirectsNotExposingModelUrlBasedViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
    </bean>
    
  7. ==============================

    7.내 애플리케이션에서 모델 속성을 리다이렉트 (redirect)하는 데 사용할 유스 케이스가 없으므로 org.springframework.web.servlet.view.UrlBasedViewResolver를 확장하여 createView 메소드를 대체하고 애플리케이션 컨텍스트에서 선언 된 것을 사용했다.

    내 애플리케이션에서 모델 속성을 리다이렉트 (redirect)하는 데 사용할 유스 케이스가 없으므로 org.springframework.web.servlet.view.UrlBasedViewResolver를 확장하여 createView 메소드를 대체하고 애플리케이션 컨텍스트에서 선언 된 것을 사용했다.

    public class UrlBasedViewResolverWithouthIncludingModeAtttributesInRedirect extends   UrlBasedViewResolver {
    
            @Override
            protected View createView(String viewName, Locale locale) throws Exception {
                // If this resolver is not supposed to handle the given view,
                // return null to pass on to the next resolver in the chain.
                if (!canHandle(viewName, locale)) {
                    return null;
                }
                // Check for special "redirect:" prefix.
                if (viewName.startsWith(REDIRECT_URL_PREFIX)) {
                    String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length());
                    boolean exposeModelAttributes = false;
                    return new RedirectView(redirectUrl, isRedirectContextRelative(), isRedirectHttp10Compatible(), exposeModelAttributes);
                }
                // Check for special "forward:" prefix.
                if (viewName.startsWith(FORWARD_URL_PREFIX)) {
                    String forwardUrl = viewName.substring(FORWARD_URL_PREFIX.length());
                    return new InternalResourceView(forwardUrl);
                }
                // Else fall back to superclass implementation: calling loadView.
                return super.createView(viewName, locale);
            }
    
    }
    
    
      <bean id="viewResolver" class="com.acme.spring.UrlBasedViewResolverWithouthIncludingModeAtttributesInRedirect">
    
      </bean>
    
  8. ==============================

    8.나를 위해 일한 RedirectView 객체를 수동으로 생성 :

    나를 위해 일한 RedirectView 객체를 수동으로 생성 :

    @RequestMapping(method=RequestMethod.POST)
    public ModelAndView addIntake(@ModelAttribute("intake")Intake intake, BindingResult result){
    
        // Validate Intake command object and persist to database
        // ...
    
        String caseNumber = assignIntakeACaseNumber();
    
        RedirectView rv = new RedirectView("redirect:intakeDetails.htm?caseNumber=" + caseNumber);
        rv.setExposeModelAttributes(false);
        return new ModelAndView(rv); 
    }
    

    IMHO 리디렉션시 기본 동작이어야합니다.

  9. ==============================

    9.또는 요청을 POST로 만듭니다. Get 요청은 모델 속성을 URL에 나타나는 요청 매개 변수로만 표시합니다.

    또는 요청을 POST로 만듭니다. Get 요청은 모델 속성을 URL에 나타나는 요청 매개 변수로만 표시합니다.

  10. ==============================

    10.다음은 Java 기반 구성 (Spring 3.1 이상, 4.2로 테스트 한 것)으로이 작업을 수행하는 방법입니다.

    다음은 Java 기반 구성 (Spring 3.1 이상, 4.2로 테스트 한 것)으로이 작업을 수행하는 방법입니다.

    @Configuration
    public class MvcConfig extends WebMvcConfigurationSupport {
    
        @Override
        @Bean
        public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
            RequestMappingHandlerAdapter adapter = super.requestMappingHandlerAdapter();
            adapter.setIgnoreDefaultModelOnRedirect(true);
            return adapter;
        }
    
        // possible other overrides as well
    
    }
    
  11. ==============================

    11.@ModelAttribute를 사용하지 마십시오. ModelMap에 명시 적으로 사용자를 저장하십시오. 어쨌든 커맨드 객체를 많이 사용하고 있습니다.

    @ModelAttribute를 사용하지 마십시오. ModelMap에 명시 적으로 사용자를 저장하십시오. 어쨌든 커맨드 객체를 많이 사용하고 있습니다.

    @RequestMapping(method=RequestMethod.GET)
        public String setupForm(ModelMap model){
    
            // Set up command object
            Intake intake = new Intake();
            intake.setIntakeDate(new Date());
            model.addAttribute("intake", intake);
    
            model.addAttribute("users", users);
    
            return "addIntake";
        }
    

    단점은 addIntake ()에서 유효성 검사 오류가 발생하는 경우입니다. 단순히 양식의 논리 이름을 반환하려면 사용자에게 모델을 다시 채우는 것을 기억해야합니다. 그렇지 않으면 양식이 올바르게 설정되지 않습니다.

  12. ==============================

    12.원인을 찾는데 도움이된다면 해결 방법이 있습니다.

    원인을 찾는데 도움이된다면 해결 방법이 있습니다.

          @ModelAttribute("users")
          public Collection<String> getUsers(){
               return this.users;
          }
    

    여기에서 String Collection을 반환하게했습니다. Collection of User (사용자를 나타내는 클래스 래핑 문자열 또는 사용자에 관한 데이터가 포함 된 클래스)가 될 수 있습니다. 문제는 문자열에서만 발생합니다. 반환 된 Collection에 다른 객체가 포함되어 있으면이 작업이 수행되지 않습니다. 그러나 이는 단지 일시적인 해결책 일 뿐이고 전혀 필요하지는 않습니다. 그냥 내 두 센트. 그냥 그렇게 만드세요 -

          @ModelAttribute("users")
          public Collection<User> getUsers(){
               return this.users;
          }
    
  13. ==============================

    13.servlet-config.xml에 아래 코드를 추가하십시오.

    servlet-config.xml에 아래 코드를 추가하십시오.

    <mvc:annotation-driven ignoreDefaultModelOnRedirect="true" />
    

    때때로 이것은 문제를 해결할 것입니다.

  14. from https://stackoverflow.com/questions/2163517/how-do-i-prevent-spring-3-0-mvc-modelattribute-variables-from-appearing-in-url by cc-by-sa and MIT license