[jsf] commandButton / commandLink / ajax 액션 / 리스너 메소드가 호출되지 않거나 입력 값이 설정 / 업데이트되지 않았습니다

사용하는 경우 때때로 <h:commandLink>, <h:commandButton>또는 <f:ajax>action, actionListener또는 listener태그와 관련된 메소드는 호출되지 않습니다. 또는 Bean 특성이 제출 된 UIInput값으로 업데이트되지 않습니다 .

이에 대한 가능한 원인과 해결책은 무엇입니까?



답변

소개

때마다 UICommand구성 요소 ( <h:commandXxx>, <p:commandXxx>, 등) 관련 액션 메소드, 또는 호출에 실패 UIInput구성 요소를 ( <h:inputXxx>, <p:inputXxxx>, 등) 제출 된 값을 처리 및 / 또는 모델의 값을 업데이트하는 데 실패하고 당신은 어떤 googlable 예외가 표시되지 및 / 또는 서버 로그에 경고, 또한 당신이 따라 아약스 예외 핸들러를 구성 할 때 JSF 아약스 요청에 처리 예외 않으며, 당신이 컨텍스트 매개 변수 아래에 설정하면 web.xml,

<context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
</context-param>

또한 브라우저의 JavaScript 콘솔에 googlable 오류 및 / 또는 경고가 표시되지 않습니다 (Chrome / Firefox23 + / IE9 +에서 F12를 눌러 웹 개발자 툴셋을 연 다음 콘솔 탭을여십시오). 아래 가능한 원인 목록을 확인하십시오.

가능한 원인들

  1. UICommandUIInput구성 요소는 내부에 위치해야합니다 UIForm구성 요소, 예를 들어, <h:form>(그리고하지 일반 HTML <form>, 그렇지 않으면 아무것도 서버에 전송 될 수 없다). UICommand구성 요소에도 type="button"속성 이 없어야 합니다. 그렇지 않으면 JavaScript에만 유용한 데드 버튼이됩니다 onclick. 참조 양식 입력 값을 전송하는 방법 및 JSF 빈의 메소드 호출<시간 :있는 명령을> 다시 게시를 시작하지 않습니다 .

  2. 여러 UIForm구성 요소를 서로 중첩 할 수 없습니다 . 이것은 HTML에서 불법입니다. 브라우저 동작이 지정되지 않았습니다. 포함 파일을 조심하십시오! UIForm컴포넌트를 병렬로 사용할 수 있지만 제출 중에 서로를 처리하지 않습니다. 또한 “신 양식”반 패턴을 조심해야합니다. 의도하지 않은 다른 모든 (보이지 않는) 입력을 동일한 형식으로 처리하거나 확인하지 않도록하십시오 (예 : 동일한 입력의 필수 입력을 가진 숨겨진 대화 상자가있는 경우). 참조 JSF 페이지에서 : <양식 H>를 사용하는 방법? 단일 양식? 여러 형태? 중첩 된 양식? .

  3. 어떤 UIInput값 검증 / 변환 오류가 발생하지합니다. <h:messages>입력 별 <h:message>구성 요소에 표시되지 않은 메시지를 표시하는 데 사용할 수 있습니다 . 인클루드하는 것을 잊지 마십시오 id<h:messages>에서 <f:ajax render>가 아니라 아약스 요청에 업데이트됩니다 그래서 (있는 경우)를. p : commandButton을 누르면 h : messages에 메시지가 표시되지 않음 도 참조하십시오 .

  4. 경우 UICommand또는 UIInput구성 요소가 반복하는 구성 요소의 내부에 배치처럼 <h:dataTable>, <ui:repeat>등, 당신은 정확히 같은 확인해야합니다 value(가) 요청을 제출 양식의 요청 값 위상을 적용하는 동안 보존되어있는 반복하는 구성 요소. JSF는이를 다시 클릭하여 클릭 한 링크 / 버튼 및 제출 된 입력 값을 찾습니다. Bean을 뷰 범위에 배치하거나 Bean의 데이터 모델을로드하여 @PostConstructgetter 메소드가 아닌지 확인하여 수정하십시오. h : dataTable에 대한 데이터베이스에서 모델을로드하는 방법과시기 도 참조하십시오 .

  5. 경우 UICommand또는 UIInput구성 요소가 같은 동적 소스가 포함되어 있습니다 <ui:include src="#{bean.include}">, 당신은 정확히 같은 있는지 확인해야 #{bean.include}값이 양식의보기 빌드 시간 요청을 제출하는 동안 보존됩니다. 컴포넌트 트리를 빌드하는 동안 JSF가 다시 실행합니다. Bean을 뷰 범위에 배치하거나 Bean의 데이터 모델을로드하여 @PostConstructgetter 메소드가 아닌지 확인하여 수정하십시오. 탐색 메뉴로 동적 포함 컨텐츠를 아약스 새로 고치는 방법을 참조하십시오 . (JSF SPA) .

  6. rendered컴퍼넌트와 그 모든 부모와의 속성 test모든 부모의 속성은 <c:if>/ <c:when>에 평가 안 false(가) 요청을 제출 양식의 요청 값 위상을 적용하는 동안. JSF는 변조 / 해킹 요청에 대한 보호의 일부로이를 다시 검사합니다. A의 조건에 대한 변수가 책임을 보관 @ViewScoped콩이나 제대로 조건을 preinitializing하고 있는지 확인하고 @PostConstruct(A)의 @RequestScoped그것을 수정해야 콩. disabled구성 요소 속성 에도 동일하게 적용되며 , 이는 true요청 값 적용 단계에서 평가되어서는 안됩니다 . 참조 JSF있는 명령 조치가 호출되지 , 폼 처리되지 조건부 렌더링 구성 요소에 제출 하고<h : panelGroup rendered>에 래핑하면 h : commandButton이 작동하지 않습니다 .

  7. onclick의 속성 UICommand구성 요소와 onsubmit의 속성 UIForm구성 요소는 반환하지 않아야 false또는 자바 스크립트 오류가 발생합니다. 의 경우가해야 <h:commandLink>하거나 <f:ajax>또한 브라우저의 JS 콘솔에서 볼 수없는 JS 오류 수 없습니다. 일반적으로 정확한 오류 메시지를 인터넷 검색하면 이미 답변이 제공됩니다. 참조 catch되지 않은 TypeErrors에서 PrimeFaces 결과에 수동으로 추가 /로드 jQuery를 .

  8. JSF 2.x <f:ajax>또는 PrimeFaces 를 통해 Ajax를 사용하는 경우 . 대신 마스터 템플릿 <p:commandXxx>이 있는지 확인하십시오 . 그렇지 않으면 JSF는 Ajax 함수가 포함 된 필요한 JavaScript 파일을 자동으로 포함 할 수 없습니다. 브라우저의 JS 콘솔에서 “mojarra is not defined”또는 “PrimeFaces is not defined”와 같은 JavaScript 오류가 발생합니다. 참조 시간을 : f를 함께 사용하면 CommandLink는 용의 ActionListener가 호출되지 않습니다 아약스 및 UI : 반복 .<h:head><head>

  9. Ajax를 사용하는 경우 제출 된 값이로 끝나는 경우 관심 null있는 UIInputUICommand구성 요소가 <f:ajax execute>또는 로 덮여 있는지 확인하십시오 <p:commandXxx process>. 그렇지 않으면 실행 / 처리되지 않습니다. <h : commandButton>에 <f : ajax>를 추가 하고 PrimeFaces 프로세스 / 업데이트 및 JSF f : ajax 실행 / 렌더 속성 이해 시 모델에서 업데이트되지 않은 제출 된 양식 값을 참조하십시오 .

  10. 제출 된 값이 여전히로 끝나고 nullCDI를 사용하여 Bean을 관리하는 경우 올바른 패키지에서 범위 어노테이션을 가져와야합니다. 그렇지 않으면 CDI는 기본적으로 @DependentEL의 모든 단일 평가에서 Bean을 효과적으로 다시 작성합니다. 표현. 또한 참조 콩 푼다 범위를 @SessionScoped 모든 시간을 다시 가져옵니다 필드가 null이 될기본은 JSF 2 애플리케이션에서 관리 빈 범위 무엇입니까?

  11. 버튼이 있는 <h:form>with의 부모가 UICommand동일한 페이지의 다른 양식에서 오는 ajax 요청에 의해 미리 렌더링 / 업데이트 된 경우 첫 번째 조치는 항상 JSF 2.2 이상에서 실패합니다. 두 번째 및 후속 조치가 작동합니다. 이는 JSF 스펙 문제 790 으로보고 되고 현재 JSF 2.3에서 수정 된 뷰 상태 처리의 버그로 인해 발생합니다 . 이전의 JSF 버전의 경우 명시 적으로의 ID를 지정해야 <h:form>에서 render<f:ajax>. 참조 시간을 :있는 명령 / h는 : CommandLink는이 첫 번째 클릭에서 작동하지 않습니다, 단지 두 번째 클릭에서 작동합니다 .

  12. 이 경우 <h:form>enctype="multipart/form-data"지원 파일 업로드하기 위해 설정 한 다음 당신은 당신이, 그렇지 않으면 적어도 JSF 2.2를 사용하거나 다중 / 폼 데이터 요청을 구문 분석을 담당하는 서블릿 필터가 제대로 구성되어 있는지하고 있는지 확인해야 FacesServlet의지를 결국 요청 매개 변수가 전혀 없으므로 요청 값을 적용 할 수 없습니다. 이러한 필터를 구성하는 방법은 사용중인 파일 업로드 구성 요소에 따라 다릅니다. Tomahawk의 경우이 답변을<t:inputFileUpload> 확인 하고 PrimeFaces의 경우이 답변을 확인 하십시오 . 또는 실제로 파일을 전혀 업로드하지 않는 경우 속성을 모두 제거하십시오.<p:fileUpload>

  13. ActionEvent인수 actionListenerjavax.faces.event.ActionEventand not not 인지 확인하십시오. java.awt.event.ActionEvent이것이 대부분의 IDE에서 첫 번째 자동 완성 옵션으로 제안하는 것입니다. 당신이 사용한다면 인수가 없다는 것도 잘못 actionListener="#{bean.method}"입니다. 메소드에 인수를 원하지 않으면을 사용하십시오 actionListener="#{bean.method()}". 아니면 실제로 action대신에 사용하고 싶을 수도 있습니다 actionListener. action과 actionListener의 차이점을 참조하십시오 .

  14. 없는지를 확인 PhaseListener또는 EventListener요청 – 응답 체인의 예를 들어 호출하여 호출 작업 단계 건너 뛸 수있는 JSF 라이프 사이클 변경 FacesContext#renderResponse()또는 FacesContext#responseComplete().

  15. 어쨌든 같은 요청-응답 체인이 아니 Filter거나 Servlet요청을 차단 하지 않았는지 확인하십시오 FacesServlet. 예를 들어, 스프링 보안과 같은 로그인 / 보안 필터. 특히 기본적으로 UI 피드백이없는 아약스 요청에서 발생합니다. Spring Security 4 및 PrimeFaces 5 AJAX 요청 처리 도 참조하십시오 .

  16. 당신이 PrimeFaces 사용하는 경우 <p:dialog>또는를 <p:overlayPanel>하고 있는지 그들은 자신이 있는지 확인 <h:form>. 이러한 컴포넌트는 기본적으로 JavaScript로 HTML 끝으로 재배치됩니다 <body>. 따라서 원래 내부에 앉아 <form>있었다면 이제 더 이상에 앉아 있지 않습니다 <form>. 참조 페이지를 :있는 명령 조치가 페이지 내에서 작업을하지 않는 : 대화를

  17. 프레임 워크의 버그. 예를 들어 RichFaces에는 속성이 있는 UI 요소 (또는 경우에 따라 하위 요소)를 사용할 때 ” 변환 오류 “가 있습니다. 이 버그는 달력 날짜에 값이 설정되지 않은 경우 Bean 메소드가 호출되지 않도록합니다. 간단한 작업 예제로 시작하고 버그가 발견 될 때까지 페이지를 백업하여 프레임 워크 버그를 추적 할 수 있습니다.rich:calendardefaultLabelrich:placeholder

디버깅 힌트

여전히 멈췄다면 이제 디버깅해야합니다. 클라이언트 측에서 웹 브라우저에서 F12를 눌러 웹 개발자 툴셋을 엽니 다. 콘솔 탭을 클릭하면 JavaScript conosle이 표시됩니다. JavaScript 오류가 없어야합니다. 아래 스크린 샷은 Chrome의 예이며, 위의 7 항에 설명 된대로 선언 <f:ajax>되지 않은 상태 에서 활성화 된 버튼을 제출하는 경우를 보여줍니다 <h:head>.

JS 콘솔

네트워크 탭을 클릭하여 HTTP 트래픽 모니터를보십시오. 양식을 제출하고 요청 헤더 및 양식 데이터와 응답 본문이 예상과 같은지 조사하십시오. 스크린 샷 아래의 성공적인 아약스가 하나와 간단한 양식의 제출을 보여 크롬에서 예입니다 <h:inputText>단일 <h:commandButton>와 함께 <f:ajax execute="@form" render="@form">.

네트워크 모니터

(경고 : 프로덕션 환경에서 위와 같은 HTTP 요청 헤더에서 스크린 샷을 게시 할 때 세션 하이재킹 공격을 피하기 위해 스크린 샷에서 세션 쿠키를 스크램블 / 난독 처리해야합니다!)

서버 측에서 서버가 디버그 모드에서 시작되었는지 확인하십시오. 양식 제출을 처리하는 동안 호출 될 것으로 예상되는 JSF 구성 요소의 메소드에 디버그 중단 점을 두십시오. 예 :이 경우 UICommand구성 요소, 그 것 UICommand#queueEvent()과의 경우 UIInput구성 요소, 그 것이다 UIInput#validate(). 코드 실행을 단계별로 진행하고 흐름과 변수가 예상과 같은지 검사하십시오. 아래 스크린 샷은 Eclipse 디버거의 예입니다.

디버그 서버


답변

귀하의 h:commandLink내부에있는 h:dataTable경우 다른 이유가 h:commandLink있습니다.

링크 된 기본 데이터 소스 h:dataTable는 링크를 클릭 할 때 트리거되는 두 번째 JSF 라이프 사이클에서도 사용 가능해야합니다.

따라서 기본 데이터 소스가 요청 범위를 지정하면 h:commandLink작동하지 않습니다!


답변

내 대답은 100 % 적용 할 수는 없지만 대부분의 검색 엔진은 이것을 첫 번째 인기 항목으로 생각하지만 그럼에도 불구하고 게시하기로 결정했습니다.

당신이 사용하는 경우 PrimeFaces (또는 유사한 API)를 p:commandButton하거나 p:commandLink, 기회는 당신이 명시 적으로 추가 할 잊어 버린 것을있는 process="@this"명령의 구성 요소.

PrimeFaces 사용 설명서 섹션 3.18에서 언급 된 바와 같이, 대한 기본값 processupdate모두 @form거의 당신이 일반 JSF에서 기대할 수있는 기본적으로 반대하는, f:ajax또는이다 RichFaces, execute="@this"그리고 render="@none"각각을.

알아 내기 위해 나에게 충분한 시간을 보냈다. (… 그리고 JSF와 다른 기본값을 사용하는 것은 다소 번거로운 것 같습니다!)


답변

Primefaces와 관련하여 한 가지 더 언급하겠습니다 p:commandButton!

p:commandButton서버에서 수행해야 할 작업에 a 를 사용 하면 서버에 ajax / non-ajax 요청을 발생시키지 않고 사용자 지정 자바 스크립트를 실행하는 데 사용되는 푸시 버튼에 사용할 수 type="button"없기 때문에 사용할 수 없습니다 .

이를 위해 type속성을 분배하거나 (기본값은 "submit") 명시 적으로 사용할 수 있습니다 type="submit".

이것이 누군가를 도울 수 있기를 바랍니다!


답변

이 문제를 직접 해결 하고이 문제의 원인을 하나 더 발견했습니다. * .xhtml에 사용 된 특성에 대한 백킹 Bean에 setter 메소드가없는 경우 조치가 호출되지 않습니다.


답변

최근 IBM Extended Faces Components를 사용하여 JSF 1.2 애플리케이션에서 호출하지 않는 UICommand에 문제가 발생했습니다.

데이터 테이블의 행 (확장 버전 <hx:datatable>) 에 명령 단추가 있었고 UICommand는 테이블의 특정 행에서 실행되지 않습니다 (발행되지 않는 행은 기본 행 표시 크기보다 큰 행이었습니다).

표시 할 행 수를 선택하기위한 드롭 다운 구성 요소가 있습니다. 이 필드를 뒷받침하는 값은입니다 RequestScope. 테이블 자체를 뒷받침하는 데이터는 일종의 ViewScope(실제로는 일시적으로 SessionScope)있었습니다.

데이터 테이블의 rows속성에 바인드 된 제어를 통해 행 표시가 증가한 경우이 변경의 결과로 표시되는 행은 클릭 할 때 UICommand를 실행할 수 없습니다.

이 속성을 테이블 데이터 자체와 동일한 범위에두면 문제가 해결되었습니다.

위의 BalusC # 4에서 언급 한 것으로 생각되지만 테이블 값은 View 또는 Session 범위 여야 할뿐만 아니라 해당 테이블에 표시 할 행 수를 제어하는 ​​특성이어야했습니다.


답변

나는이 문제도 가지고 있었고 브라우저의 웹 콘솔을 연 후에 근본 원인을 찾기 시작했습니다. 그때까지는 오류 메시지를 얻을 수 없었습니다 (조차도 <p:messages>). 웹 콘솔에에서 HTTP 405 상태 코드가 다시 나타났습니다 <h:commandButton type="submit" action="#{myBean.submit}">.

제 경우에는 Auth0 및 JSF 페이스 렛을 통해 OAuth 인증을 제공하는 바닐라 HttpServlet과 애플리케이션 뷰 및 비즈니스 로직을 수행하는 Bean을 혼합했습니다.

web.xml을 리팩토링하고 중개인 서블릿을 제거하면 “마 법적으로”작동했습니다.

결론적으로, 문제는 Middle-man-servlet이 RequestDispatcher.forward (…)를 사용하여 HttpServlet 환경에서 JSF 환경으로 리디렉션하는 반면 서블릿은 HttpServletResponse.sendRedirect (.. ).

기본적으로 sendRedirect ()를 사용하면 JSF “컨테이너”가 제어 할 수 있지만 RequestDispatcher.forward ()는 분명히 그렇지 않습니다.

내가 모르는 것은 Facelet이 bean 속성에 액세스 할 수 있었지만 설정할 수 없었기 때문에 서블릿과 JSF의 혼합을 없애기 위해 비명을 지르지 만, 이것이 누군가가 많은 시간을 낭비하지 않도록 도와주기를 바랍니다. 테이블 뱅잉.