在Spring-mvc中,视图中的属性名称必须始终与模型中的属性名称匹配?

时间:2010-12-07 18:27:39

标签: forms spring-mvc

在http请求体中,传递密码字符串的方式是“pass = 1111”,但是在bean中,定义密码的方式是“私有字符串密码”。有没有办法可以使用注释来处理差异还是我必须总是匹配名字?

Http请求就像这样

curl -H "Accept:text/html" -H "Content-Type application/x-www-form-urlencoded" -d 'email=test%40gmail.com&pass=1111&passconfirm=1111&name=x+y' "http://localhost:8080/project/register"

处理程序方法

@RequestMapping(method = RequestMethod.POST, headers = "content-type=application/x-www-form-urlencoded")
public String register(@ModelAttribute UserAccountBean account) ...

UserAccountBean是

public  class UserAccountBean2 {
    @NotNull
    @Size(min = 1, max = 25)
    private String name;

    @NotNull
    @Size(min = 4, max = 8)
    private String password;

    @NotNull
    private String email;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword()
    {
        return password;
    }

    public void setPassword(String password)
    {
        this.password = password;
    }

    public String toString() {
        return new ToStringCreator(this).append("name", name).append("password", password).toString();
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

3 个答案:

答案 0 :(得分:4)

你可以用这个来实现它:

@RequestMapping(method = RequestMethod.POST, headers = "content-type=application/x-www-form-urlencoded")
public String register(@ModelAttribute("userAccountBean") UserAccountBean account) ...

@ModelAttribute("userAccountBean")
public UserAccountBean getUserAccountBean(HttpServletRequest req) {
  UserAccountBean uab = new UserAccountBean();
  uab.setPassword(req.getParameter("pass"));
  return uab;
}

答案 1 :(得分:4)

在@InitBinder注释方法中使用@RequestParam注释,并手动设置所需的值。

<强> UserController中

    @InitBinder(value="user")
    public void bind(WebDataBinder dataBinder, WebRequest webRequest, @RequestParam(value="pass", required=false) String password) {
        User user = (User) dataBinder.getTarget();
        user.setPassword(password);
    }
  

有没有办法可以使用注释   处理差异或我必须   总是匹配名字?

AFAIK Spring MVC中没有现成的注释可以解决你的问题;你需要自定义设置来处理这种情况。

<强> WebModelAttribute

@Target({ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebModelAttribute {
String modelAttributeName();
    WebParameterMapping[] parameterMappings();
}

<强> WebParameterMapping

@Target({ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebParameterMapping {
    String webProperty();
    String beanProperty();
}

<强> UserController中

@Controller
public class UserController extends AbstractController {

    @Override
    @InitBinder(value="user")
    @WebModelAttribute(modelAttributeName="user", parameterMappings={@WebParameterMapping(webProperty="pass", beanProperty="password")})
    protected void bindWebParameters(WebDataBinder dataBinder, WebRequest webRequest, WebParameterResolver mappingResolver) {
        super.bindWebParameters(dataBinder, webRequest, mappingResolver);
    }

<强>一个AbstractController

public class AbstractController {

    protected void bindWebParameters(WebDataBinder dataBinder, WebRequest webRequest, WebParameterResolver mappingResolver) {
        if(mappingResolver != null && dataBinder.getTarget() != null && dataBinder.getObjectName().equals(mappingResolver.getModelAttributeName())) {
            String[] allowedFields = mappingResolver.getAllowedFields(dataBinder.getAllowedFields());
            String[] disallowedFields = mappingResolver.getDisallowedFields(dataBinder.getDisallowedFields());

            dataBinder.setAllowedFields(allowedFields);
            dataBinder.setDisallowedFields(disallowedFields);

            dataBinder.bind(mappingResolver.getPropertyValues(dataBinder, webRequest));
        }
    }

}

<强> WebParameterResolver

public class WebParameterResolver {

    private String modelAttributeName;
    private WebParameterMapping[] parameterMappings;

    public WebParameterResolver(String modelAttributeName,
            WebParameterMapping[] parameterMappings) {
        this.modelAttributeName = modelAttributeName;
        this.parameterMappings = parameterMappings;
    }

    public String getModelAttributeName() {
        return modelAttributeName;
    }

    public String[] getDisallowedFields(String[] existingDisallowedFields) {
        List<String> disallowedFields = new ArrayList<String>();
        for (WebParameterMapping parameterMapping : parameterMappings) {
            disallowedFields.add(parameterMapping.webProperty());
        }
        if (existingDisallowedFields != null) {
            for (String disallowedField : existingDisallowedFields) {
                disallowedFields.add(disallowedField);
            }
        }
        return disallowedFields.toArray(new String[disallowedFields.size()]);
    }

    public String[] getAllowedFields(String[] existingAllowedFields) {
        List<String> allowedFields = new ArrayList<String>();
        for (WebParameterMapping parameterMapping : parameterMappings) {
            allowedFields.add(parameterMapping.beanProperty());
        }
        if (existingAllowedFields != null) {
            for (String allowedField : existingAllowedFields) {
                allowedFields.add(allowedField);
            }
        }
        return allowedFields.toArray(new String[allowedFields.size()]);
    }

    public MutablePropertyValues getPropertyValues(WebDataBinder dataBinder,
            WebRequest webRequest) {
        MutablePropertyValues propertyValues = new MutablePropertyValues();
        for (WebParameterMapping parameterMapping : parameterMappings) {
            String[] values = webRequest.getParameterValues(parameterMapping.webProperty());
            if (values == null || values.length == 0) {
                // do nothing
            } else if (values.length == 1) {
                propertyValues.add(parameterMapping.beanProperty(), values[0]);
            } else {
                propertyValues.add(parameterMapping.beanProperty(), values);
            }
        }
        dataBinder.bind(propertyValues);
        return propertyValues;
    }

}

<强> CustomArgumentResolver

public class CustomArgumentResolver implements WebArgumentResolver {

    @Override
    public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) throws Exception {

        if(methodParameter.getParameterType().equals(WebParameterResolver.class)) {
            WebModelAttribute webModelAttribute = methodParameter.getMethod().getAnnotation(WebModelAttribute.class);
            if(webModelAttribute == null) {
                throw new RuntimeException("method must have WebModelAttribute");
            }
            return new WebParameterResolver(webModelAttribute.modelAttributeName(), webModelAttribute.parameterMappings());
        }

        return UNRESOLVED;
    }

}

<强>的beans.xml

    <bean id="handlerAdapter" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="customArgumentResolvers" ref="timetracking.annotations.CustomArgumentResolver"/>
    </bean>
<bean name="timetracking.annotations.CustomArgumentResolver"
        class="timetracking.annotations.CustomArgumentResolver" />

您还可以在某个帮助程序类中使用public static void bindWebParameters(...)方法;所以你不必每次都扩展AbstractController。

答案 2 :(得分:0)

3.0中没有基于注释的解决方案。

只需提供额外的getPass()setPass(String pass)方法即可设置。