I have to check some textField with the following regex:
[\sa-zA-Z.'-àáâãäåçèéêëìíîïðòóôõöùúûüýÿ]+
It works with regex checkers but it doesn't work with my GWT/GXT application. I use the function above in a class that extends AbstractValidator.
public static native boolean isValidName(String name) /*-{
var pattern = /[\sa-zA-Z.\'-àáâãäåçèéêëìíîïðòóôõöùúûüýÿ]+/;
return pattern.test(name);
}-*/;
I use GXT2 and GWT 1.6.4.
have you tried using String.macthes for validate the value and Validator class in gxt TextField?
someTextField.setValidator(new Validator() {
#Override
public String validate(Field<?> field, String value) {
return value.matches("[\\sa-zA-Z.'-àáâãäåçèéêëìíîïðòóôõöùúûüýÿ]+")
? null : "not a valid value";
}
});
Why go native, while you can still use Java ? Or even better, try to see if GXT gives you some validation tools. Like Validators
Related : Regular Expressions and GWT
OK for gxt2...
the corresponding method is setRegex(String regex) which will get called if all other validators have passed
http://www.jarvana.com/jarvana/view/com/extjs/gxt/2.2.0/gxt-2.2.0-javadoc.jar!/com/extjs/gxt/ui/client/widget/form/TextField.html
Why don't you use (for gxt3):
com.sencha.gxt.widget.core.client.form.Field<T>.addValidator(Validator<T> validator)
field.addValidator(new RegExValidator( "[\sa-zA-Z.\'-àáâãäåçèéêëìíîïðòóôõöùúûüýÿ]", "some message"));
see gxt field api
see gxt RegExValidator
Sencha GXT4:
enum VType
public enum VType {
ALPHABET("^[a-zA-Z_]+$", "Alphabet"), ALPHANUMERIC("^[a-zA-Z0-9_]+$",
"Alphanumeric"), NUMERIC("^[+0-9]+$", "Numeric"), EMAIL("^(\\w+)([-+.][\\w]+)*#(\\w[-\\w]*\\.){1,5}([A-Za-z]){2,4}$","Email");
String regex;
String name;
VType(String regex, String name) {
this.regex = regex;
this.name = name;
}
}
Validator class
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.editor.client.Editor;
import com.google.gwt.editor.client.EditorError;
import com.sencha.gxt.widget.core.client.form.Validator;
import com.sencha.gxt.widget.core.client.form.error.DefaultEditorError;
public class VTypeValidator implements Validator<String> {
private String message;
private final VType type;
public VTypeValidator(VType type,String message){
this.type = type;
this.message=message;
}
#Override
public List<EditorError> validate(Editor<String> editor, String value) {
List<EditorError> res = null;
if (!value.matches(type.regex)) {
List<EditorError> errors = new ArrayList<EditorError>();
errors.add(new DefaultEditorError(editor, message,""));
return errors;
}
return res;
}
}
How to use with textField
field.addValidator(new VTypeValidator(VType.EMAIL,"Invalid email"));
Related
I am trying to implement custom validation in spring boot but there is some issue with the code even if I am passing wrong phone number the phone number should be 10 digit but I am passing a string and still I get status as OK can anyone tell me what is wrong with my code
#Data
public class StudentData {
#Phone
String phone;
}
#RestController
public class HomeController {
#PostMapping("/showData")
public String display(#Valid #RequestBody StudentData studentData){
return "OK";
}
}
#Documented
#Constraint(validatedBy = PhoneValidation.class)
#Target( { ElementType.METHOD, ElementType.FIELD })
#Retention(RetentionPolicy.RUNTIME)
public #interface Phone {
String message() default "{Wrong phone}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class PhoneValidation implements ConstraintValidator<Phone, String> {
#Override
public void initialize(Phone phone) { }
#Override
public boolean isValid(String phoneField, ConstraintValidatorContext constraintValidatorContext) {
if(phoneField == null) {
return false;
}
if(phoneField.matches("^[0-9]*$"))
return true;
return false;
}
}
Payload I am passing
http://localhost:8080/showData
{
"phone":"abc"
}
Try adding #Validated to your controller.
If that does not work, I would also confirm that validation code is being hit. Running your API in debug mode with a breakpoint in the isValid method can confirm if this is a problem in the validation logic, the Bean validator injection or your test setup (is it a test scenario?).
First, you don't need to use #Validated over #RestController, servlet container will validate it for you on data input annotated with #Valid
Second, your regex validates all strings consisting of digits, in spite of their length, so "1" or "22222222222222222" is a valid Phone
And last but not least - your code is working as desired :)
I would like to iterate through a list, get the object's name and match that name with the record in my database. Then fetch that record.
I tried to use the foreach tag in Mybatis but I only get an empty list in return. Please help me out and point out if I have made any mistakes.
For reference, I have attached my Service implementation, DAO, mapper & the list class I'm using.
Service implementation
String jsonStr = "[{\"name\":\"first \",\"value\":\"1 \"},{\"name\":\"second\",\"value\":\"2\"},{\"name\":\"third\",\"value\":\"3\"},{\"name\":\"fourth\",\"value\":\"4\"}]";
List<PaymentCommon.CampaignsRsp> list = null;
try { // creating a list from the json String
list = mapper.readValue(jsonStr, new TypeReference<List<PaymentCommon.CampaignsRsp>>(){});
} catch (IOException e) {
e.printStackTrace();
}
if(JudgeUtils.isNotEmpty(rsp.getCampaigns())) {
listRsp = cmmClmWhitelistingDao.getCampaigns(list); // calling the method
}
else System.out.println("LIST IS EMPTY");
DAO
package com.hisun.lemon.cmm.dao;
import com.hisun.lemon.cio.dto.common.PaymentCommon;
import com.hisun.lemon.cmm.entity.CmmClmCampaignDO;
import com.hisun.lemon.framework.dao.BaseDao;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
#Mapper
public interface ICmmClmWhitelistingDao extends BaseDao {
List<CmmClmCampaignDO> getCampaigns(List<PaymentCommon.CampaignsRsp> campaignList);
}
Mapper
<select id="getCampaigns" resultMap="BaseResultMap" >
SELECT campaign.campaign_id, campaign.campaign_name,
FROM clm_campaign campaign
WHERE campaign.campaign_name IN
<foreach item="id" collection="list" open="[{" separator="},{" close="}]" >
#{id.name}
</foreach>
</select>
PaymentCommon.class
#Json
public static class CampaignsRsp {
#Item
private String name;
#Item
private String value;
public CampaignsRsp() {
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return this.value;
}
public void setValue(String value) {
this.value = value;
}
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
I found a solution.
I am now getting the names from the List<PaymentCommon.CampaignsRSp> and making a simple List of those names. Then, I'm passing that list to the mapper, making it simple to iterate the list.
Plus, I was missing the #Param annotation in my DAO, so I added that.
This approach gets me the data I want from my DB.
I am trying to use conventions in my unit tests which make use of AutoFixture. I have a Password value object as shown:
public class Password : SemanticType<string>
{
private int _daysPasswordValid;
public Password(string password) : base(IsValid, password)
{
Guard.NotNullOrEmpty(() => password, password);
Guard.IsValid(() => password, password, IsValid, "Invalid Password");
DateCreated = DateTime.Now;
}
static bool IsValid(string candidate)
{
//password cannot contain be whitespace
if (string.IsNullOrWhiteSpace(candidate))
return false;
const string passwordPattern = #"^(?=.*[A-Z].*[A-Z])(?=.*[!##$&=()-*])(?=.*[0-9].*[0-9])(?=.*[a-z].*[a-z].*[a-z]).{20}$";
var match = Regex.Match(candidate, passwordPattern);
return match.Success;
}
public DateTime DateCreated { get; private set; }
public int DaysPasswordValid
{
get { return _daysPasswordValid; }
set
{
const int minimunDays = 0;
const int maximumDays = 90;
if (value <= maximumDays && value > minimunDays)
_daysPasswordValid = value;
else
throw new ArgumentOutOfRangeException(
"Password must be valid more than {0} and no more than {1} days.".Fmt(minimunDays, maximumDays));
}
}
public static implicit operator string(Password password)
{
return password.Value;
}
public static explicit operator Password(string value)
{
return new Password(value);
}
}
I would like to be able to create a fixture based on the Password class and have the fixture created with a valid password, in other words, a password that matches the RegEx pattern in the Password class. I have been looking at the RegularExpressionGenerator available in AutoFixture but haven't quite gotten things to work. Here is the builder have so far:
public class ValidPasswordBuilder : ISpecimenBuilder
{
public ValidPasswordBuilder(string regularExpressionRequest)
{
PasswordRegularExpression = regularExpressionRequest;
}
public string PasswordRegularExpression { get; private set; }
public object Create(object request, ISpecimenContext context)
{
var pi = request as ParameterInfo;
if (pi != null && pi.Name == "password" && pi.ParameterType == typeof(string))
{
var generator = new RegularExpressionGenerator();
var regExRequest = new RegularExpressionRequest(PasswordRegularExpression);
var result = generator.Create(regExRequest, context);
return result.ToString();
}
return new NoSpecimen(request);
}
}
Here is the test:
[Fact]
public void ValidPasswordMatches()
{
var fixture = new Fixture();
fixture.Customizations.Add(new ValidPasswordBuilder(PasswordPattern));
Action a = () => fixture.Create<Password>();
a.ShouldNotThrow<ArgumentException>();
}
I can run the test as setup above, and it passes, but if I debug it, I get an error in the IsValid function in the Password class (through the Guard clause) that says that the password returned from the builder is:
Ploeh.AutoFixture.Kernel.NoSpecimen
I never seem to get a result that matches the RegEx pattern. I feel like I'm close, but need some help getting over the hump.
Thanks!
As it looks like, the pattern you use is not supported:
^(?=.*[A-Z].*[A-Z])(?=.*[!##$&=()-*])(?=.*[0-9].*[0-9])(?=.*[a-z].*[a-z].*[a-z]).{20}$
Try with a different Regular Expression.
Edit: Or try doing this or this, in order to configure AutoFixture to use a different Regular Expression, without changing the Password class.
AutoFixture turns Regular Expressions into Automatons by applying the algorithms of dk.brics.automaton.
You may use a different pattern or use a different engine to reverse the Regular Expression into an Automaton. As an example, you can use the Rex engine.
Though, even with Rex your Regular Expression is not supported, as the following constructs are currently not supported by Rex:
anchors \G, \b, \B, named groups, lookahead, lookbehind, as-few-times-as-possible quantifiers, backreferences, conditional alternation, substitution.
If you want to try Rex with AutoFixture you can use the following generator:
internal class RexRegularExpressionGenerator : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (request == null)
return new NoSpecimen();
var regularExpressionRequest = request as RegularExpressionRequest;
if (regularExpressionRequest == null)
return new NoSpecimen();
var pattern = regularExpressionRequest.Pattern;
try
{
var regex = RexEngine
.GenerateMembers(
new RexSettings(pattern) { k = 1 })
.FirstOrDefault();
if (Regex.IsMatch(regex, pattern))
return regex;
}
catch (ArgumentException)
{
return new NoSpecimen(request);
}
return new NoSpecimen(request);
}
}
As far as I can tell, you can download Rex only as a .NET application (.exe) file which you can then reference like any other managed assembly in your project.
In my class, I have a property for a file attachment like so...
public class Certificate {
[Required]
// TODO: Wow looks like there's a problem with using regex in MVC 4, this does not work!
[RegularExpression(#"^.*\.(xlsx|xls|XLSX|XLS)$", ErrorMessage = "Only Excel files (*.xls, *.xlsx) files are accepted")]
public string AttachmentTrace { get; set; }
}
I don't see anything wrong with my regex, but I always get ModelState.IsValid false. This seems pretty trivial and simple regex, am I missing something? Do I need to write my own custom validation?
I'm populating AttachmentTrace via a regular input of type file:
<div class="editor-label">
#Html.LabelFor(model => model.AttachmentTrace)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.AttachmentTrace, new { type = "file" })
#Html.ValidationMessageFor(model => model.AttachmentTrace)
</div>
The action method is just a regular action:
public ActionResult Create(Certificate certificate, HttpPostedFileBase attachmentTrace, HttpPostedFileBase attachmentEmail)
{
if (ModelState.IsValid)
{
// code ...
}
return View(certificate);
}
Ok, here's the solution I found. I'm sure there are other solutions out there. First a little background, because my application uses EF code-first migration, specifying a HttpPostedFileBase property type in my model, produces this error when adding migration:
One or more validation errors were detected during model generation:
System.Data.Entity.Edm.EdmEntityType: : EntityType
'HttpPostedFileBase' has no key defined. Define the key for this
EntityType. \tSystem.Data.Entity.Edm.EdmEntitySet: EntityType:
EntitySet 'HttpPostedFileBases' is based on type 'HttpPostedFileBase'
that has no keys defined.
So I really had to stick with using a string type for the AttachmentTrace property.
The solution is to employ a ViewModel class like this:
public class CertificateViewModel {
// .. other properties
[Required]
[FileTypes("xls,xlsx")]
public HttpPostedFileBase AttachmentTrace { get; set; }
}
Then create a FileTypesAttribute like so, I borrowed this code from this excellent post.
public class FileTypesAttribute : ValidationAttribute {
private readonly List<string> _types;
public FileTypesAttribute(string types) {
_types = types.Split(',').ToList();
}
public override bool IsValid(object value) {
if (value == null) return true;
var postedFile = value as HttpPostedFileBase;
var fileExt = System.IO.Path.GetExtension(postedFile.FileName).Substring(1);
return _types.Contains(fileExt, StringComparer.OrdinalIgnoreCase);
}
public override string FormatErrorMessage(string name) {
return string.Format("Invalid file type. Only {0} are supported.", String.Join(", ", _types));
}
}
In the controller Action, I needed to make a change to use the ViewModel instead, then map it back to my Entity using AutoMapper (which is excellent by the way):
public ActionResult Create(CertificateViewModel certificate, HttpPostedFileBase attachmentTrace, HttpPostedFileBase attachmentEmail) {
if (ModelState.IsValid) {
// Let's use AutoMapper to map the ViewModel back to our Certificate Entity
// We also need to create a converter for type HttpPostedFileBase -> string
Mapper.CreateMap<HttpPostedFileBase, string>().ConvertUsing(new HttpPostedFileBaseTypeConverter());
Mapper.CreateMap<CreateCertificateViewModel, Certificate>();
Certificate myCert = Mapper.Map<CreateCertificateViewModel, Certificate>(certificate);
// other code ...
}
return View(myCert);
}
For the AutoMapper, I created my own TypeConverter for the HttpPostedFileBase as follows:
public class HttpPostedFileBaseTypeConverter : ITypeConverter<HttpPostedFileBase, string> {
public string Convert(ResolutionContext context) {
var fileBase = context.SourceValue as HttpPostedFileBase;
if (fileBase != null) {
return fileBase.FileName;
}
return null;
}
}
That's it. Hope this helps out others who may have this same issue.
I am using MVC 3 with Razor. I can't figure out how to code a string extension regex to take this:
This_is_some_text
to display:
This is some text
I set up some enums for a drop down list, so they appear thusly (obviously I can't create an enum with a space):
public enum MyProperty
{
This_is_some_text,
This_is_some_other_text
}
I just cannot figure out the regex is to do what I want if I am doing this:
public static string EnumToDisplay(this string str)
{
return Regex.Replace(str, "[What is the regex I should use?]");
}
As a bonus for me I would also like to add a period "." to the end of the enum. The reason for this is that I have OCD and my enums are taking the form of short sentences. :)
Thanks!
Why not use String.Replace() for this? RegEx seems a bit overkill.
public static string EnumToDisplay(this string str)
{
return str.Replace('_', ' ') + ".";
}
Why do you want to use regular expressions? A very wise man once said, I quote:
Some people, when confronted with a problem, think "I know, I'll use
regular expressions." Now they have two problems.
How about using the [Display] attribute which is kinda designed exactly for this purpose:
public enum MyProperty
{
[Display(Name = "This is some super text")]
This_is_some_text,
[Display(Name = "And this is some other text")]
This_is_some_other_text
}
and then writing a custom Html helper:
public static class HtmlExtensions
{
public static IHtmlString DisplayForEnum<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
if (!typeof(TProperty).IsEnum)
{
throw new ArgumentException("sorry this helper is inteded to be used with enum types");
}
var model = htmlHelper.ViewData.Model;
if (htmlHelper.ViewData.Model == null)
{
return MvcHtmlString.Empty;
}
var field = typeof(TProperty).GetField(expression.Compile()(htmlHelper.ViewData.Model).ToString());
if (field == null)
{
return new HtmlString(htmlHelper.Encode(htmlHelper.ViewData.Model.ToString()));
}
var display = field.GetCustomAttributes(typeof(DisplayAttribute), true).FirstOrDefault() as DisplayAttribute;
if (display == null)
{
return new HtmlString(htmlHelper.Encode(htmlHelper.ViewData.Model.ToString()));
}
return new HtmlString(htmlHelper.Encode(display.Name));
}
}
So now assuming you have a view model:
public class MyViewModel
{
public MyProperty Foo { get; set; }
}
and a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
Foo = MyProperty.This_is_some_other_text
};
return View(model);
}
}
you could use the custom helper we just wrote in the view to display a user friendly text that we might have associated to an ugly enum. Hey, now you could even have this working with globalization and multiple languages using resources:
#model MyViewModel
#Html.DisplayForEnum(x => x.Foo)
I do not know about asp.net - but there should be a really simple method that replaces one character with another char. Like:
String.replace( myString, '_',' ' );
You can use the replacement pattern which is also called substitution.
You can find graet info here:
http://msdn.microsoft.com/en-us/library/ewy2t5e0.aspx
Good luck