Spring 4 MVC проверяет формы на стороне сервера - PullRequest
0 голосов
/ 24 октября 2018

Java 8 Spring 4.3

Я пытаюсь внедрить проверку формы Spring 4 MVC в мое веб-приложение, но сталкиваюсь с некоторыми препятствиями, а именно, похоже, я не могу проверить UPDATE.Множество примеров, показывающих, как применить проверку к новому объекту, а затем сохранить (вставить) .A

Приложение аварийно завершает работу с 500-дюймовым ни связывающим результатом, ни простым целевым объектом для имени компонента «ruleDeckForm», доступным в качестве атрибута запроса"errmsg, если

@ModelAttribute("ruleDeckForm")
public RuleDeckForm getRuleDeckForm() {
    return new RuleDeckForm();
}

отсутствует в BaseController.Но это то, что, кажется, обнуляет значения, поступающие от вызова ajax.Более любопытное поведение: при использовании @Valid сообщения журнала не появляются из RuleDeckFormValidator.validate, но кажется, что они выполняются без вывода сообщений, поскольку строка в методе контроллера сообщает об 1 обнаруженной ошибке, чего я и ожидал от объекта RuleDeckForm, и будет иметь все нулевые значения.Удаление @Valid и ручной вызов средства проверки действительно выполняется, но не находит ошибок, что позволяет выполнить обновление, что приводит к ошибке SQL из-за NOT NULL, помещенного в deckType в таблице базы данных.

Подробнее ...

public class RuleDeckForm
{
    private Long id; // might be null or empty if doing an insert

    @NotNull(message="deckType cannot be null")
    @NotBlank(message="deckType cannot be blank")
    @Size(min=1,max=10, message="deckType must be between 1 - 10 characters")
    private String deckType;

    // constructors, getters, setters, toString, etc ...
}


@Component(value="ruleDeckFormValidator")
public class RuleDeckFormValidator implements org.springframework.validation.Validator
{
    private static final Logger logger = LoggerFactory.getLogger( RuleDeckFormValidator.class );

    //constructor
    public RuleDeckFormValidator() {}

    @Override
    public boolean supports( Class<?> clazz) {
        return RuleDeckForm.class.isAssignableFrom(clazz);
    }

    @Override
    public void validate( Object obj, Errors errors) {
        logger.debug("entering RuleDeckFormValidator.validate");

        RuleDeckForm ruleDeckForm = (RuleDeckForm) obj;

        logger.debug("cast:" + ruleDeckForm.toString());

        if( errors.hasErrors()) {  // could be a data binding error, could be all sorts of things
            logger.debug( "number of errors found: " + errors.getErrorCount());
            ...
        } else {
            logger.debug("no validation errors found");
        }
        logger.debug("exiting  RuleDeckFormValidator.validate");
    }
}


@Controller
public class BaseController
{
    @Autowired
    MyService myService;

    @Autowired
    RuleDeckFormValidator ruleDeckFormValidator;

    @InitBinder( value="RuleDeckForm")
    protected void initBinder( WebDataBinder binder) {
        binder.setValidator( ruleDeckFormValidator);
    }

    @ModelAttribute("ruleDeckForm")
        public RuleDeckForm getRuleDeckForm() {
        return new RuleDeckForm();
    }

    ObjectMapper mapper = new ObjectMapper();  // JSON to/from object or list of objects, which itself an object

    @RequestMapping( value="/ruleDeck_insert_update", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody ResponseEntity<?> ruleDeckUpdateHander( @RequestBody @ModelAttribute("ruleDeckForm") @Valid RuleDeckForm ruleDeckForm , BindingResult result)
    {
        ResponseEntity<?> re = null;
        RuleDeck = null;

        // use @Valid OR this but not both
        //is.ruleDeckFormValidator.validate( ruleDeckForm, result);

        if( result.hasErrors()) {
            logger.debug( "number of errors found: ", result.getErrorCount());
            ...
            re = new ResponseEntity<Errors>( result, HttpStatus.BAD_REQUEST);
        } else {
            ruleDeck = updateExistingRuleDeck( ruleDeckForm);
            re = new ResponseEntity<RuleDeck>( ruleDeck, HttpStatus.OK);
        }
        return re;
    }
}

и, наконец, index.jsp

<%@ page language="java" contentType="text/html" pageEncoding="UTF-8" %>
<%@ taglib prefix="c"      uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn"     uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form"   uri="http://www.springframework.org/tags/form" %>
<html>
  <body>
    <div id="popupRuleDeck_update" class="popup displayNone">
      <div class="form-wrapper">
        <form:form id="form_popupRuleDeck_update" modelAttribute="ruleDeckForm" method="post">
          <fieldset>
            <legend>RuleDeck-update</legend>
            <label for="id">id</label>&nbsp;
            <form:input  id="update-id" path="id" type="number" readonly="readonly"/>&nbsp;&nbsp;
            <label for="deckType">deckType</label>&nbsp;
            <form:input id="update-deck-type" path="deckType" type="text" /><p>
            <form:errors path="deckType" class="help-online"/>
            ...
            <button  id="popupRuleDeck_update_submit">Submit</button>
          </fieldset>
        </form:form>
      </div>
    </div>
  </body>
</html>
<script>
  ...
  function popupRuleDeck_update_submit( event) {
      event.preventDefault();
      var formJsonObj = $('#form_popupRuleDeck_update').serializeObject();
      var formJsonStr = JSON.stringify( formJsonObj);
      $.ajax({
        url: '${pageContext.request.contextPath}/ruleDeck_insert_update',
        type: "post",
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        data: formJsonStr
      }).done( function( response, textStatus, jqXHR) {
        console.dir( "update succeeded textStatus:" + textStatus);
        ruleTable.row('.selected').data( response).invalidate().draw();
      }).fail( function( jqXHR, textStatus, errorThrown) {
        console.dir( "update failed textStatus:" + textStatus);
        console.dir( "update failed errorThrown:" + errorThrown );
        var errors = jqXHR.responseJSON;
        if( errors) {
              console.dir( "failed errors:" + jqXHR.responseJSON);
        }
     }).always( closeUpdatePopup);  
  }
  ...
</script>

Таким образом, общая задача заключается в том, чтобы проверка на стороне сервера работала для вставок, обновлений и удалений, а также сообщала об ошибках обратно во всплывающую форму.как во всех этих классных примерах.Есть идеи, как поступить? это , кажется, приводит к частичному ответу. здесь - почти такая же проблема, как у меня, но у меня действительно есть hibernate-validator в качестве зависимости в моем pom. this довольно хорошо объясняет три способа достижения валидации и почему я не могу получить желаемые результаты, но не объясняет, как вернуть ошибки обратно в форму в интерфейсе

Дополнительный вопрос: Iстал последним новообращенным jsfiddle.Но есть ли что-то подобное, что может моделировать вещи на стороне сервера?

TIA,

Все еще изучающий Стив

...