2009-06-27 2 views
3

저는 스프링 MVC를 처음 사용하지만 Java의 웹 개발에는 새로운 것은 아닙니다. 간단한 폼 -> 컨트롤러 예제를 만들려고합니다.스프링 MVC 폼 입력 값은 항상 null입니다.

양식, 양식 컨트롤러 (아래에 붙여 넣은 컨텍스트 XML로 구성) 및 모델 (간단한 bean)이 있습니다. 양식을 제출할 때 텍스트 입력 값은 상관없이 항상 null입니다. 어떤 아이디어?

양식 컨트롤러 봄 구성 : 다음

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 

    <!-- controllers --> 

    <bean name="/home.html" class="atc.web.view.controller.HomeController" /> 

    <!--bean name="/mirror.html" class="atc.web.view.controller.MirrorController" --> 

    <bean name="/url-cache.html" class="atc.web.view.controller.URLCacheFormController"> 
     <property name="synchronizeOnSession" value="true" /> 
     <!--property name="sessionForm" value="false"--> 
     <property name="commandName" value="urlForm"/> 
     <property name="commandClass" value="atc.web.view.model.URLBean"/> 
     <property name="validator"> 
      <bean class="atc.web.view.validators.URLValidator"/> 
     </property> 
     <property name="formView" value="mirror"/> 
     <property name="successView" value="url-cache.html"/> 
     <property name="URLCachingService" ref="urlCachingService" /> 
    </bean> 

    <!-- end controllers --> 

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
     <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> 
     <property name="prefix" value="/WEB-INF/jsp/" /> 
     <property name="suffix" value=".jsp" /> 
    </bean> 

    <!-- custom beans --> 

    <bean id="breakcrumbInjectionFilter" class="atc.web.view.filter.BreadcrumbInjectionFilter"> 
     <property name="contextPrefix" value="/home-web" /> 
    </bean> 

    <!-- end custom beans --> 
</beans> 

는 JSP 내 양식이 포함되어 같이

public class URLCacheFormController extends SimpleFormController { 
    private URLCachingService cachingService; 

    private static Logger log = Logger.getLogger(URLCacheFormController.class); 

    public ModelAndView onSubmit(Object command) throws ServletException { 
     log.debug(String.format("URLCachingFormController received request with object '%s'", command)); 
     URLBean urlBean = (URLBean) command; 
     try { 
      URL url = new URL(urlBean.getUrl()); 
      URLCache cache = cachingService.cacheURL(url); 
      cache.cacheToTempFile(); 

     } catch (IOException e) { 
      log.error("Invalid URL...", e); 
     } 
     return new ModelAndView(new RedirectView(getSuccessView())); 
    } 

    protected Object formBackingObject(HttpServletRequest request) throws ServletException { 
     log.debug("formBackingObject() "); 
     return new URLBean(); 
    } 

    public void setURLCachingService(URLCachingService cachingService) { 
     this.cachingService = cachingService; 
    } 
} 

의 모든 :

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 
<%@ page contentType="text/html;charset=UTF-8" language="java" %> 
<%@ include file="/WEB-INF/jspf/core/taglibs.jspf" %> 
<html> 
<head><title>Simple tools</title></head> 
<style> 
.error s { 
    color:#FF0000; 
} 
</style> 
<body> 
<%@ include file="/WEB-INF/jspf/nav/nav.jspf" %> 
    Errors: <form:errors path="url" cssClass="error"/> 
    <form:form method="post" commandName="urlForm"> 
     <form:input path="url" /> 
     <input type="submit" align="center" value="Execute" /> 
    </form:form> 
</body> 
</html> 

여기 내 컨트롤러의 전체 소스입니다 위의 코드는 다음 HTML을 생성합니다.

<html> 
<head></head> 
<body> 
<div><span><a href="home.html">Home </a></span><span> | <a href="url-cache.html">Page Mirror</a></span></div> 
<div id="breadcrumb"><span>Your trail:<a href=""/></span></div>Attrs:<div/> 
<form id="urlForm" method="post" action="/home-web/url-cache.html"> 
<input id="url" type="text" value="" name="url"/> 
<input type="submit" align="center" value="Execute"/> 
</form> 
</body> 
</html> 

지금은 doSubmitAction(Object command)을 무시하지만 아직 방법을 사용하지 않습니다. 양식은 제출되지만 다음 양식은 공백 양식으로 표시됩니다 ( formBackingObject(HttpServletRequest request)이 호출 된 후).

즉, 제출할 때 양식 컨트롤러에서 doSubmitAction의 1 번 줄에 로깅 호출이 실행되지 않습니다. 유효성 검사기는 실행중인 값이 항상 null (또는 올바르게 입력되었으므로 설정되지 않았습니다.)이므로 오류 메시지를 올바르게 실행하지 못하고 오류 메시지를 추가하지 못합니다. 그러나 formBackingObject에 대한 호출이 항상 발생합니다. 내 양식의 요청 속성 (양식 입력 'url')은 항상 null입니다.

업데이트 : - 같은 양식에서 'URL'의 값으로 OK, 몇 가지 심각한 디버깅 후 그래서이 문제를 확인 할 수 serg555 제안 및 검증을 제거로 요청 매개 변수를 매핑 것 같다 - 내 명령/콩; 즉, URL이 결코 내 bean에 설정되어 있지 않거나 bean이 재생성 중입니다.

도와주세요.

+0

URL을 컨트롤러에 매핑 한 방법을 표시하지 않습니다. 앱 컨텍스트에서 그렇게 할 수 있습니까? 아마도 당신은 질문을 업데이트해서 그것을 보여 주어야 할 것입니다. – duffymo

+0

URL 매핑은 이미 제공 한 스프링 컨텍스트 XML에서 정의됩니다. 그러나 명확성을 위해 나머지 컨텍스트 XML을 추가했습니다. –

+0

이 질문에 대한 답변이 아니지만 이전 FormCintroller 계층 구조 대신 Spring 2.5 스타일 주석이 달린 컨트롤러를 사용하는 것이 더 쉽습니다. 상당히 간단하고 직관적입니다. – skaffman

답변

1

그 이유는 내 양식 bean이 Java Bean 계약을 준수하지 못했기 때문입니다. setter가 void 대신 리턴되어 Spring이 호출 할 수 없습니다.

+0

그게 도움이되었습니다. 감사합니다! 수업 시간에 세터가 누락되었습니다. –

2

나는 문제가, 내가 당신에게 작동하는 내 컨트롤러를 보여주게된다 모르고 어쩌면 당신은 무엇이 잘못되었는지 알아낼 수있을 것입니다 :

public class TestController extends SimpleFormController { 

    public TestController() { 
     setFormView("testView"); 
     setSuccessView("testView"); 
     setCommandClass(TestCmd.class); 
     setCommandName("cmd"); 
    } 

    protected Object formBackingObject(HttpServletRequest request)throws Exception { 
     Object o = super.formBackingObject(request); 
     TestCmd cmd = (TestCmd) o; 

     return cmd; 
    } 


    public ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object obj, BindException errors) throws Exception { 

     TestCmd cmd = (TestCmd) obj; 

     log.debug("test value = " + cmd.getTestValue()); 

     return super.onSubmit(request, response, obj, errors); 
    } 

} 

형태 :

<form method="post" action="/test.html"> 
    <form:input path="cmd.testValue"/> 
    <input type="submit"> 
</form> 

<bean id="urlMapping" 
     class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> 
     <property name="alwaysUseFullPath" value="true" /> 
     <property name="mappings"> 
      <props> 
       <prop key="/test.html">testController</prop> 
      </props> 
     </property> 
    </bean> 
    <bean id="testController" 
     class="com.sample.TestController"> 
     <property name="synchronizeOnSession" value="true" /> 
     <property name="validator"> 
      <bean class="com.sample.TestValidator"/> 
     </property> 
    </bean> 

검사기 :

앱-servlet.xml 파일 내부
public class TestValidator implements Validator { 

    public boolean supports(Class clazz) { 
     return (TestCmd.class.equals(clazz)); 
    } 

    public void validate(Object obj, Errors errors) { 
     TestCmd cmd = (TestCmd) obj; 
     if (obj == null) { 
      // nothing 
     } else { 

      ValidationUtils.rejectIfEmptyOrWhitespace(errors, "testValue", null, "<b>Value</b> is required"); 

     } 
    } 

} 

명령 :

public class TestCmd { 

    private String testValue; 

    public TestCmd() { 
    } 

    public String getTestValue() { 
     return testValue; 
    } 

    public void setTestValue(String testValue) { 
     this.testValue = testValue; 
    } 

} 
+1

빈의 정의가 잘못되었습니다. 속성 설정자의 반환 유형은 void가 아닙니다. 도와 주셔서 감사합니다. –

1

OK, 당신이 컨트롤러 내에서 설정된 URL이 매핑 명령 빈에 맞는지 제안하는 JSP로를 통해 올 않는 것을 확인했습니다.

한 가지 더."onSubmit"코드에 결코 도달하지 못하면 컨트롤러가 양식 제출 여부를 알아내는 것이 문제 일 수 있습니다. 제출 버튼에 이름 속성을 추가하고 "isFormSubmission"을 재정 의하여 해당 이름이 있는지 여부 (즉, 제출 버튼을 클릭했는지 여부)를 확인할 수 있습니다. 그렇다면 isFormSubmission은 true를 리턴해야합니다. (이것은 필수적이지 않아야합니다 - 기본적으로 컨트롤러는 POST 요청이 폼 제출이라고 가정합니다.하지만 문제에 대해 더 많이 알게되고 적어도 해결 방법을 찾을 수 있다면 도움이 될 것입니다. .)

+0

시도해 보니 값이 변하지 않는 것처럼 보입니다. 초기 값을 "http://google.com"으로 설정 한 다음 양식에서 변경하고 제출하면 수정 된 값이 없습니다. 이전에 설정된대로 "http://google.com"만 있습니다. –

+0

좋습니다.하지만 맵핑이 폼의 배경 객체에서 JSP의 필드로 작동한다는 것을 제안합니다. 명령 빈의 코드를 게시 할 수 있습니까? –

+0

위의 답변이 변경되었으므로 다시 읽으십시오. :) –

0

aplication-context.xml에 다음 코드를 삽입하십시오. encType = multipart/form-data 형식 인 경우 솔루션이 될 수 있습니다.

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 
<property name="maxUploadSize" value="10000000"/> 
</bean> 

또한 jsp 페이지에서 콘텐츠 유형을 삭제하려고합니다. 글쎄 내 경우에 이것은 나를 도왔다 ... !!

+0

이것은 전혀 관련이 없습니다. 이후 수정 사항을 설명하는 게시물을 추가했습니다 (주석에 묻어 있음). –

+0

친구는 2 일 동안이 문제로 인해 어려움을 겪었으므로 여기에 적어 두었습니다. 아무도 똑같은 문제로 어려움을 겪고 있다면 도움을받을 수 있습니다. 대답은 stackoverflow를 처음 접했을 때 무관 할 수 있습니다. (내 평판 참조) – HVT7

0

많은 시간을 들여 비슷한 문제를 조사했습니다. 마지막으로 바인더의 초기화 메서드 내부에서 범인을 찾았습니다.

@InitBinder 
void allowFields(final WebDataBinder binder) { 
    binder.setAllowedFields("name"); 
} 

이 메서드는 바인딩이 허용되는 필드에 대한 제한을 설정합니다. 다른 모든 필드는 묶여 있지 않으므로 자연히 null 값이됩니다.