当前位置: 首页 > 面试题库 >

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

艾弘义
2023-03-14
问题内容

在http请求主体中,密码字符串的传递方式为“ pass = 1111”,但是在bean中,密码的定义方式为“ private String
password”。是否可以使用批注来处理差异?必须始终匹配名称?

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;
    }
}

问题答案:

在@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);
    }

抽象控制

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。



 类似资料:
  • 问题内容: 我有一个疑问,因为@Entity和@Table中都存在name属性 例如,允许名称属性具有相同的值 我也可以在同一班上使用不同的名字 谁能告诉我这两者之间有什么区别,为什么我们两者都具有相同的属性? 问题答案: DB 因此,在第一种情况下,表和实体将具有相同的名称,这将允许您在编写HQL或JPQL时以与实体相同的名称访问表。 在第二种情况下,编写查询时,您必须使用 @Entity中提供

  • 问题内容: 我正在使用JSON.NET,我想从XML转换为JSON。 我正在使用JsonConvert.SerializeXNode(node),我注意到我的json对象具有在其名称前面带有@的属性: 因此,例如:如果我有: JSON对象是: 为什么在JSON中插入“ @”,有什么方法可以避免插入“ @”字符? 问题答案: 我认为这就是json.net关于@符号的工作方式。您始终可以在json字符

  • 问题内容: 我正在尝试反序列化JSON。我的根对象具有单个属性“ en.pickthall”。我正在使用动态类型读取JSON。我以为我可以取消“。” 在属性中,因为它是本地JSON文件,但是必须有某种方法可以访问此类属性 问题答案: C#没有任何引用标识符的方式。如果不是有效的标识符,则唯一的选择就是反射。 但是,您的JSON解串器返回的对象可能会更改了标识符,以使其在C#中可用- 您可能希望枚举

  • 问题内容: 我有一堂课,有以下领域。这些属性用于在需要调用外部rest API方法时序列化为json对象。 在属性名称中,外部API服务调用需要一些类似json归档名称格式的内容。 就我而言,这可以根据诸如test,dev和prod之类的环境进行更改。因此,我正在寻找一种将listId值移动到app.config中的方法。 我尝试按照以下方式进行操作,但不允许这样做。如果分配常数值,它将起作用。

  • 在Spring 3中,我在jsp的表单标签中看到了两种不同的属性 在这里,属性modelAttribute是表单对象的名称,其属性用于填充表单。我在发布表单时使用了它,在控制器中我使用了< code>@ModelAttribute来获取值,调用验证器,应用业务逻辑。这里一切都好。现在 这个属性所期望的是什么,它是否也是我们要填充其属性的表单对象?

  • 我正在尝试使用DynamoDB JavaScript shell创建一个简单的表,我得到了这个异常: 下面是我试图创建的表: 但是,如果我将第二个属性添加到KeySchema,它就可以正常工作。a工作台下方: 我不想将范围添加到密钥架构。知道怎么修吗?

  • 我将php中的Symfony与此捆绑包一起使用:https://github.com/hslavich/OneloginSamlBundle 使用onelogin php saml工具包:https://github.com/onelogin/php-saml 身份验证时我的IDP返回需要从oid映射到友好名称的属性 如果我在symfony bundles配置中使用oid名称,并且没有友好的名称,

  • 问题内容: 我有一个用swift编写的CustomViewController类和用Objective C编写的CustomNavigationController类。我试图将CustomNavigationController作为属性添加到我的CustomViewController中。我已经添加到我的桥接头中。 在我的CustomViewController中,我有: 在尝试构建并运行之前没有