Validating queryparam values jersey - jaxb

Are there any other ways besides the one below to validate query parameter values i.e. is there a Jersey way to this by mapping to a schema via a wadl. Thank you
#Path("smooth")
#GET
public Response smooth(
#DefaultValue("blue") #QueryParam("min-color") ColorParam minColor,
public class ColorParam extends Color {
public ColorParam(String s) {
super(getRGB(s));
}
private static int getRGB(String s) {
if (s.charAt(0) == '#') {
try {
Color c = Color.decode("0x" + s.substring(1));
return c.getRGB();
} catch (NumberFormatException e) {
throw new WebApplicationException(400);

Unfortunately, there is limited support for validation on current JAX-RS version. But according to the draft for JAX-RS 2.0, it will have much better validation handling in the future.
You can see an example of the new features here.

Related

How can I add custom string preprocessing in JOOQ to sanitize strings?

I want to fix the errors, which sometimes happened in my app:
ERROR: invalid byte sequence for encoding "UTF8": 0x00; nested exception is org.postgresql.util.PSQLException: ERROR: invalid byte sequence for encoding "UTF8": 0x00
I think right way to solve it is to sanitize all text fields before insertion to database with
this.replace("\\u0000", "")
The question is how to implement the converter or custom binding in one place to force JOOQ invoke this replace function?
Using jOOQ's Converter or Binding
I'm assuming this is about JSON and PostgreSQL? See also: org.jooq.exception.DataAccessException: unsupported Unicode escape sequence \u0000
It seems that a Converter<JSON, JSON> (or JSONB, respectively) would suffice?
Converter.ofNullable(JSON.class, JSON.class,
j -> j,
j -> JSON.json(j.data().replace("\\u0000", ""))
);
And then, attach that everywhere using a forcedType:
<configuration xmlns="http://www.jooq.org/xsd/jooq-codegen-3.17.0.xsd">
<generator>
<database>
<forcedTypes>
<forcedType>
<userType>org.jooq.JSON</userType>
<converter>Converter.ofNullable(JSON.class, JSON.class,
j -> j,
j -> JSON.json(j.data().replace("\\u0000", ""))
)</converter>
<includeTypes>(?i:json)</includeTypes>
</forcedType>
</forcedTypes>
</database>
</generator>
</configuration>
Using JDBC
You could, of course, also just proxy JDBC and patch PreparedStatement::setString:
#Override
public void setString(int parameterIndex, String x) throws SQLException {
if (x == null)
delegate.setString(parameterIndex, x);
else
delegate.setString(parameterIndex, x.replace("\\u0000", "");
}
// Also all the other methods that might accept strings
A simple way to approach this is by using jOOQ's own JDBC proxy utility types, to avoid implementing the entire JDBC API:
org.jooq.tools.jdbc.DefaultConnection
org.jooq.tools.jdbc.DefaultPreparedStatement
This will handle things on a lower level, including when you don't use jOOQ. However, if you're using inline values, then those won't be converted by this approach, as those values are transparent to JDBC
So what I've did to solve the problem:
Added custom binding:
class PostgresStringsBinding : Binding<String, String> {
override fun converter(): Converter<String, String> {
return object : Converter<String, String> {
override fun from(dbString: String?): String? {
return dbString
}
override fun to(string: String?): String? {
return string?.withEscapedNullChars()
}
override fun fromType(): Class<String> {
return String::class.java
}
override fun toType(): Class<String> {
return String::class.java
}
}
}
#Throws(SQLException::class)
override fun sql(ctx: BindingSQLContext<String>) {
if (ctx.render().paramType() == ParamType.INLINED) ctx.render()
.visit(DSL.inline(ctx.convert(converter()).value())).sql("::text") else ctx.render().sql("?::text")
}
#Throws(SQLException::class)
override fun register(ctx: BindingRegisterContext<String>) {
ctx.statement().registerOutParameter(ctx.index(), Types.VARCHAR)
}
#Throws(SQLException::class)
override fun set(ctx: BindingSetStatementContext<String>) {
ctx.statement().setString(ctx.index(), Objects.toString(ctx.convert(converter()).value(), null))
}
#Throws(SQLException::class)
override fun get(ctx: BindingGetResultSetContext<String>) {
ctx.convert(converter()).value(ctx.resultSet().getString(ctx.index()))
}
#Throws(SQLException::class)
override fun get(ctx: BindingGetStatementContext<String>) {
ctx.convert(converter()).value(ctx.statement().getString(ctx.index()))
}
#Throws(SQLException::class)
override fun set(ctx: BindingSetSQLOutputContext<String>) {
throw SQLFeatureNotSupportedException()
}
#Throws(SQLException::class)
override fun get(ctx: BindingGetSQLInputContext<String>) {
throw SQLFeatureNotSupportedException()
}
}
and registered it as ForcedType:
ForcedType()
.withUserType("java.lang.String")
.withBinding("org.example.jooqbindings.PostgresStringsBinding")
.withIncludeExpression(".*")
.withIncludeTypes("VARCHAR|TEXT")

Dapper Extensions custom ClassMapper isn't called on Insert()

I'm using Dapper Extensions and have defined my own custom mapper to deal with entities with composite keys.
public class MyClassMapper<T> : ClassMapper<T> where T : class
{
public MyClassMapper()
{
// Manage unmappable attributes
IList<PropertyInfo> toIgnore = typeof(T).GetProperties().Where(x => !x.CanWrite).ToList();
foreach (PropertyInfo propertyInfo in toIgnore.ToList())
{
Map(propertyInfo).Ignore();
}
// Manage keys
IList<PropertyInfo> propsWithId = typeof(T).GetProperties().Where(x => x.Name.EndsWith("Id") || x.Name.EndsWith("ID")).ToList();
PropertyInfo primaryKey = propsWithId.FirstOrDefault(x => string.Equals(x.Name, $"{nameof(T)}Id", StringComparison.CurrentCultureIgnoreCase));
if (primaryKey != null && primaryKey.PropertyType == typeof(int))
{
Map(primaryKey).Key(KeyType.Identity);
}
else if (propsWithId.Any())
{
foreach (PropertyInfo prop in propsWithId)
{
Map(prop).Key(KeyType.Assigned);
}
}
AutoMap();
}
}
I also have this test case to test my mapper:
[Test]
public void TestMyAutoMapper()
{
DapperExtensions.DapperExtensions.DefaultMapper = typeof(MyClassMapper<>);
MySubscribtionEntityWithCompositeKey entity = new MySubscribtionEntityWithCompositeKey
{
SubscriptionID = 145,
CustomerPackageID = 32
};
using (var connection = new SqlConnection(CONNECTION_STRING))
{
connection.Open();
var result = connection.Insert(entity);
var key1 = result.SubscriptionID;
var key2 = result.CustomerPackageID;
}
}
Note that I set the default mapper in the test case.
The insert fails and I notive that my customer mapper is never called. I have no documentation on the github page on the topic, so I'm not sure if there's anything else I need to do to make dapper extensions use my mapper.
Thanks in advance!
Looking at your question, you are attempting to write your own defalut class mapper derived from the existing one. I never used this approach; so I do not know why it is not working or whether it should work.
I explicitly map the classes as below:
public class Customer
{
public int CustomerID { get; set; }
public string Name { get; set; }
}
public sealed class CustomerMapper : ClassMapper<Customer>
{
public CustomerMapper()
{
Schema("dbo");
Table("Customer");
Map(x => x.CustomerID).Key(KeyType.Identity);
AutoMap();
}
}
The AutoMap() will map rest of the properties based on conventions. Please refer to these two resources for more information about mapping.
Then I call SetMappingAssemblies at the startup of the project as below:
DapperExtensions.DapperExtensions.SetMappingAssemblies(new[] { Assembly.GetExecutingAssembly() });
The GetExecutingAssembly() is used in above code because mapping classes (CustomerMapper and other) are in same assembly which is executing. If those classes are placed in other assembly, provide that assembly instead.
And that's it, it works.
To set the dialect, I call following line just below the SetMappingAssemblies:
DapperExtensions.DapperExtensions.SqlDialect = new DapperExtensions.Sql.SqlServerDialect();
Use your preferred dialect instead of SqlServerDialect.
Apparently, the solution mentioned here may help you achieve what you are actually trying to. But, I cannot be sure, as I said above, I never used it.

Javafx PropertyValueFactory not populating Tableview

This has baffled me for a while now and I cannot seem to get the grasp of it. I'm using Cell Value Factory to populate a simple one column table and it does not populate in the table.
It does and I click the rows that are populated but I do not see any values in them- in this case String values. [I just edited this to make it clearer]
I have a different project under which it works under the same kind of data model. What am I doing wrong?
Here's the code. The commented code at the end seems to work though. I've checked to see if the usual mistakes- creating a new column instance or a new tableview instance, are there. Nothing. Please help!
//Simple Data Model
Stock.java
public class Stock {
private SimpleStringProperty stockTicker;
public Stock(String stockTicker) {
this.stockTicker = new SimpleStringProperty(stockTicker);
}
public String getstockTicker() {
return stockTicker.get();
}
public void setstockTicker(String stockticker) {
stockTicker.set(stockticker);
}
}
//Controller class
MainGuiController.java
private ObservableList<Stock> data;
#FXML
private TableView<Stock> stockTableView;// = new TableView<>(data);
#FXML
private TableColumn<Stock, String> tickerCol;
private void setTickersToCol() {
try {
Statement stmt = conn.createStatement();//conn is defined and works
ResultSet rsltset = stmt.executeQuery("SELECT ticker FROM tickerlist order by ticker");
data = FXCollections.observableArrayList();
Stock stockInstance;
while (rsltset.next()) {
stockInstance = new Stock(rsltset.getString(1).toUpperCase());
data.add(stockInstance);
}
} catch (SQLException ex) {
Logger.getLogger(WriteToFile.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Connection Failed! Check output console");
}
tickerCol.setCellValueFactory(new PropertyValueFactory<Stock,String>("stockTicker"));
stockTableView.setItems(data);
}
/*THIS, ON THE OTHER HAND, WORKS*/
/*Callback<CellDataFeatures<Stock, String>, ObservableValue<String>> cellDataFeat =
new Callback<CellDataFeatures<Stock, String>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(CellDataFeatures<Stock, String> p) {
return new SimpleStringProperty(p.getValue().getstockTicker());
}
};*/
Suggested solution (use a Lambda, not a PropertyValueFactory)
Instead of:
aColumn.setCellValueFactory(new PropertyValueFactory<Appointment,LocalDate>("date"));
Write:
aColumn.setCellValueFactory(cellData -> cellData.getValue().dateProperty());
For more information, see this answer:
Java: setCellValuefactory; Lambda vs. PropertyValueFactory; advantages/disadvantages
Solution using PropertyValueFactory
The lambda solution outlined above is preferred, but if you wish to use PropertyValueFactory, this alternate solution provides information on that.
How to Fix It
The case of your getter and setter methods are wrong.
getstockTicker should be getStockTicker
setstockTicker should be setStockTicker
Some Background Information
Your PropertyValueFactory remains the same with:
new PropertyValueFactory<Stock,String>("stockTicker")
The naming convention will seem more obvious when you also add a property accessor to your Stock class:
public class Stock {
private SimpleStringProperty stockTicker;
public Stock(String stockTicker) {
this.stockTicker = new SimpleStringProperty(stockTicker);
}
public String getStockTicker() {
return stockTicker.get();
}
public void setStockTicker(String stockticker) {
stockTicker.set(stockticker);
}
public StringProperty stockTickerProperty() {
return stockTicker;
}
}
The PropertyValueFactory uses reflection to find the relevant accessors (these should be public). First, it will try to use the stockTickerProperty accessor and, if that is not present fall back to getters and setters. Providing a property accessor is recommended as then you will automatically enable your table to observe the property in the underlying model, dynamically updating its data as the underlying model changes.
put the Getter and Setter method in you data class for all the elements.

Using one Validator for multiple request DTOs? or multiple Validators for a single request DTO?

I have several ServiceStack request DTOs that implement an interface called IPageable. I have a validator that can validate the two properties that are on this interface. I think I'm going to end up having one validator per request type, but I'm trying to avoid having to duplicate that IPageable-related validation logic in all of them.
public class PageableValidator : AbstractValidator<IPageable>
{
public PageableValidator()
{
RuleFor(req => req.Page)
.GreaterThanOrEqualTo(1);
RuleFor(req => req.PageSize)
.GreaterThanOrEqualTo(1)
.When(req => req.Page > 1);
}
}
Some ideas I've had about this include:
It appears I can't just have container.RegisterValidators() apply
this to all request types that implement IPageable, but that was my
first thought.
can I specify multiple <Validator> attributes on all the request
definitions, so that both a request-specific validator runs, as well
as my IPageable validator?
can I specify at validator registration time that for all types
implementing IPageable, my IPageable validator should run?
can I write a base class for my request-specific validators that
gets the rules from my PageableValidator and includes / runs them?
I can make something sort of work by subclassing AbstractValidator<T> where T : IPageable , but I'd like to be able to do validation on more than one interface in more of an aspect-oriented way.
I don't know the answers to your questions but a few options came to mind to after reading your question.
I am not familiar with the <Validator> attribute, but in regards to question 2, you could create a Filter attribute that would run your paging validation. This allows you to use many attributes on your request and set their priority.
public class PageableValidator : Attribute, IHasRequestFilter
{
public void RequestFilter(IHttpRequest req, IHttpResponse res, object requestDto)
{
if (requestDto is IPageable)
{
var validator = new PageableValidator(); //could use IOC for this
validator.ValidateAndThrow(requestDto as IPageable);
}
}
public IHasRequestFilter Copy()
{
return (IHasRequestFilter)this.MemberwiseClone();
}
public int Priority { get { return -1; //setting to negative value to run it before any other filters} }
}
Another option would be creating an abstract class for Paging validation. This would require a subclass for every Request and requires a bit more code and some repetition*. Though, depending on how you want to handle your error messages you could move the code around.
public abstract class PagerValidatorBase<T> : AbstractValidator<T>
{
public bool ValidatePage(IPageable instance, int page)
{
if (page >= 1)
return true;
return false;
}
public bool ValidatePageSize(IPageable instance, int pageSize)
{
if (pageSize >= 1 && instance.Page > 1)
return true;
return false;
}
}
public class SomeRequestValidator : PagerValidatorBase<SomeRequest>
{
public SomeRequestValidator()
{
//validation rules for SomeRequest
RuleFor(req => req.Page).Must(ValidatePage);
RuleFor(req => req.PageSize).Must(ValidatePageSize);
}
}
IMO, the repetition makes the code more explicit (not a bad thing) and is okay since it isn't duplicating the logic.

Add behavior to existing implementation - C# / Design Pattern

My current implementation for service and business layer is straight forward as below.
public class MyEntity { }
// Business layer
public interface IBusiness { IList<MyEntity> GetEntities(); }
public class MyBusinessOne : IBusiness
{
public IList<MyEntity> GetEntities()
{
return new List<MyEntity>();
}
}
//factory
public static class Factory
{
public static T Create<T>() where T : class
{
return new MyBusinessOne() as T; // returns instance based on T
}
}
//Service layer
public class MyService
{
public IList<MyEntity> GetEntities()
{
return Factory.Create<IBusiness>().GetEntities();
}
}
We needed some changes in current implementation. Reason being data grew over the time and service & client cannot handle the volume of data. we needed to implement pagination to the current service. We also expect some more features (like return fault when data is more that threshold, apply filters etc), so the design needs to be updated.
Following is my new proposal.
public interface IBusiness
{
IList<MyEntity> GetEntities();
}
public interface IBehavior
{
IEnumerable<T> Apply<T>(IEnumerable<T> data);
}
public abstract class MyBusiness
{
protected List<IBehavior> Behaviors = new List<IBehavior>();
public void AddBehavior(IBehavior behavior)
{
Behaviors.Add(behavior);
}
}
public class PaginationBehavior : IBehavior
{
public int PageSize = 10;
public int PageNumber = 2;
public IEnumerable<T> Apply<T>(IEnumerable<T> data)
{
//apply behavior here
return data
.Skip(PageNumber * PageSize)
.Take(PageSize);
}
}
public class MyEntity { }
public class MyBusinessOne : MyBusiness, IBusiness
{
public IList<MyEntity> GetEntities()
{
IEnumerable<MyEntity> result = new List<MyEntity>();
this.Behaviors.ForEach(rs =>
{
result = rs.Apply<MyEntity>(result);
});
return result.ToList();
}
}
public static class Factory
{
public static T Create<T>(List<IBehavior> behaviors) where T : class
{
// returns instance based on T
var instance = new MyBusinessOne();
behaviors.ForEach(rs => instance.AddBehavior(rs));
return instance as T;
}
}
public class MyService
{
public IList<MyEntity> GetEntities(int currentPage)
{
List<IBehavior> behaviors = new List<IBehavior>() {
new PaginationBehavior() { PageNumber = currentPage, }
};
return Factory.Create<IBusiness>(behaviors).GetEntities();
}
}
Experts please suggest me if my implementation is correct or I am over killing it. If it correct what design pattern it is - Decorator or Visitor.
Also my service returns JSON string. How can I use this behavior collections to serialize only selected properties rather than entire entity. List of properties comes from user as request. (Kind of column picker)
Looks like I don't have enough points to comment on your question. So, I am gonna make some assumption as I am not a C# expert.
Assumption 1: Looks like you are getting the data first and then applying the pagination using behavior object. If so, this is a wrong approach. Lets say there are 500 records and you are showing 50 records per fetch. Instead of simply fetching 50 records from DB, you are fetching 500 records for 10 times and on top of it you are adding a costly filter. DB is better equipped to do this job that C# or Java.
I would not consider pagination as a behavior with respect to the service. Its the behavior of the presentation layer. Your service should only worry about 'Data Granularity'. Looks like one of your customer wants all the data in one go and others might want a subset of that data.
Option 1: In DAO layer, have two methods: one for pagination and other for regular fetch. Based on the incoming params decide which method to call.
Option 2: Create two methods at service level. One for a small subset of data and the other for the whole set of data. Since you said JSON, this should be Restful service. Then based on the incoming URL, properly call the correct method. If you use Jersey, this should be easy.
In a service, new behaviors can be added by simply exposing new methods or adding new params to existing methods/functionalities (just make sure those changes are backward compatible). We really don't need Decorator or Visitor pattern. The only concern is no existing user should be affected.

Resources