Spring forward is not working in android api - spring-mvc

I have been search on google but I can not find the solution so please tell me why spring forward is not working in android api but working in web api so how to fix it?
#Controller
#RequestMapping(value = "/")
public class LoginController {
#RequestMapping(method = {RequestMethod.GET,RequestMethod.POST,RequestMethod.HEAD})
public ModelAndView home(#ModelAttribute LoginInfo user, Model model,
HttpServletRequest request, HttpServletResponse response)throws Exception {
System.out.println("LoginController.user.userName: "+userName);
return new ModelAndView("forward:admin.html");
}
#RequestMapping(value = "/admin", method={RequestMethod.GET, RequestMethod.POST})
public ModelAndView successAdmin(#ModelAttribute LoginInfo user, Model model,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
System.out.println("admin.userName: "+userName);
return null;
}
}
I also use return new ModelAndView("forward:/admin.html"); but not forward the request to /admin handler method.

Try to use
return new ModelAndView("admin.html");
in your home method
or change the home function to
public String home() {
return "forward:/admin";
}}

Related

Class level request mapping #requestmapping execute some code on every request to that class

#Controller
#RequestMapping(value = {"user"})
public class UserController {
...
#RequestMapping(value = {"dashboard"})
public String index(HttpServletRequest req, ModelMap map) {
this.objSession = req.getSession(false);
try {
System.out.println(this.objSession.getAttribute("userid"));
I am using Spring 4.2.
Suppose I have this class and I want to check the session object having the attribute userid=1 or not.
I am doing this checking in every methods under this "/user" request.
My query is that if I can avoid this same coding which i am doing before executing any codes of any methods.
Is there any way round to increase code resuability for checking ?
In advance thanks for your time.
You can make use of interceptors by matching the request path.
<mvc:interceptors path-matcher="/someRequest/*">
<bean class="className" autowire="constructor"/>
</mvc:interceptors>
In path-mathcer you can specify one type of url,so that it will execute whatever you require.
Controller:
#Controller
#RequestMapping(value = {"someRequest/user"})
public class UserController {
Interceptor: Before processing someRequest/user you can use a interceptor like below, in 3 ways you can use->afterCompletion ,preHandle,postHandle.
In you case code would be written in preHandle method
public class SomeRequestIntercept implements HandlerInterceptor {
#Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object,
Exception exception) throws Exception {
}
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object arg2, ModelAndView arg3)
throws Exception {
}
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
System.out.println("before processing someRequest/**");
return true;
}
}

advise controller method *before* #Valid annotation is handled

I am adding rate-limiting to a restful webservice using Spring MVC 4.1.
I created a #RateLimited annotation that I can apply to controller methods. A Spring AOP aspect intercepts calls to these methods and throws an exception if there have been too many requests:
#Aspect
#Component
#Order(Ordered.HIGHEST_PRECEDENCE)
public class RateLimitingAspect {
#Autowired
private RateLimitService rateLimitService;
#Before("execution(* com.example..*.*(.., javax.servlet.ServletRequest+, ..)) " +
"&& #annotation(com.example.RateLimited)")
public void wait(JoinPoint jp) throws Throwable {
ServletRequest request =
Arrays
.stream(jp.getArgs())
.filter(Objects::nonNull)
.filter(arg -> ServletRequest.class.isAssignableFrom(arg.getClass()))
.map(ServletRequest.class::cast)
.findFirst()
.get();
String ip = request.getRemoteAddr();
int secondsToWait = rateLimitService.secondsUntilNextAllowedAttempt(ip);
if (secondsToWait > 0) {
throw new TooManyRequestsException(secondsToWait);
}
}
This all works perfectly, except when the #RateLimited controller method has parameters marked as #Valid, e.g.:
#RateLimited
#RequestMapping(method = RequestMethod.POST)
public HttpEntity<?> createAccount(
HttpServletRequest request,
#Valid #RequestBody CreateAccountRequestDto dto) {
...
}
The problem: if validation fails, the validator throws MethodArgumentNotValidException, which is handled by an #ExceptionHandler, which returns an error response to the client, never triggering my #Before and therefore bypassing the rate-limiting.
How can I intercept a web request like this in a way that takes precedence over parameter validation?
I've thought of using Spring Interceptors or plain servlet Filters, but they are mapped by simple url-patterns and I need to differentiate by GET/POST/PUT/etc.
I eventually gave up on trying to find an AOP solution and created a Spring Interceptor instead. The interceptor preHandles all requests and watches for requests whose handler is #RateLimited.
#Component
public class RateLimitingInterceptor extends HandlerInterceptorAdapter {
#Autowired
private final RateLimitService rateLimitService;
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (HandlerMethod.class.isAssignableFrom(handler.getClass())) {
rateLimit(request, (HandlerMethod)handler);
}
return super.preHandle(request, response, handler);
}
private void rateLimit(HttpServletRequest request, HandlerMethod handlerMethod) throws TooManyRequestsException {
if (handlerMethod.getMethodAnnotation(RateLimited.class) != null) {
String ip = request.getRemoteAddr();
int secondsToWait = rateLimitService.secondsUntilNextAllowedInvocation(ip);
if (secondsToWait > 0) {
throw new TooManyRequestsException(secondsToWait);
} else {
rateLimitService.recordInvocation(ip);
}
}
}
}
Add the following controller advice in your application.
#ControllerAdvice
public class ApplicationControllerAdvice {
#InitBinder
#RateLimited
protected void activateBeanPropertyAccess(DataBinder dataBinder) {
dataBinder.initBeanPropertyAccess();
}
}
The #RateLimited should call the class RateLimitingAspect. So, after this all the constraints validator will be called.
See if it's feasible for you to implement similar logic for ##AfterThrowing advice as well which will have similar pointcut.

how can i access controller method value in postHandle in spring mvc 's interceptor

#Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
#Controller
public ModeAndView createUser(User user){
}
how can get controller method createUser's parameter user value
in interceptor 's postHandle ???
You cannot directly.
As you see in its parameters, an Interceptor has direct access to the request, the response and the ModelAndView. If you need to have access to the method parameter user, the simplest is to put it in model.
public ModeAndView createUser(User user){
ModelAndView mav = new ModelAndView();
mav.addAttribute("user", user);
...
return mav;
}
Then in interceptor postHandle method, you simply do
User user = (User) modelAndView.getAttribute("user");
You could write an org.springframework.web.servlet.HandlerInterceptor. (or its convenience subclass HandlerInterceptorAdapter)
#See: Spring Reference chapter: 15.4.1 Intercepting requests - the HandlerInterceptor interface
It has the method:
void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception;
This method is invoked after the controller is done and before the view is rendered. So you can use it, to add some properties to the ModelMap
An example:
public class VersionAddingHandlerInterceptor extends HandlerInterceptorAdapter {
/**
* The name under which the version is added to the model map.
*/
public static final String VERSION_MODEL_ATTRIBUTE_NAME =
"VersionAddingHandlerInterceptor_version";
/**
* it is my personal implmentation
* I wanted to demonstrate something usefull
*/
private VersionService versionService;
public VersionAddingHandlerInterceptor(final VersionService versionService) {
this.versionService = versionService;
}
#Override
public void postHandle(final HttpServletRequest request,
final HttpServletResponse response, final Object handler,
final ModelAndView modelAndView) throws Exception {
if (modelAndView != null) {
modelAndView.getModelMap().
addAttribute(VERSION_MODEL_ATTRIBUTE_NAME,
versionService.getVersion());
}
}
}
webmvc-config.xml
<mvc:interceptors>
<bean class="demo.VersionAddingHandlerInterceptor" autowire="constructor" />
</mvc:interceptors>

How should I add attribute after redirect to a controller

I am just a newbie about Spring.
I am now using #ExceptionHandler to handle all the exception for my web application. And after I catch the exception, it will go to and error.jsp page displaying the error message.
I have a ParentController and in that, I have:
#org.springframework.web.bind.annotation.ExceptionHandler(PortalException.class)
public ModelAndView handle(PortalException e, HttpServletRequest request) {
ModelMap map = new ModelMap();
map.addAttribute("message", e.getMessage());
return new ModelAndView("/error", map);
}
and I have a ErrorControllerextends the ParentController to add the attributes:
#Controller
public class ErrorController extends ParentSecureController {
#RequestMapping(value = "/error", method = RequestMethod.POST)
#ResponseBody
public String errorHandler(Model model, HttpServletRequest request) {
model.addAttribute("excetpion.message", request.getParameter("message"));
return "/error";
}
}
In the error.jsp:
<p>Excpetion is: ${exception.message}</p>
When I run my application, I can catch the exception and jump to error.jsp, but no exception message is display.
Anyone can help me to figure out how to solve it.
Please try use:
#Controller
public class ErrorController extends ParentSecureController {
#RequestMapping(value = "/error", method = RequestMethod.POST)
#ResponseBody
public String errorHandler(Map<String, Object> map, HttpServletRequest request) {
map.put("excetpion.message", request.getParameter("message"));
return "/error";
}
}
UPDATE
Map you get it messae from #Controller to View in this case error.jsp
I hope these helped! :)

Return value of Controller should be ignored

For test reasons I'd like to have a method signature in a spring-mvc-controller with a return value which should be ignored by spring:
#RequestMapping(value = "/{uuid}", params = "question", method = RequestMethod.POST)
#ResponseBody
public IAnswer saveAnswer(UiAnswer json, #PathVariable String uuid, #RequestParam("question") String question, HttpServletResponse response) {}
It's a post-request where the controller receives data and just responses with response.setStatus(HttpServletResponse.SC_OK); if everything went fine.
With #ResponseBody it dies in a internal server error 500
Without #ResponseBody spring tries to resolve the view
With void as the return value, it works fine
Can I tell spring to ignore my returned object?
Thanks!
#RequestMapping(value = "/{uuid}", params = "question", method = RequestMethod.POST)
#ResponseBody
public void saveAnswer(UiAnswer json,
#PathVariable String uuid,
#RequestParam("question") String question,
HttpServletResponse response) {
doSaveAnswer(json, uuid, question, response);
}
protected IAnswer doSaveAnswer(UiAnswer json,
String uuid,
String question,
HttpServletResponse response) {
// your original code here
}
Then unit-test doSaveAnswer().

Resources