I have many pages, where i want to use a single property value of type String.
Fro example, i have login page, after i login i will set a property, whether it is admin or not, according to this property value, i will do some action on other jsp pages as well. To do this below url is giving some solution, but i don't know how can i use this
http://stackoverflow.com/questions/18211075/how-to-set-controller-wide-global-variables
I want to read this property value and use this in all different jsp pages.
Iadded the following class
public class PagePopulationInterceptor extends HandlerInterceptorAdapter {
#Autowired
private UserService userService;
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
if(modelAndView != null) {
userService.setUserType("admin");
modelAndView.addObject("myUserProfile", userService);
}
}
}
and as well changed spring-servlet xml
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<beans:bean class="com.test.PagePopulationInterceptor" />
</mvc:interceptor>
<!-- other interceptors (locale, theme and so on) -->
</mvc:interceptors>
In JSP how i tried calling is
<div>
<p>${myUserProfile.userType}</p>
</div>
In the above jsp code, i did not receive any values.
Related
If a request is sent to my API without an Accept header, I want to make JSON the default format. I have two methods in my controller, one for XML and one for JSON:
#RequestMapping(method = RequestMethod.GET,produces=MediaType.APPLICATION_ATOM_XML_VALUE)
#ResponseBody
public ResponseEntity<SearchResultResource> getXmlData(final HttpServletRequest request) {
//get data, set XML content type in header.
}
#RequestMapping(method = RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public ResponseEntity<Feed> getJsonData(final HttpServletRequest request){
//get data, set JSON content type in header.
}
When I send a request without an Accept header the getXmlData method is called, which is not what I want. Is there a way to tell Spring MVC to call the getJsonData method if no Accept header has been provided?
EDIT:
There is a defaultContentType field in the ContentNegotiationManagerFactoryBean that does the trick.
From the Spring documentation, you can do this with Java config like this:
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_JSON);
}
}
If you are using Spring 5.0 or later, implement WebMvcConfigurer instead of extending WebMvcConfigurerAdapter. WebMvcConfigurerAdapter has been deprecated since WebMvcConfigurer has default methods (made possible by Java 8) and can be implemented directly without the need for an adapter.
If you use spring 3.2.x, just add this to spring-mvc.xml
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false"/>
<property name="mediaTypes">
<value>
json=application/json
xml=application/xml
</value>
</property>
<property name="defaultContentType" value="application/json"/>
</bean>
I'm getting the following exception if I use multi level urls in class like #RequestMapping("/api/v0.1"):
java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'userController'
bean method getUsers()|to {[/api/v0.1]}: There is already 'userController' bean
method getUser(java.lang.String) mapped.
It's like the method level mappings doesn't get into consideration at all.
But it's ok if I put #RequestMapping("/api") i.e. remove the /v0.1 part.
Here is the configuration stripped up to the minimal case:
#Controller
#RequestMapping("/api/v0.1")
public class UserController {
#RequestMapping(value = "/users")
#ResponseBody
public List<User> getUsers() {
return null;
}
#RequestMapping(value = "/users/{username}")
#ResponseBody
public User getUser(#PathVariable String username) {
return null;
}
}
web.xml
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
servlet-context.xml:
<!-- Configures the #Controller programming model -->
<mvc:annotation-driven />
<!-- Forwards requests to the "/" resource to the "welcome" view -->
<mvc:view-controller path="/" view-name="home"/>
<!-- Handles HTTP GET requests for /assets/** by efficiently serving up static resources in the ${webappRoot}/resources/ directory -->
<mvc:resources mapping="/assets/**" location="/assets/" />
I'm using spring 3.1. I also tried to set alwaysUseFullPath property to true of the RequestMappingHandlerMapping bean but it didn't change the situation.
Very interesting issue - I checked what could be going on, you are right the "v0.1" is really throwing off the org.springframework.util.AntPathMatcher which creates the full URI path by combining the path from the controller and the path from the mapped method. If it sees a "file.extension" kind of a pattern in the Controller, then it totally ignores the path mapping of the method - this is the reason why your #PathVariable was getting ignored.
I am not sure if this is a bug or intended behavior in Spring MVC, temporary fix would be along what you have already mentioned -
1.To remove "v0.1" from the RequestMapping of Controller and make it without extension say v0_1
2.To put this mapping in the mapped method:
#Controller
#RequestMapping("/api")
public class UserController {
#RequestMapping(value = "/v0.1/users")
#ResponseBody
public List<User> getUsers() {
return null;
}
#RequestMapping(value = "/v0.1/users/{username}")
#ResponseBody
public User getUser(#PathVariable String username) {
return null;
}
}
You should use the #RequestMapping(value = "/{version:.*}/users") to include the dot '.' in the path variable
I'm having a problem getting the file object when I use FormPanel, FileUploadField, and Spring.
Here is what I have:
I added the CommonsMultipartResolver bean to my Spring Context file:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="100000"/>
</bean>
I have a model class with the regular getters and setters:
pulic class UploadItem{
private String filename;
private CommonsMultipartFile fileData;
....
getters/setters
....
}
My controller class:
#Controller
#RequestMapping("/Foo")
public class ThingController extends BaseController implements ServlerContextAware{
....
#RequestMapping(value = "/bar", method = RequestMethod.POST)
public #ResponseBody
String createFile(UploadItem item, BindingResults results){
String orgFile = item.getFileData().getOriginalFilename();
return orgFile;
}
I'm using UiBinding to create the form fields, but I'm calling the fileupload field and formpanel to add the other methods in code.
I have a submit button that calls:
form.submit();
And my constructor I take care of the other form requirements:
form.setMethod(Method.POST);
form.setEncoding(Encoding.MULTIPART);
form.setAction("http://url.com/foo/bar");
form.addSubmitCompleteHandler(new SubmitCompleteHandler(){
#Override
public void onSubmitComplete(SubmitCompleteEvent event){
String results = event.getResults();
Info.display("Upload Response", results);
}
});
When I run the code I get a nullpointerexecption on item.getFileData().getOriginalFilename();
I don't know what the problem is.
My guess is the form isn't bound to the UploadItem, because you never told Spring to do that. Now, I am hoping that someone knows how to do this. Normally I would use Spring's form tag library and provide a modelAttribute or commandName in the form, but since I (and the ts) use GWT the form is built from GWT components and I can't use Spring form tags.
Is a way to access view name in JSP (profile in example below) or i need to add this name to model ?
#RequestMapping(value="/user/account", method=RequestMethod.GET)
return "profile";
}
I ran into this same problem recently. There could be an official way to solve this problem, but I couldn't find it. My solution was to create an interceptor to place the view name into the model.
My interceptor is very simple:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class ViewNameInModelInterceptor extends HandlerInterceptorAdapter {
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
if (modelAndView != null) {
modelAndView.addObject("springViewName", modelAndView.getViewName());
}
super.postHandle(request, response, handler, modelAndView);
}
}
And registering it in the spring config, is also pretty simple (using the namespace configuration):
<mvc:interceptors>
<beans:bean class="ViewNameInModelInterceptor" />
</mvc:interceptors>
${requestScope['javax.servlet.forward.servlet_path']}
Just for people that will search for Thymeleaf solution:
${#httpServletRequest.getServletPath()}
You can get a view name in the jsp page as it shown below:
${pageContext.request.servletPath}
I am trying to record current time of Login (in a method or object) once the login is successful and assign LastLogin time to current login time at logout. I am using spring security for login, logout. But I don't know how to take control to a method before it goes to the target-url.
spring-security.xml
<security:form-login login-page="/login" login-processing-url="/home/currentTime" authentication-failure-url="/login?error=true" default-target-url="/home"/>
<security:logout invalidate-session="true" logout-success-url="/home/copyLastloginToCurrentLoginTime" logout-url="/logout" />
Controller
#RequestMapping(value = "/currentTime", method = RequestMethod.GET)
public void recordCurrentLoginTime(Model model) {
// code to record current time
}
#RequestMapping(value = "/copyLastloginToCurrentLoginTime", method = RequestMethod.GET)
public void changeLastLoginTime(Model model) {
//code to copy current to last time
}
Problem
I get Error 404 for - project-title/j_spring_security_check URL and when I try to debug, it doesn't come into the controller methods at all.
Should I use some filters or something else for this purpose?
I found this and that and but that didn't help.
Write your own AuthenticationSuccessHandler and LogoutSuccessHandler.
Example:
spring-security.xml :
<security:form-login login-page="/login"
login-processing-url="/login_check"
authentication-failure-url="/login?error=true"
authentication-success-handler-ref="myAuthenticationSuccessHandler"
/>
<security:logout
logout-url="/logout"
success-handler-ref="myLogoutSuccessHandler"
/>
AuthenticationSuccessHandler
#Component
public class MyAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
#Autowired
private UserService userService;
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
// changeLastLoginTime(username)
userService.changeLastLoginTime(authentication.getName());
setDefaultTargetUrl("/home");
super.onAuthenticationSuccess(request, response, authentication);
}
}
LogoutSuccessHandler
#Component
public class MyLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
#Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
if (authentication != null) {
// do something
}
setDefaultTargetUrl("/login");
super.onLogoutSuccess(request, response, authentication);
}
}
You can map a default-target-url in your mapping like
<security:form-login login-page="/login"
login-processing-url="/login_check"
authentication-failure-url="/login?error=true"
default-target-url = "/welcome"
authentication-success-handler-ref="myAuthenticationSuccessHandler"/>
When the user is authenticated it is the time when user accessed your system. Make a update through DAO in the user table with current date and time.
Simple process and you are done