Spring controller get request/response - java

How do I get the request/response that I can setcookie? Additionally, at the end of this method, how can I can redirect to another page?
#RequestMapping(value = "/dosomething", method = RequestMethod.GET)
public RETURNREDIRECTOBJ dosomething() throws IOException {
....
return returnredirectpagejsp;
}

How about this:
#RequestMapping(value = "/dosomething", method = RequestMethod.GET)
public ModelAndView dosomething(HttpServletRequest request, HttpServletResponse response) throws IOException {
// setup your Cookie here
response.setCookie(cookie)
ModelAndView mav = new ModelAndView();
mav.setViewName("redirect:/other-page");
return mav;
}

Just pass it as argument: public String doSomething(HttpServletRequest request). You can pass both the request and response, or each of them individually.
return the String "redirect:/viewname" (most often without the .jsp suffix)
For both questions, check the documentation, section "15.3.2.3 Supported handler method arguments and return types"

You can also simply #Autowire. For example:
#Autowired
private HttpServletRequest request;
Though HttpServletRequest is request-scoped bean, it does not require your controller to be request scoped, as for HttpServletRequest Spring will generate a proxy HttpServletRequest which is aware how to get the actual instance of request.

You could also use this way
#RequestMapping(value = "/url", method = RequestMethod.GET)
public String method(HttpServletRequest request, HttpServletResponse response){
Cookie newCookie = new Cookie("key", "value");
response.addCookie(newCookie);
return "redirect:/newurl";
}

Related

Java Servlet retrieve Spring RequestMapping Url

I wrote a Request Interceptor to add some Information to Requests in Test-Environment.
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler)
throws Exception {
...
}
public void postHandle(
HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView)
throws Exception {
...
}
Currently I'm retrieving the URLs like this:
String url = request.getServletPath();
For a Controller like this:
#RequestMapping(value = "/{id}",
method = RequestMethod.GET)
public ResponseEntity<?> getByID(#PathVariable long ID) {
...
}
And for a Request like /1/
url would be /1/
Is there any way to get the Request-Mapping-Value ==> /{id}
Thanks in advance
#RequestMapping and its composed annotation methods (i.e. #GetMapping , #PostMapping etc.) are handled by HandlerMethod. So cast the handler object to it and you can access the #RequestMapping information that you want:
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod hm = (HandlerMethod) handler;
RequestMapping mapping = hm.getMethodAnnotation(RequestMapping.class);
if (mapping != null) {
for(String val : mapping.value()) {
//***This is the mapping value of #RequestMapping***
System.out.println(val);
}
}
}
}

Spring MVC - calling method on every admin pages

I'm new to spring mvc , I'm working on a web project admin panel.
Here is some example of my admin pages controllers :
#Controller
#RequestMapping("/admin/article/**")
public class ArticleController {
private ArticleDao articleDao;
private String fileName;
private String baseUrl;
public ArticleController() {
articleDao = ArticleDaoFactory.create();
}
#RequestMapping(value = "/admin/article",method = RequestMethod.GET)
public String doGet(ModelMap model,HttpServletRequest request,ArticleForm articleForm) {
//some codes
}
#RequestMapping(value = "/admin/article/add",method = RequestMethod.GET)
public String doGetAdd(ModelMap model,ArticleForm articleForm) {
model.addAttribute("article", articleForm);
return "admin/articleAdd";
}
#RequestMapping(value = "/admin/article/add",method = RequestMethod.POST)
public String doPost(#ModelAttribute ArticleForm article, BindingResult result ,ModelMap model){
//some codes
}
#RequestMapping(value = "/admin/article/edit/{id}",method = RequestMethod.GET)
public String getEdit(ModelMap model, #PathVariable("id") int id) {
//some codes
}
#RequestMapping(value = "/admin/article/edit/{id}",method = RequestMethod.POST)
public String postEdit(ModelMap model, #PathVariable("id") int id, ArticleForm article, BindingResult result) {
//some codes
}
#RequestMapping(value = "/admin/article/delete/{id}",method = RequestMethod.GET)
public void getDelete(ModelMap model, #PathVariable("id") int id, HttpServletResponse response) {
//some codes
}
}
now I need another mapping in another contoller named AdminController (for example) to Authenticate admin and bring him to login page if he is not logged in. for sure Authenthication is one example, I might want to use more classes on every admin page.
Note that my authenthication class needs request and session references (and for sure my other classes will need other references created by spring)
I got to know that I can not get HttpServletRequest and ... using a constructor method so I wrote another request mapping to call a method.
Eventhough I can set my properties this way ,but I can not use this method on every admin url.
#Controller
#RequestMapping(value = "/admin/**",method = RequestMethod.GET)
public class AdminController {
Authentication authentication;
HttpServletRequest request;
HttpSession session;
HttpServletResponse response;
public void checkAndSet(HttpSession session,HttpServletRequest request,HttpServletResponse response) {
authentication = new Authentication(session,request);
this.request = request;
this.session = session;
this.response = response;
if(!authentication.isLoggedIn()){
System.out.println(" I'm not logged in");
response.setHeader("Location","/admin/login");
}
}
So I need some suggestion on how to write a request mapping in a controller to call a method on every other controllers that are 'admin' page child ?
FYI : I'm not thinking for spring security for this.
thanks;
I think you can do it by implementing a servlet filter.
For example :
public class AuthenticationFilter extends GenericFilterBean {
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String url = request.getServletPath();
HttpSession session = request.getSession(false);
Authentication authentication = new Authentication(session,request);
if (isAdminUrl(url) && !authentication.isLoggedIn()) {
res.sendRedirect/admin/login");
}
chain.doFilter(req, res);
}
}
And then, you have to implement the method isAdminUrl(String url) to determine if you want to apply your filter.
Otherwise, I strongly recommend you to take a look at Spring Security

redirecting one to another Controller using spring mvc 3

below is my controller
#RequestMapping(method = RequestMethod.GET)
#ResponseBody
public String ABC(Registratio registration, ModelMap modelMap,
HttpServletRequest request,HttpServletResponse response){
if(somecondition=="false"){
return "notok"; // here iam returning only the string
}
else{
// here i want to redirect to another controller shown below
}
}
#RequestMapping(value="/checkPage",method = RequestMethod.GET,)
public String XYZ(ModelMap modelMap,
HttpServletRequest request,HttpServletResponse response){
return "check"; // this will return check.jsp page
}
since the Controller ABC is #ResponceBody type it will always return as string, but i want that in else contion it should be redirected to the XYZ controller and from which it return a jsp page which i can show.
i tried using return "forward:checkPage"; also with return "redirect:checkPage";
but doesn't work.
any help.
Thanks.
I think you have to remove #ResponseBody if you want to either render response yourself or redirect in one controller method based on some condition, try this:
#RequestMapping(method = RequestMethod.GET)
//remove #ResponseBody
public String ABC(Registratio registration, ModelMap modelMap,
HttpServletRequest request,HttpServletResponse response){
if(somecondition=="false"){
// here i am returning only the string
// in this case, render response yourself and just return null
response.getWriter().write("notok");
return null;
}else{
// redirect
return "redirect:checkPage";
}
}
--edit--
if you want to access controller via ajax, you'd better include the datatype parameter on you request to indicate that you are simply expecting a text response:
$.get("/AAA-Web/abc",jQuery.param({})
,function(data){
alert(data);
}, "text");
return new ModelAndView("redirect:/admin/index");
The code above works for me. I was redirecting from the present controller to index in AdminController.
edirected to the XYZ controller and from which it return a jsp page instead of using the following code i/e
#RequestMapping(value="/checkPage",method = RequestMethod.GET,)
public String XYZ(ModelMap modelMap,
HttpServletRequest request,HttpServletResponse response){
return "check"; // this will return check.jsp page
}
use
#RequestMapping(value ="/checkPage",method = RequestMethod.GET)
public ModelAndView XYZ(HttpServletRequest req)
{
ModelAndView m=new ModelAndView();
m.setViewName("check");
return m;
}

Redirect to an external URL from controller action in Spring MVC

I have noticed the following code is redirecting the User to a URL inside the project,
#RequestMapping(method = RequestMethod.POST)
public String processForm(HttpServletRequest request, LoginForm loginForm,
BindingResult result, ModelMap model)
{
String redirectUrl = "yahoo.com";
return "redirect:" + redirectUrl;
}
whereas, the following is redirecting properly as intended, but requires http:// or https://
#RequestMapping(method = RequestMethod.POST)
public String processForm(HttpServletRequest request, LoginForm loginForm,
BindingResult result, ModelMap model)
{
String redirectUrl = "http://www.yahoo.com";
return "redirect:" + redirectUrl;
}
I want the redirect to always redirect to the URL specified, whether it has a valid protocol in it or not and do not want to redirect to a view. How can I do that?
Thanks,
You can do it with two ways.
First:
#RequestMapping(value = "/redirect", method = RequestMethod.GET)
public void method(HttpServletResponse httpServletResponse) {
httpServletResponse.setHeader("Location", projectUrl);
httpServletResponse.setStatus(302);
}
Second:
#RequestMapping(value = "/redirect", method = RequestMethod.GET)
public ModelAndView method() {
return new ModelAndView("redirect:" + projectUrl);
}
You can use the RedirectView. Copied from the JavaDoc:
View that redirects to an absolute, context relative, or current request relative URL
Example:
#RequestMapping("/to-be-redirected")
public RedirectView localRedirect() {
RedirectView redirectView = new RedirectView();
redirectView.setUrl("http://www.yahoo.com");
return redirectView;
}
You can also use a ResponseEntity, e.g.
#RequestMapping("/to-be-redirected")
public ResponseEntity<Object> redirectToExternalUrl() throws URISyntaxException {
URI yahoo = new URI("http://www.yahoo.com");
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setLocation(yahoo);
return new ResponseEntity<>(httpHeaders, HttpStatus.SEE_OTHER);
}
And of course, return redirect:http://www.yahoo.com as mentioned by others.
You can do this in pretty concise way using ResponseEntity like this:
#GetMapping
ResponseEntity<Void> redirect() {
return ResponseEntity.status(HttpStatus.FOUND)
.location(URI.create("http://www.yahoo.com"))
.build();
}
Looking into the actual implementation of UrlBasedViewResolver and RedirectView the redirect will always be contextRelative if your redirect target starts with /. So also sending a //yahoo.com/path/to/resource wouldn't help to get a protocol relative redirect.
So to achieve what you are trying you could do something like:
#RequestMapping(method = RequestMethod.POST)
public String processForm(HttpServletRequest request, LoginForm loginForm,
BindingResult result, ModelMap model)
{
String redirectUrl = request.getScheme() + "://www.yahoo.com";
return "redirect:" + redirectUrl;
}
Another way to do it is just to use the sendRedirect method:
#RequestMapping(
value = "/",
method = RequestMethod.GET)
public void redirectToTwitter(HttpServletResponse httpServletResponse) throws IOException {
httpServletResponse.sendRedirect("https://twitter.com");
}
For me works fine:
#RequestMapping (value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<Object> redirectToExternalUrl() throws URISyntaxException {
URI uri = new URI("http://www.google.com");
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setLocation(uri);
return new ResponseEntity<>(httpHeaders, HttpStatus.SEE_OTHER);
}
For external url you have to use "http://www.yahoo.com" as the redirect url.
This is explained in the redirect: prefix of Spring reference documentation.
redirect:/myapp/some/resource
will redirect relative to the current Servlet context, while a name such as
redirect:http://myhost.com/some/arbitrary/path
will redirect to an absolute URL
Did you try RedirectView where you can provide the contextRelative parameter?
This works for me, and solved "Response to preflight request doesn't pass access control check ..." issue.
Controller
RedirectView doRedirect(HttpServletRequest request){
String orgUrl = request.getRequestURL()
String redirectUrl = orgUrl.replaceAll(".*/test/","http://xxxx.com/test/")
RedirectView redirectView = new RedirectView()
redirectView.setUrl(redirectUrl)
redirectView.setStatusCode(HttpStatus.TEMPORARY_REDIRECT)
return redirectView
}
and enable securty
#EnableWebSecurity
class SecurityConfigurer extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
}
}
In short "redirect://yahoo.com" will lend you to yahoo.com.
where as "redirect:yahoo.com" will lend you your-context/yahoo.com ie for ex- localhost:8080/yahoo.com

Spring MVC and X-HTTP-Method-Override parameter

I'm using Spring MVC, and I have a function to update a user's profile:
#RequestMapping(value = "/{userName}" + EndPoints.USER_PROFILE,
method = RequestMethod.PUT)
public #ResponseBody ResponseEntity<?> updateUserProfile(
#PathVariable String userName, #RequestBody UserProfileDto userProfileDto) {
// Process update user's profile
}
I've started using JMeter, and for some reason they have a problem with sending a PUT request with a body (either in a request body or using a request parameter hack).
I know that in Jersey you can add a filter to process the X-HTTP-Method-Override request parameter, so that you can send a POST request and override it using the header parameter.
Is there any way to do this in Spring MVC?
Thanks!
Spring MVC has the HiddenHttpMethodFilter which allows you to include a request parameter (_method) to override the http method. You just need to add the filter into your filter chain in web.xml.
I'm not aware of an out-of-the-box solution to use the X-HTTP-Method-Override header, but you can create a filter similar to the HiddenHttpMethodFilter yourself which uses the header to change the value rather than the request parameter.
You can use this class as a filter:
public class HttpMethodOverrideHeaderFilter extends OncePerRequestFilter {
private static final String X_HTTP_METHOD_OVERRIDE_HEADER = "X-HTTP-Method-Override";
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String headerValue = request.getHeader(X_HTTP_METHOD_OVERRIDE_HEADER);
if (RequestMethod.POST.name().equals(request.getMethod()) && StringUtils.hasLength(headerValue)) {
String method = headerValue.toUpperCase(Locale.ENGLISH);
HttpServletRequest wrapper = new HttpMethodRequestWrapper(request, method);
filterChain.doFilter(wrapper, response);
}
else {
filterChain.doFilter(request, response);
}
}
private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
private final String method;
public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
super(request);
this.method = method;
}
#Override
public String getMethod() {
return this.method;
}
}
}
Source: http://blogs.isostech.com/web-application-development/put-delete-requests-yui3-spring-mvc/

Categories