Spring Validation – Validate list of integers

I have a DTO which has a field List<Integer> amountList . I want to validate that all the elements inside this list are greater than 0 and if not I want to throw a validation error that says which element has failed the validation i.e. “amountList[0] should be greater than 0”, “amountList[1] should be greater than 0”,etc.

I tried to implement the following validator for the above requirement, but I get an error

javax.validation.ValidationException: HV000033: At least one custom
message must be created if the default error message gets disabled.

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PeriodAmountValidationConstraint.PeriodAmountFieldsValidator.class)
public @interface PeriodAmountValidationConstraint {

    String message() default "Period Amount should be greater than 0";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    class PeriodAmountFieldsValidator implements ConstraintValidator<PeriodAmountValidationConstraint, List<Integer>> {

        @Override
        public void initialize(PeriodAmountValidationConstraint notEmptyFields) {
        }

        @Override
        public boolean isValid(List<Integer> periodAmountList, ConstraintValidatorContext context) {

            List<Integer> nonNullPeriodAmounts = periodAmountList.stream().filter(Objects::nonNull).collect(Collectors.toList());
            int index = 0;
            context.disableDefaultConstraintViolation();
            boolean validationfailed = false;
            for (Integer nonNullPeriodAmount : nonNullPeriodAmounts) {
                if (nonNullPeriodAmount <= 0) {
                    context.buildConstraintViolationWithTemplate("periodAmountList["+index+"] should be greater than 0")
                            .addConstraintViolation();
                    validationfailed = true;
                }
                index++;
            }
            return validationfailed;
        }
    }
}

I know that I disabled the Constraint Validation, but I added the context.buildConstraintViolationWithTemplate('....').addConstraintViolation(), which as per my understanding should add a custom error message. Obviously this is not working.

What am I doing wrong here ??

Grails 3.3.1 and reloading beans with properties defined in resources.groovy

I have a class in src/main/groovy (ApiService.groovy). I am defining this as a spring bean in resources.groovy as I have multiple implementations.

There is a single property for this bean:

apiService(ApiService) {
    server = '${server.address}'
}

Properties are defined in an external properties file.

All is fine when the application is first started.

However, if I change the file ApiService.groovy, the server property is null after ApiService gets reloaded.

I am using the following when starting the app with run-app:

-reloading -Ddisable.auto.recompile=false

I have also tried running Application.groovy, running the Gradle task bootRun and numerous other options for reloading but to no avail.

I have also tried using constructor based args instead, using resources.xml instead of resources.groovy but the same outcome.

Also, just for testing, I used the @Value annotation for the server property in the class itself and all was fine after a reload.

I’m running within Intellij but get the same behaviour running from the command line.

Maybe this shouldn’t actually work but any suggestions/advice would be greatly appreciated to save me spending any more time on it.

what happen when override spring repository method without implementing

Here is my spring repository interface

    interface TupleRepository extends JpaRepository<Tuple, Integer> {

    @Override
    @CacheEvict(cacheNames="tuples", allEntries=true)
    void delete(Tuple tuple);

}

As you see I overrided withoud giving any implementation.
the method is still working.

Which implem is being called.

I tried the debugging and investigation but ended up in the aop class managing the call.

does this method still call the jpaRepository implementation or what ?

Spring Boot returns Whitelabel Error Page instead of JSON

I need RESTful service to return JSON every time regardless if there is error or not. With normal cases everything goes ok, but when exceptions come I see Whitelabel Error Page.

I tried to resolve this in two ways.

Through @ExceptionHandler inside @Controller class inside the class annotated with @RestController:

@ExceptionHandler(MyCustomException.class)
@ResponseBody
public ErrorResponse handleException(Exception e) {
    return new ErrorResponse(5, "Error message");

}

And through special class with @ControllerAdvice annotation:

@ControllerAdvice
public class ExceptionController {

    @ExceptionHandler(MyCustomException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorResponse handleSecurityException(MyCustomException e) {
        return new ErrorResponse(5, "Error message");
    }

}

In both cases through breakpoints I see that those methods was called, but I still receive Whitelabel Error Page.

So what am I missing or doing wrong?

Session.saveOrUpdate increases id by two

I’ve created method to save entity with new id or update existing via hibernate session. When I use next code:

try {
        Session session = sessionWrapper.getSession();
        sessionWrapper.beginTransaction();
        if (user.getId()==null || session.get(User.class, user.getId())==null) {
            return (long) session.save(user);
        } else {
            session.get(User.class, user.getId());
            session.merge(user);
            return user.getId();
        }
    } finally {
        sessionWrapper.commit();
        sessionWrapper.closeSession();
    }

it works ok, but when I use session.saveOrUpdate instead in case of new entity generated id is increased by two, not one. Why and how to fix it?

Add custom HandlerMethodArgumentResolver without having to declare mvc dependency

In my project I’m using the @AuthenticationPrincipal annotation on a few methods of a @RestController. The only information I need tough, is the id field of the custom principal.

Currently this looks pretty ugly:

public void deleteUsers(@RequestParam(name = "id") List<Long> userIds, @AuthenticationPrincipal UserDetails userDetails) {
    if (userDetails != null && userIds.contains(((MyUser) userDetails).getId())) {
        throw new IllegalArgumentException("Cannot delete self");
    }
    userManager.deleteUsers(userIds);
}

That’s why I came up with the idea of a @AuthenticationId which gets resolved by a custom HandlerMethodArgumentResolver.

The thing is, that my project currently does not rely on the spring-mvc dependency. As I’ve seen, I would need to declare this dependency to register a custom HandlerMethodArgumentResolver myself: Inject your custom method argument in Spring MVC using HandlerMethodArgumentResolver

This seems a bit odd.

If the HandlerMethodArgumentResolver concept relies on spring-mvc, how can @AuthenticationPrincipal work if I do not include the dependency?

Spring @RestController with @RequestBody @Valid by default

Usually we write

@RestController
public class TestController {
    @RequestMapping(value = "/test")
    public String test2(@RequestBody @Valid TestClass req) {
        return "test2";
    }
}

But since it is a REST controller is it possible to configure Spring to use @RequestBody @Valid by default, so these annotations could be omitted?

How to create request with parameters with webflux Webclient?

At backend side i have REST controller with POST method:

@RequestMapping(value = "/save", method = RequestMethod.POST)
public Integer save(@RequestParam String name) {
   //do save
   return 0;
}

How can i create request using WebClient with request parameter?

WebClient.create(url).post()
    .uri("/save")
    //?
    .exchange()
    .block()
    .bodyToMono(Integer.class)
    .block();

Redirect automatically from http to https using EmbeddedServletContainerCustomizer

I have a below configuration class:

@Configuration
public class TomcatConfiguration implements EmbeddedServletContainerCustomizer {

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {

        TomcatEmbeddedServletContainerFactory factory = (TomcatEmbeddedServletContainerFactory) container;

        factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {

             @Override
             public void customize(Connector connector) {

                    connector.setPort(8443);
                    connector.setSecure(true);
                    connector.setScheme("https");
                    connector.setAttribute("sslProtocol", "TLS");
                    connector.setAttribute("SSLEnabled", true);

                    Http11NioProtocol proto = (Http11NioProtocol) connector.getProtocolHandler();
                    proto.setSSLEnabled(true);
                    proto.setKeystorePass("pass");
                    proto.setKeyAlias("alias");                        
                    proto.setKeystoreFile(new ClassPathResource("tomcat.keystore").getFile().getAbsolutePath());

            }
        });
    }
}

Now I would like to add automatically http => https functionality something like this:

@Bean
public EmbeddedServletContainerFactory servletContainer(){
    TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory(){
        @Override
        protected void postProcessContext(Context context) {
            SecurityConstraint securityConstraint = new SecurityConstraint();
            securityConstraint.setUserConstraint("CONFIDENTIAL");
            SecurityCollection collection = new SecurityCollection();
            collection.addPattern("/*");
            securityConstraint.addCollection(collection);
            context.addConstraint(securityConstraint);
        }
    };

    return tomcat;
}

How can I do it using ConfigurableEmbeddedServletContainer? Im using Spring boot 1.5.

Spring can not automatically inject dubbo service

Development tools: idea java

Use the framework: spring + springmvc + mybatis + dubbo

dubbo is a high-performance, java based, open source RPC framework.
When I use spring @autowired error, as shown in Figure 1.
But when I was in java annotations, it works fine, as shown in Figure II.
Figure 1
Figure 2

code1. the spring/applicationContext-service.xml for service.

code2. the spring/spring-mvc.xml for contoller.
code3. Service
code4. Controller (Here’s a problem, with @autowired can not be automatically injected)
Thanks!

The code:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">


    <context:component-scan base-package="xyz.maojun.service"/>
    <dubbo:application name="manager"/>
    <dubbo:registry protocol="zookeeper"
                    address="localhost:2181"/>
    <dubbo:protocol name="dubbo" port="20880"/>
    <dubbo:service interface="xyz.maojun.service.ItemService" ref="itemServiceImpl"  timeout="600000"/>

</beans>

More code:

<?xml version="1.0"encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.2.xsd
        http://code.alibabatech.com/schema/dubbo
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">
<context:component-scan base-package="xyz.maojun.controller"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix"value="/WEB-INF/jsp/"/>
<property name="suffix"value=".jsp"/>
</bean>
<mvc:resources mapping="/css/**"location="css/"/>
<mvc:resources mapping="/js/**"location="js/"/>
<dubbo:application name="manager-web"/>
<dubbo:registry protocol="zookeeper"address="localhost:2181"/>
<dubbo:reference interface="xyz.maojun.service.ItemService"id="itemService"/>
</beans>

ItemService code:

package xyz.maojun.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import xyz.maojun.common.pojo.EasyUIDateGridResult;
import xyz.maojun.mapper.TbItemMapper;
import xyz.maojun.pojo.TbItem;
import xyz.maojun.pojo.TbItemExample;
import xyz.maojun.service.ItemService;

import javax.annotation.Resource;
import java.util.List;

@Service
public class ItemServiceImpl implements ItemService {
    @Autowired
    private TbItemMapper tbItemMapper;

    @Override
    public TbItem getItemById(long itemid) {

        TbItemExample example = new TbItemExample();
        TbItemExample.Criteria criteria = example.createCriteria();

        criteria.andIdEqualTo(itemid);

        List<TbItem> list = tbItemMapper.selectByExample(example);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }
}

The controller:

  package xyz.maojun.controller;
 import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import xyz.maojun.pojo.*;
    import xyz.maojun.service.ItemService;
    import javax.annotation.Resource;
    @Controller
    public class ItemController {
        @Resource  // i want to use @autowired ,but it not work
        private ItemService itemService;
        @RequestMapping("/item/{itemId}")
        @ResponseBody
        public TbItem getItemById(@PathVariable long itemId) {
            TbItem tbItem = itemService.getItemById(itemId);
            return tbItem;
        }
    }