Spring MVC- Storing and Retrieving #PathVariable Map<String, String> - java

I have taken 2 PathVariable, and instead of taking these separately i want to store these 2 PathVariables in to a Map and want to retrieve it from the Map.
In Spring MVC 3.1.0 here is the my Controller class method:
#Controller
#RequestMapping("/welcome")
public class HelloController {
#RequestMapping(value="/{countryName}/{userName}",method=RequestMethod.GET)
public String getPathVar(#PathVariable Map<String, String> pathVars, Model model) {
String name = pathVars.get("userName");
String country = pathVars.get("countryName");
model.addAttribute("msg", "Welcome " + name+ " to Spring MVC & You are from" + country);
return "home";
}
My Request URL is :
http://localhost:3030/spring_mvc_demo/welcome/India/ashrumochan123
But when giving request using this url, i am getting HTTP Status 400 -
Description: The request sent by the client was syntactically incorrect.
When i am taking these Path Variables separately then it is working fine.
Here is the code -
#RequestMapping(value="/{countryName}/{userName}", method=RequestMethod.GET)
public String goHome(#PathVariable("countryName") String countryName,
#PathVariable("userName") String userName, Model model) {
model.addAttribute("msg", "Welcome " + userName
+ " to Spring MVC& You are from " + countryName);
return "home";
}
Please tell me whether i am doing anything wrong?
Any help would be greatly appreciated.

According to the Spring documentation, it's been there since version 3.2.
For the #PathVariable with Map<String,String>, I think you are missing <mvc:annotation-driven/> on your Spring servlet configuration:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<mvc:annotation-driven/>
...
I've found it on this link.

Related

java.lang.AssertionError: Status expected:<200> but was:<404>

I know there are so many similar posts for this question. I tried to implement all but not working for me. Please help me why I am getting this error java.lang.AssertionError: Status expected:<200> but was:<404>
I tried to implement MediaType.APPLICATION_JSON
Annotation #EnableWebMvc
But not working
Do I need to include headers also to get that working? Please let me know
Code that I have written is:
Controller class:
#EnableWebMvc
#Controller
public class Controller {
#RequestMapping(value = "/app/data", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseData> DataInquiry(
#RequestBody RequestData requestData,
#RequestHeader(value = Constants.ID, required = false) String transactionId) {
//Do some action
return new ResponseEntity<ResponseData>(responseData, headers, HttpStatus.OK);
}
ControllerTest class:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration({"classpath*:spring/beanRefContext.xml"})
#WebAppConfiguration
public class ControllerTest{
public static final MediaType APPLICATION_JSON_UTF8 = new MediaType(MediaType.APPLICATION_JSON.getType(),
MediaType.APPLICATION_JSON.getSubtype(),
Charset.forName("utf8"));
private MockMvc mockMvc;
#Autowired
WebApplicationContext wac;
ObjectMapper mapper;
AnnotationMethodHandlerAdapter adapter;
MockHttpServletRequest request;
MockHttpServletResponse response;
#Before
public void setUp() {
System.out.println("Before method execution in CommonInquiryControllerTest class ");
//this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).dispatchOptions(true).build();
adapter = new AnnotationMethodHandlerAdapter();
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
mapper = new ObjectMapper();
}
#Test
public void InquiryDataTest() throws Exception, JsonProcessingException
{
RequestData anObject = new RequestData();
anObject.setId("1234");
anObject.setQualifier("someData");
mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
ObjectWriter ow = mapper.writer().withDefaultPrettyPrinter();
String requestJson=ow.writeValueAsString(anObject );
assertNotNull(anObject.getId());
assertNotNull(anObject.getQualifier());
ResultActions resultActions = mockMvc
.perform(post("/app/data")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(mapper.writeValueAsBytes(requestJson)));
resultActions.andExpect(status().isOk());
//This will print the response JSON string
resultActions.andDo(MockMvcResultHandlers.print());
Assert.assertEquals(200, response.getStatus());
}
xml Info:
beanContext.xml
<?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:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:encryption="http://www.jasypt.org/schema/encryption"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.jasypt.org/schema/encryption
http://www.jasypt.org/schema/encryption/jasypt-spring3-encryption-1.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<import resource="classpath:core-application-context.xml"/>
<import resource="classpath:region-context.xml"/>
<jee:jndi-lookup id="somedataSourceid" jndi-name="some name" proxy-interface="javax.sql.DataSource"/>
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven/>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<!-- a PlatformTransactionManager is still required -->
<bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager"/>
</beans>
In region-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="true" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd">
<!-- Import this context file and pass it the requisite properties and a Data Source named dataSource -->
<context:component-scan base-package="com.java.geek"/>
</beans>
Even though you Enable WebMvc, you need to scan your controller to auto register controller & url mappings.component-scan scans packages to find and register beans within the application context.
<context:component-scan base-package="com.mycompany.xyz" />
I doubt component scanning is missing in your context xml.If so Add this statement in your beanRefContext.xml.

Spring Integration - how to send POST parameters with http outbound-gateway

I'm trying to put together a really simple HTTP POST example using Spring Integration and a http outbound-gateway.
I need to be able to send a HTTP POST message with some POST parameters, as I would with curl:
$ curl -d 'fName=Fred&sName=Bloggs' http://localhost
I can get it working (without the POST parameters) if I send a simple String as the argument to the interface method, but I need to send a pojo, where each property of the pojo becomes a POST parameter.
I have the following SI config:
<?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:int="http://www.springframework.org/schema/integration"
xmlns:int-http="http://www.springframework.org/schema/integration/http"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http.xsd">
<int:gateway id="requestGateway"
service-interface="RequestGateway"
default-request-channel="requestChannel"/>
<int:channel id="requestChannel"/>
<int-http:outbound-gateway request-channel="requestChannel"
url="http://localhost"
http-method="POST"
expected-response-type="java.lang.String"/>
</beans>
My RequestGateway interface looks like this:
public interface RequestGateway {
String echo(Pojo request);
}
My Pojo class looks like this:
public class Pojo {
private String fName;
private String sName;
public Pojo(String fName, String sName) {
this.fName = fName;
this.sName = sName;
}
.... getters and setters
}
And my class to kick it all off looks like this:
public class HttpClientDemo {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("/si-email-context.xml");
RequestGateway requestGateway = context.getBean("requestGateway", RequestGateway.class);
Pojo pojo = new Pojo("Fred", "Bloggs");
String reply = requestGateway.echo(pojo);
System.out.println("Replied with: " + reply);
}
}
When I run the above, I get:
org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [Pojo] and content type [application/x-java-serialized-object]
I've googled a lot for this, but cannot find any examples of sending HTTP POST parameters with an outbound-gateway (I can find lots about setting HTTP Headers, but that's not what I'm trying to do here)
The only thing I did find was spring-integration: how to pass post request parameters to http-outbound but it's a slightly different use case as the OP was trying to send a JSON representation of his pojo which I am not, and the answer talks about setting headers, not POST parameters.
Any help with this would be very much appreciated;
Thanks
Nathan
Thanks to the pointers from #jra077 regarding Content-Type, this is how I solved it.
My SI config now looks like this - the important bit was adding the Content-Type header:
<?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:int="http://www.springframework.org/schema/integration"
xmlns:int-http="http://www.springframework.org/schema/integration/http"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http.xsd">
<int:gateway id="requestGateway"
service-interface="RequestGateway"
default-request-channel="requestChannel">
<int:method name="sendConfirmationEmail">
<int:header name="Content-Type" value="application/x-www-form-urlencoded"/>
</int:method>
</int:gateway>
<int:channel id="requestChannel"/>
<int-http:outbound-gateway request-channel="requestChannel"
url="http://localhost"
http-method="POST"
expected-response-type="java.lang.String"/>
</beans>
Then I changed my interface to take a Map as it's argument rather than the pojo:
public interface RequestGateway {
String echo(Map<String, String> request);
}
The pojo itself remains as before; and the class that invokes the service is changed so that it creates a Map and passes it:
public class HttpClientDemo {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("/si-email-context.xml");
RequestGateway requestGateway = context.getBean("requestGateway", RequestGateway.class);
Pojo pojo = new Pojo("Fred", "Bloggs");
Map<String, String> requestMap = new HashMap<String, String>();
requestMap.put("fName", pojo.getFName());
requestMap.put("sName", pojo.getSName());
String reply = requestGateway.echo(requestMap);
System.out.println("Replied with: " + reply);
}
}
I'm sure there are several more elegant ways of transforming the pojo into a Map, but for the time being this answers my question.
To send POST parameters with a http outbound-gateway you need to set the Content-Type to application/x-www-form-urlencoded and you need to pass a Map of key/values pairs.

Generate XML response in Spring MVC

I have a controller class, I'm expecting it to display the .xml response of model class which is annotated with #XmlRootElement. The Controller class method which displays all the student list is ,
#RequestMapping("studentlist")
public #ResponseBody
StudentList getStudentList() {
List<student> studentList = new ArrayList<student>();
studentList.add(new Student(3, "Robert", "Parera", "robert#gmail.com", "88"));
studentList.add(new Student(93, "Andrew", "Strauss","andrew#gmail.com", "89"));
studentList.add(new Student(239, "Eddy", "Knight", "knight#gmail.com", "79"));
return new StudentList(studentList);
}
}
i have added the #ResponseBody ,but still the class is not displaying the .xml response This is my web.xml.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="com.javasample.common.controller" />
<mvc:annotation-driven />
</beans>
Please advice what is missing. I also have model class which is properly annotated with #XMLElement ,#XmlRootElement etc. Kindly advice as I'm new to Spring MVC.

how to access property file value in the method of a class in spring

I am using spring 4.0.3.RELEASE
Here is my applicationContext.xml where i am configuring PropertyPlaceHolder
<?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:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<mvc:annotation-driven/>
<context:component-scan base-package="org.graphsearch.tutor.service.impls, org.graphsearch.tutor.dao.impls, org.graphsearch.tutor.configs, org.graphsearch.tutor.utils"/>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>/WEB-INF/properties/database/jdbc.properties</value>
<value>/WEB-INF/properties/alert/message.properties</value>
<value>/WEB-INF/properties/email/mail.properties</value>
<value>/WEB-INF/properties/logger/logging.properties</value>
</list>
</property>
</bean>
</beans>
In Email client class i am injecting property values like this
#Component
public class EmailClient {
#Value("${tutor.mail.common.note}")
private static String NOTE;
#Value("${tutor.mail.common.regards}")
private static String REGARDS;
#Value("${tutor.mail.from}")
private static String FROM;
#Autowired
private MailSender mailSender;
#Autowired
private Environment env;
public void sendRegisterMail(User user){
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(user.getEmailID());
String subject = env.getProperty("tutor.register.success.mail.subject"); //retuns null
String contentTemplate = env.getProperty("tutor.register.success.mail.content"); //returns null
MessageFormat format = new MessageFormat(contentTemplate);
Object[] args = {user.getFullName()};
StringBuffer content = new StringBuffer();
content.append(format.format(args));
content.append(NOTE);
content.append(REGARDS);
message.setSubject(subject);
message.setText(content.toString());
mailSender.send(message);
}
}
Now problem is #Value("${property.key}") does work like charm when i inject a private field of the class like NOTE, REGARDS, FROM.
But if i need this value inside the method sendRegisterMail()
#Value("$key") is giving compiler error. I searched on web few examples are there getting properties value through environment so i used like i have done in EmailClient class but it always give me null. I checked the log it says it can not find the property key.
Can some body give me a clue how to inject properties value inside a method.
Thanks in advance
Try
#Value("#{propertyConfigurer['tutor.mail.common.note']}")
private static String NOTE;
For more info have a look at How can I inject a property value into a Spring Bean which was configured using annotations?

Spring MVC 3.1 RedirectAttributes is not working

I'm trying to implement RedirectAttributes feature in Spring MVC 3.1-Release
I'm sending simple form to Post URL and would like to see the the value I'm sending in redirect:
my Controller looks like this:
#Controller
public class DefaultController {
#RequestMapping(value="/index.html", method=RequestMethod.GET)
public ModelAndView indexView(){
ModelAndView mv = new ModelAndView("index");
return mv;
}
#RequestMapping(value="/greetings.action", method=RequestMethod.POST)
public ModelAndView startTask(#RequestParam("firstName") String firstName,RedirectAttributes redirectAttributes){
redirectAttributes.addFlashAttribute("redirectAttributes.firstName", firstName);
ModelAndView mv = new ModelAndView(new RedirectView("success.html"));
return mv;
}
#RequestMapping(value="/success.html", method=RequestMethod.GET)
public ModelAndView successView(){
ModelAndView mv = new ModelAndView("success");
return mv;
}
}
Now my Servlet XML looks like this:
<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:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<mvc:annotation-driven/>
<context:component-scan base-package="com.vanilla.flashscope.controllers" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
My problem is that in success.html view redirectAttributes is empty.
<body>
<h5>${redirectAttributes.firstName} </h5>
</body>
Prints nothing.
It does not work because You are using ModelAndView as a return value.
See JIRA Issue: https://jira.springsource.org/browse/SPR-8968
It looks like you need to remove "redirectAttributes." from the key name"
Instead of:
redirectAttributes.addFlashAttribute("redirectAttributes.firstName", firstName);
Do this:
redirectAttributes.addFlashAttribute("firstName", firstName);

Categories